Question

I implemented my navigation app with Navigation Drawer but one of the item open fragment with two tabs.

The tabs I have implemented a "FragmentTabHost" because Roman Nurik does not recommend the use of "ViewPager" with "NavigationDrawer".

Roman Nurik https://plus.google.com/u/0/+DavidTaSmoochibi/posts/8dWEkFcbTFX

Everything works fine me the problem I have is that FragmentTabHost Is it possible to implement horizontal swipe between tabs?

Attach code:

Main_Activity.xml

<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent" >

<FrameLayout
    android:id="@+id/content_frame"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

<ListView
    android:id="@+id/left_drawer"
    android:layout_width="240dp"
    android:layout_height="match_parent"
    android:layout_gravity="start"
    android:background="#111"
    android:choiceMode="singleChoice"
    android:divider="@android:color/transparent"
    android:dividerHeight="0dp" />

MainActivity.java

public class MainActivity extends ActionBarActivity {

private DrawerLayout            mDrawerLayout;
private ListView                mDrawerList;
private ActionBarDrawerToggle   mDrawerToggle;
private Fragment                fragment1;
private Fragment                fragment2;

private String[]                title;
private String[]                subtitle;
private int[]                   icon;

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

    fragment1 = new Fragment1();
    fragment2 = new Fragment2();

    /**
     * Implementacion del NavigationDrawer
     */
    title = new String[] {"Noticias", "Promociones"};
    subtitle = new String[] {"Noticias", "Promociones"};

    mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
    mDrawerList = (ListView) findViewById(R.id.left_drawer);

    mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START);

    mDrawerList.setAdapter(new ArrayAdapter<String>(this, R.layout.drawer_list_item, title));

    mDrawerList.setOnItemClickListener(new DrawerItemClickListener());

    //Enable ActionBar app icon to behave as action to toggle nav drawer
    getSupportActionBar().setHomeButtonEnabled(true);
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);

    mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, R.drawable.ic_drawer, R.string.drawer_open, R.string.drawer_close) {

        @Override
        public void onDrawerClosed(View drawerView) {
            // TODO Auto-generated method stub
            super.onDrawerClosed(drawerView);
        }

        @Override
        public void onDrawerOpened(View drawerView) {
            // TODO Auto-generated method stub
            super.onDrawerOpened(drawerView);
        }
    };

   mDrawerLayout.setDrawerListener(mDrawerToggle);

   if (savedInstanceState ==  null) {
       selectItem(0);
   }

}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // TODO Auto-generated method stub
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // TODO Auto-generated method stub

    if (item.getItemId() == android.R.id.home) {
        if (mDrawerLayout.isDrawerOpen(mDrawerList)) {
            mDrawerLayout.closeDrawer(mDrawerList);
        } else {
            mDrawerLayout.openDrawer(mDrawerList);
        }
    }

    return super.onOptionsItemSelected(item);
}

/**
 * The click listener for ListView in the navigation drawer
 * @author TeRRo
 */
private class DrawerItemClickListener implements ListView.OnItemClickListener {

    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        // TODO Auto-generated method stub
        selectItem(position);
    }

}

private void selectItem (int position) {
    FragmentTransaction ft = getSupportFragmentManager().beginTransaction();

    switch (position) {
    case 0:
        ft.replace(R.id.content_frame, fragment1);
        break;

    case 1:
        ft.replace(R.id.content_frame, fragment2);
        break;
    }
    ft.commit();
    //Close drawer
    mDrawerLayout.closeDrawer(mDrawerList);
}

@Override
protected void onPostCreate(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    super.onPostCreate(savedInstanceState);
    // Sync the toggle state after onRestoreInstanceState has occurred.
    mDrawerToggle.syncState();
}

@Override
public void onConfigurationChanged(Configuration newConfig) {
    // TODO Auto-generated method stub
    super.onConfigurationChanged(newConfig);
    // Pass any configuration change to the drawer toggles
    mDrawerToggle.onConfigurationChanged(newConfig);
}   
}

Fragment1.xml

<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" >

Fragment1.java

public class Fragment1 extends Fragment {

//Declare variable of TabHost
private FragmentTabHost mTabHost;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    // TODO Auto-generated method stub

    mTabHost = new FragmentTabHost(getActivity());
    mTabHost.setup(getActivity(), getChildFragmentManager(), R.layout.fragment1);
    mTabHost.addTab(mTabHost.newTabSpec("noticas").setIndicator("Noticias"), FragmentTab1.class, null);
    mTabHost.addTab(mTabHost.newTabSpec("promociones").setIndicator("Promociones"), FragmentTab2.class, null);


    return mTabHost;

}

//Detach FragmentTabHost
@Override
public void onDetach() {
    super.onDetach();

    try {
        Field childFragmentManager = Fragment.class
                .getDeclaredField("mChildFragmentManager");
        childFragmentManager.setAccessible(true);
        childFragmentManager.set(this, null);

    } catch (NoSuchFieldException e) {
        throw new RuntimeException(e);
    } catch (IllegalAccessException e) {
        throw new RuntimeException(e);
    }

}

//Remove FragmentTabHost
@Override
public void onDestroyView() {
    super.onDestroyView();
    mTabHost = null;
}

}

Can be implemented the horizontal swipe with a FragmentTabHost?

I searched for information but all say to make such things better to use ViewPager.

Était-ce utile?

La solution

So his complete answer was

You shouldn't use navigation drawers with action bar tabs. If you're aiming for a UI similar to that of Google Play Music, you should implement tabs manually (and beware of how this looks on tablet—you don't want full-width tab bars on tablets). Also make sure to check out the Structure in Android App Design session from this year's Google I/O for a detailed run-through of the various interface patterns available for exposing app hierarchy.

So basically he is recommending reconsidering UI ... and I suppose this is not recommended because pulling out drawer and swiping between tabs actually are using same gesture..

EDIT: if you really want to do TabHost-Swipe manually I guess the only way is to use Flipper and Gesture detector (implementing GestureListener).. It is a bit of code you need to implement but I hope this example of Swipe Action and ViewFlipper in Android can help you a bit.. ;)

EDIT2: and one more example here (like author knew we were talking about it yesterday ;) )

Autres conseils

On one of my projects, I had to do something similar. I wanted to design a view similar to Google News Stand. I could not find anything on the web that was simple to implement. So I wrote my own. I am using FragmentTabHost with ViewPager and scrollable tabs. Full implementation is on my blog post here.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top