سؤال

My main activity is a Swipe View with tabs in the action bar, which can be used to change to a particular fragment directly. I basically followed the developer guidelines on this. So far this works fine and as expected.

However, I now have a couple of items in the menu (Settings, About), which should not be displayed as part of the ViewPager, but rather should replace the ViewPager completely and set the "navigation up" affordance in the action bar. Following along with the answers to this question I know how to use the BackStack to manipulate the action bar and to show the "navigation up" affordance.

However I'm not sure what the best way to replace the ViewPager would be. As far as I know I can either try to disable all ViewPager functionality and make it appear as it would be a single fragment (e.g. disable tabs and swipe), or I could use nested fragments. Yet, I'm not convinced that either of this options is "clean".

Maybe I'm overlooking something here and there is a more intuitive way to achieve the same? What are you guys thinking about this and how do you implement something "basic" as this?

P.S.: Obviously I could use activities for this, but I think that an Activity is too heavy for a simple "About" text and in my understanding one should try to use Fragments wherever possible these days.

هل كانت مفيدة؟

المحلول

As I can understand, you could put the ViewPager inside a parent as FrameLayout and add() the "about" fragment with addToBackState() method above the ViewPager.
You will avoid to disable or refresh the ViewPager. Just add above it a new fragment.


UPDATE

I'm able to achieve it with add() method and a custom background on the added fragment to avoid the overlap issues. And finally make this background clickable to prevent the click events for the behind ViewPager.
See my activity layout:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    tools:context="com.example.viewpageroverlap.MainActivity"
    android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <android.support.v4.view.ViewPager
        android:id="@+id/pager"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</FrameLayout>

My Menu item event:

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    int id = item.getItemId();
    if (id == R.id.action_settings) {
        getSupportFragmentManager().beginTransaction()
            .add(R.id.container, OverlapFragment.newInstance(990), null).addToBackStack(null).commit();
        return true;
    }
    return super.onOptionsItemSelected(item);
}

My Overlap Fragment layout:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.viewpageroverlap.MainActivity$OverlapFragment"
    android:background="#FF0000"
    android:clickable="true" >

    <TextView
        android:id="@+id/section_label"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center" />

</RelativeLayout>  

This gives me this output:

Screenshot Viewpager Overlaped by Fragment

Note: I used a red background but you can try with Android Resources Color and avoid to use a color declared in your files as android:background="@android:color/white".

WITH TABS

You can do the same as above and reset the navigation with NAVIGATION_MODE_STANDARD:

if (id == R.id.action_settings) {
    getSupportActionBar().setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
    getSupportFragmentManager().beginTransaction()
        .add(R.id.container, OverlapFragment.newInstance(990), null).addToBackStack(null).commit();
    return true;
}  

Then, when the user come back to the ViewPager (when he presses the home button or hardware back button), reset the old navigation as:

// do the same with android.R.id.home inside onOptionsItemSelected
@Override
public void onBackPressed() {
    // check if the "about" fragment is still displayed
    if(this.getSupportFragmentManager().getBackStackEntryCount() > 0) {
        actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
        this.getSupportFragmentManager().popBackStack();
    }
}

نصائح أخرى

Just have the ViewPager in its own fragment and replace that when you want to change to another fragment using regular fragment transactions.

If you turn on addToBackStack those transactions will react to the back button in a natrual way.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top