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.

Was it helpful?

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 ;) )

OTHER TIPS

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top