Categories
discuss

Start DialogFragment from Activity

I’m learning Android programming with IntelliJ right now and got a little problem.

I’ve got an Activity which looks like this:

public class example2 extends Activity {
    ...some code...
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.optExit:
                finish();
                return true;
            case R.id.optSettings:
                Intent sintent = new Intent(this, settings.class);
                startActivity(esintent);
                return true;
            case R.id.optAbout:
                //need to start the fragmentdialog

        }
        return true;
    }
    ...some code...
}

And this is how my DialogFragment looks like

public class about extends DialogFragment {

    public Dialog onCreateDialog(Bundle savedInstanceState) {
        AlertDialog.Builder b = new AlertDialog.Builder(getActivity());
        b.setTitle("About");
        b.setMessage("some text");
        b.setCancelable(false);
        b.setPositiveButton("OK", null);
        return b.create();
    }
}

I’ve tried nearly everything, creating a new instance and start the method, using FragmentManager, which i wasn’t able to use. What should I do?

Answer

for approved namings use About instead of about its just

new About().show(getSupportFragmentManager(),"about");
Categories
discuss

HTTP Status 415 – request entity is in a format not supported

I am working on java restful web service. I got it working for GET request, but POST request does not work. My Controller class is RestController. I have done these so far:

@RequestMapping(value = "/api/signup", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
public long signUp(@ModelAttribute ApiMemberModel apiMember) {
    memberService = new MemberDetailsService();
    Member m = memberService.createMember(apiMember.getUsername(), apiMember.getPassword(), apiMember.getEmail(), "");
    return m.getId();
}

Also tried RequestBody instead of ModelAttribute.

I use Postman extension for sending POST request. For example:

{
    "username": "asd",
    "password": "sfsdg",
    "email": "sdfdsf@fdsfkg.com"
}

But I get the error:

description The server refused this request because the request entity is in a format not supported by the requested resource for the requested method.

What am I doing wrong? Model class is:

 public class ApiMemberModel {
    private String username;
    private String password;
    private String email;

    public ApiMemberModel(String username, String password, String email) {
        this.username = username;
        this.password = password;
        this.email = email;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }
}

Answer

I bet that call from Postman does not include Content-Type: application/json.

HTTP 415 means that the server does not understand the media format of the request. In your controller you are specifying it accepts JSON, but you have not said if the request indicated that the body is in that format. Just because you put the data in JSON format, does not mean that the server is going to recognize it, you have to indicate it in the Content-Type header.

Categories
discuss

espresso dynamic spinner testing

I am trying to test a dynamically generated Spinner. I am able to click on the spinner but then I need to select an option from the list with a given text that is shown (I found out from hierarchyviewer that a PopupWindow is shown but am unable to get to the required text which is offscreen). The spinner uses an ArrayAdapter of custom objects (code below),

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Spinner mySpinner = (Spinner) findViewById(R.id.my_spinner);
        List<MyValue> list = Arrays.asList(
                new MyValue("One", "1"),
                new MyValue("Two", "2"),
                new MyValue("Three", "3"),
                new MyValue("Four", "4"),
                new MyValue("Five", "5"),
                new MyValue("Six", "6"),
                new MyValue("Seven", "7"),
                new MyValue("Eight", "8"),
                new MyValue("Nine", "9"),
                new MyValue("Ten", "10"),
                new MyValue("Eleven", "11"),
                new MyValue("Twelve", "12"),
                new MyValue("Thirteen", "13"),
                new MyValue("Fourteen", "14"),
                new MyValue("Fifteen", "15"),
                new MyValue("Sixteen", "16"),
                new MyValue("Seventeen", "17"),
                new MyValue("Eighteen", "18"),
                new MyValue("Nineteen", "19"),
                new MyValue("Twenty", "20"),
                new MyValue("Twenty One", "21")
        );

        final ArrayAdapter<MyValue> adapter = new ArrayAdapter<>(this,
                R.layout.dropdown_selected_item,
                list);
        mySpinner.setAdapter(adapter);
        mySpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                Log.d("MySpinnerTest", "current = " + adapter.getItem(position));
            }
            @Override
            public void onNothingSelected(AdapterView<?> parent) {}
        });
    }

    public class MyValue {
        String name;
        String code;

        public MyValue(String name, String code) {
            this.name = name;
            this.code = code;
        }

        @Override
        public String toString() {
            return name;
        }
    }
}

I tried with onData(withSpinnerText("Twenty")).perform(click()) but get a PerformException and I tried to find out how else to match the correct view based on a given text, in the spinner popupwindow but could not figure out how to do this.

Any help would be greatly appreciated.

TIA

Answer

Found a way to do this and so posting the answer to my own question.

I had to create a custom matcher for my object and then use that with the onData()

public static Matcher<Object> withMyValue(final String expectedName) {
    return new BoundedMatcher<Object, MyValue>(MyValue.class) {

        @Override
        public void describeTo(Description description) {
            description.appendText("with expectedName: " + expectedName);
        }

        @Override
        protected boolean matchesSafely(MyValue myValue) {
            return myValue.getName().equalsIgnoreCase(expectedName);
        }
    };
}

which then could be used as (after clicking on the spinner to display the dropdown)

onData(withMyValue(field.name)).perform(click());

Categories
discuss

Android Layout: Horizontal Recyclerview inside a Vertical Recyclerview inside a Viewpager with Scroll Behaviors

This is the app I’m trying to build with all the elements mapped out below:

Veggies app

Everything works, however, I want the inner horizontal recyclerview not to capture any of the vertical scrolls. All vertical scrolls must go towards the outer vertical recyclerview, not the horizontal one, so that the vertical scroll would allow for the toolbar to exit out of view according to it’s scrollFlag.

When I put my finger on the “StrawBerry Plant” part of the recyclerview and scroll up, it scroll out the toolbar:

strawberry plant

If I put my finger on the horizontal scrollview and scroll up, it does not scroll out the toolbar at all.

The following is my xml layout code so far.

The Activity xml layout:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/fragment_container"
    android:clipChildren="false">

    <android.support.design.widget.CoordinatorLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/container"
        >

    <android.support.design.widget.AppBarLayout
        android:id="@+id/appBarLayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:minHeight="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:layout_scrollFlags="scroll|enterAlways">

        </android.support.v7.widget.Toolbar>

        <android.support.design.widget.TabLayout
            android:id="@+id/sliding_tabs"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="?attr/colorPrimary"
            style="@style/CustomTabLayout"
            />

    </android.support.design.widget.AppBarLayout>
    <android.support.v4.view.ViewPager
        android:id="@+id/viewPager"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior"
        />

    </android.support.design.widget.CoordinatorLayout>

</FrameLayout>

The “Fruits” fragment xml layout (which is the code for the fragment – the fragment is labeled in the above picture):

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ProgressBar
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/progressBar"
        android:visibility="gone"
        android:layout_centerInParent="true"
        android:indeterminate="true"/>

<!--    <android.support.v7.widget.RecyclerView-->
    <com.example.simon.customshapes.VerticallyScrollRecyclerView
        android:id="@+id/main_recyclerview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        />

</RelativeLayout>

I have used a custom class called VerticallyScrollRecyclerView which follows google example of handling touch events in a viewgroup. Its aim is to intercept and consume all the vertical scroll events so that it will scroll in / out the toolbar: http://developer.android.com/training/gestures/viewgroup.html

The code for VerticallyScrollRecyclerView is below:

public class VerticallyScrollRecyclerView extends RecyclerView {

    public VerticallyScrollRecyclerView(Context context) {
        super(context);
    }

    public VerticallyScrollRecyclerView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public VerticallyScrollRecyclerView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    ViewConfiguration vc = ViewConfiguration.get(this.getContext());
    private int mTouchSlop = vc.getScaledTouchSlop();
    private boolean mIsScrolling;
    private float startY;

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        final int action = MotionEventCompat.getActionMasked(ev);
        // Always handle the case of the touch gesture being complete.
        if (action == MotionEvent.ACTION_CANCEL || action == MotionEvent.ACTION_UP) {
            // Release the scroll.
            mIsScrolling = false;
            startY = ev.getY();
            return super.onInterceptTouchEvent(ev); // Do not intercept touch event, let the child handle it
        }
        switch (action) {
            case MotionEvent.ACTION_MOVE: {
                Log.e("VRecView", "its moving");
                if (mIsScrolling) {
                    // We're currently scrolling, so yes, intercept the
                    // touch event!
                    return true;
                }
                // If the user has dragged her finger horizontally more than
                // the touch slop, start the scroll
                // left as an exercise for the reader
                final float yDiff = calculateDistanceY(ev.getY());
                Log.e("yDiff ", ""+yDiff);
                // Touch slop should be calculated using ViewConfiguration
                // constants.
                if (Math.abs(yDiff) > 5) {
                    // Start scrolling!
                    Log.e("Scroll", "we are scrolling vertically");
                    mIsScrolling = true;
                    return true;
                }
                break;
            }
        }
        return super.onInterceptTouchEvent(ev);
    }


    private float calculateDistanceY(float endY) {
        return startY - endY;
    }

}

The “Favourite” layout which is the recyclerview within the vertical recyclerview:

<?xml version="1.0" encoding="utf-8"?>

<RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:background="@color/white"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Favourite"
        android:layout_marginTop="8dp"
        android:layout_marginBottom="8dp"
        android:layout_marginLeft="16dp"
        android:id="@+id/header_fav"/>

    <android.support.v7.widget.RecyclerView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:layout_below="@+id/header_fav"
        android:id="@+id/recyclerview_fav">
    </android.support.v7.widget.RecyclerView>

</RelativeLayout>

This has been bugging me for a while now and I have not managed to come up with a solution. Does anyone know how to solve this problem?

5 points to Griffindor for the correct answer and of course, reputation points on SO.

Answer

Tested solution:

All you need is to call mInnerRecycler.setNestedScrollingEnabled(false); on your inner RecyclerViews


Explanation:

RecyclerView has support for nested scrolling introduced in API 21 through implementing the NestedScrollingChild interface. This is a valuable feature when you have a scrolling view inside another one that scrolls in the same direction and you want to scroll the inner View only when focused.

In any case, RecyclerView by default calls RecyclerView.setNestedScrollingEnabled(true); on itself when initializing. Now, back to the problem, since both of your RecyclerViews are within the same ViewPager that has the AppBarBehavior, the CoordinateLayout has to decide which scroll to respond to when you scroll from your inner RecyclerView; when your inner RecyclerView‘s nested scrolling is enabled, it gets the scrolling focus and the CoordinateLayout will choose to respond to its scrolling over the outer RecyclerView‘s scrolling. The thing is that, since your inner RecyclerViews don’t scroll vertically, there is no vertical scroll change (from the CoordinateLayout‘s point of view), and if there is no change, the AppBarLayout doesn’t change either.

In your case, because your inner RecyclerViews are scrolling in a different direction, you can disable it, thus causing the CoordinateLayout to disregard its scrolling and respond to the outer RecyclerView‘s scrolling.


Notice:

The xml attribute android:nestedScrollingEnabled="boolean" is not intended for use with the RecyclerView, and an attempt to use android:nestedScrollingEnabled="false" will result in a java.lang.NullPointerException so, at least for now, you will have to do it in code.

Categories
discuss

OpenCV Android – Cannot Resolve Corresponding JNI Function

I’m trying to setup Android Studio with Opencv by following this tutorial outlined here: https://www.youtube.com/watch?v=OTw_GIQNbD8

I can get the result obtained by the person giving the tutorial but upon trying to actually use some of Opencv’s functions I run into some trouble.

I am able to load the Opencv library but upon trying use some of the native functions such as “Imgcodecs.imread” I get the error: “.lang.UnsatisfiedLinkError: No implementation found for long org.opencv.imgcodecs.Imgcodecs.imread_1(java.lang.String)”

I believe I have tracked down the issue to the following:

[![enter image description here][1]][1]

It seems that Android Studio is unable to detect the native C++ code which I’m guessing should be picked up from jniLibs folder I now have in app/src/main?

I’ve tried updating Android Studio to the latest stable build and I have fixed my file paths for my android SDK and NDK as having white-space can apparently affect the running of native code. The issue still persists.

I have been trying to fix this for the last 4 hours, any help would be greatly appreciated!

Answer

FINAL EDIT: I’ve made a tutorial explaining how to install Opencv for Android along with SIFT/SURF algorithms – https://www.youtube.com/watch?v=cLK9CjQ-pNI

It appears that I have solved my issue with using the following file structure and dependencies. I can’t say for sure how I got it to work but I believe if you copy my structure here then yours should work too.

Ensure that there are no spaces present in your file path to your Android SDK or NDK. Android Studio warns that this may cause issue when loading native code.

Place the folders containing the ‘*.so’ files into /YOUR_PROJECT_ROOT/libs (You’ll probably have to manually create this libs folder).
All the other solutions online stating to put them into app/src/main/jniLibs did not work for me.

To include the openCVLibrary300, I imported it as a module using File->New->Import Module, the set the Source Directory to something like ..OpenCV-android-sdksdkjava

Ensure build.gradle files in both the app and the imported library share the same min and max sdk version etc.

Sample code used to test – http://pastebin.com/2zzU5B9G

The sample code I’ve posted above ensures the libraries are loaded before using Opencv methods. It uses the Imgcodecs.imread() function that uses native code in C++ that was previously giving me the “.lang.UnsatisfiedLinkError: No implementation found for long org.opencv.imgcodecs.Imgcodecs.imread_1(java.lang.String)” error.

enter image description here

enter image description here

enter image description here

Source: stackoverflow
Text is available under the Creative Commons Attribution-ShareAlike License; additional terms may apply. By using this site, you agree to the Privacy Policy, and Copyright Policy. Content is available under CC BY-SA 3.0 unless otherwise noted. The answers/resolutions are collected from stackoverflow, are licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0 © No Copyrights, All Questions are retrived from public domain..