Swapable Tabs In Slider Menu Fragment
Solution 1:
You must create a fragment with a custom layout that contains a ViewPager on it.
Follow these steps, it will guide in the entire process.
1. Create the layout to represent the ViewPager, name it fragment_main.xml
<TabHostandroid:id="@android:id/tabhost"android:layout_width="match_parent"android:layout_height="match_parent"><LinearLayoutandroid:orientation="vertical"android:layout_width="match_parent"android:layout_height="match_parent"><TabWidgetandroid:id="@android:id/tabs"android:orientation="horizontal"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_weight="0"/><FrameLayoutandroid:id="@android:id/tabcontent"android:layout_width="0dp"android:layout_height="0dp"android:layout_weight="0"/><android.support.v4.view.ViewPagerandroid:id="@+id/pager"android:layout_width="match_parent"android:layout_height="0dp"android:layout_weight="1"/></LinearLayout></TabHost>
2. Create a fragment to hold the ViewPager declared on the XML above, name it MyFragment.java
As you can see, we declare the TabHost
the ViewPager
and other elements declared in the XML above. Also in this fragment we inflate the layout created before, and a TabAdapter
to handle all the tabs.
import android.content.Context;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v4.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TabHost;
import android.widget.TabWidget;
import java.util.ArrayList;
publicstaticclassMyFragmentextendsFragment
{
private TabHost mTabHost;
private ViewPager mViewPager;
private TabsAdapter mTabsAdapter;
publicMyFragment() {
}
@OverridepublicvoidonCreate(Bundle instance)
{
super.onCreate(instance);
}
@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
Viewv= inflater.inflate(R.layout.fragment_main, container, false);
mTabHost = (TabHost) v.findViewById(android.R.id.tabhost);
mTabHost.setup();
mViewPager = (ViewPager) v.findViewById(R.id.pager);
mTabsAdapter = newTabsAdapter(getActivity(), mTabHost, mViewPager);
// Here we load the content for each tab.
mTabsAdapter.addTab(mTabHost.newTabSpec("one").setIndicator("One"), PageOneFragment.class, null);
mTabsAdapter.addTab(mTabHost.newTabSpec("two").setIndicator("Two"), PageTwoFragment.class, null);
return v;
}
publicstaticclassTabsAdapterextendsFragmentPagerAdapterimplementsTabHost.OnTabChangeListener, ViewPager.OnPageChangeListener
{
privatefinal Context mContext;
privatefinal TabHost mTabHost;
privatefinal ViewPager mViewPager;
privatefinal ArrayList<TabInfo> mTabs = newArrayList<TabInfo>();
staticfinalclassTabInfo
{
privatefinal String tag;
privatefinal Class<?> clss;
privatefinal Bundle args;
TabInfo(String _tag, Class<?> _class, Bundle _args)
{
tag = _tag;
clss = _class;
args = _args;
}
}
staticclassDummyTabFactoryimplementsTabHost.TabContentFactory
{
privatefinal Context mContext;
publicDummyTabFactory(Context context)
{
mContext = context;
}
public View createTabContent(String tag)
{
Viewv=newView(mContext);
v.setMinimumWidth(0);
v.setMinimumHeight(0);
return v;
}
}
publicTabsAdapter(FragmentActivity activity, TabHost tabHost, ViewPager pager)
{
super(activity.getSupportFragmentManager());
mContext = activity;
mTabHost = tabHost;
mViewPager = pager;
mTabHost.setOnTabChangedListener(this);
mViewPager.setAdapter(this);
mViewPager.setOnPageChangeListener(this);
}
publicvoidaddTab(TabHost.TabSpec tabSpec, Class<?> clss, Bundle args)
{
tabSpec.setContent(newDummyTabFactory(mContext));
Stringtag= tabSpec.getTag();
TabInfoinfo=newTabInfo(tag, clss, args);
mTabs.add(info);
mTabHost.addTab(tabSpec);
notifyDataSetChanged();
}
@OverridepublicintgetCount()
{
return mTabs.size();
}
@Overridepublic Fragment getItem(int position)
{
TabInfoinfo= mTabs.get(position);
return Fragment.instantiate(mContext, info.clss.getName(), info.args);
}
publicvoidonTabChanged(String tabId)
{
intposition= mTabHost.getCurrentTab();
mViewPager.setCurrentItem(position);
}
publicvoidonPageScrolled(int position, float positionOffset, int positionOffsetPixels)
{
}
publicvoidonPageSelected(int position)
{
// Unfortunately when TabHost changes the current tab, it kindly// also takes care of putting focus on it when not in touch mode.// The jerk.// This hack tries to prevent this from pulling focus out of our// ViewPager.TabWidgetwidget= mTabHost.getTabWidget();
intoldFocusability= widget.getDescendantFocusability();
widget.setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS);
mTabHost.setCurrentTab(position);
widget.setDescendantFocusability(oldFocusability);
}
publicvoidonPageScrollStateChanged(int state)
{
}
}
}
As you can see, each tab calls a specific fragment. These fragments represent the content for each tab. So let's create them, they are very simple, and contains only a TextView
.
3. Create a fragment for the first tab content, name it PageOneFragment.java
This fragment will hold the content of the first tab. You can put anything inside this fragment, it will live separated from the other fragments and from the other tabs.
Here we inflate the xml layout pageone_fragment.xml inside the onCreateView
method. We will create this xml layout in the next step.
import android.app.Activity;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
publicclassPageOneFragmentextendsFragment
{
@OverridepublicvoidonCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
}
@OverridepublicViewonCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
return inflater.inflate(R.layout.pageone_fragment, container, false);
}
@OverridepublicvoidonActivityCreated(Bundle savedInstanceState)
{
super.onActivityCreated(savedInstanceState);
}
@OverridepublicvoidonAttach(Activity activity)
{
super.onAttach(activity);
}
@OverridepublicvoidonStart()
{
super.onStart();
}
@OverridepublicvoidonResume()
{
super.onResume();
}
}
We must create the layout for this fragment as we mentioned before.
4. Create the layout for the PageOneFragment, name it pageone_fragment.xml
This is just a simple layout with a TextView
to represent the content of the tab. You can build anything you want inside this layout, it will live separated from the other fragments and tabs.
<?xml version="1.0" encoding="utf-8"?><LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"android:id="@+id/first_fragment"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"android:paddingLeft="@dimen/activity_horizontal_margin"android:paddingRight="@dimen/activity_horizontal_margin"android:paddingTop="@dimen/activity_vertical_margin"android:paddingBottom="@dimen/activity_vertical_margin"android:background="#ff4063ff"><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:textAppearance="?android:attr/textAppearanceMedium"android:text="First Page"android:textColor="#FFFFFF"android:textStyle="bold"android:id="@+id/firstFragmentTextView"android:layout_gravity="center_horizontal|top" /></LinearLayout>
As we have two tabs, we have two fragments, one for each tab. So let's create the second fragment for the second tab content.
5. Create the fragment for the second tab content, name it PageTwoFragment.java
As you can see, we inflate a different layout on the onCreateView
method, it's called pagetwo_fragment.xml
. We will create it on the next step.
import android.app.Activity;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
publicclassPageTwoFragmentextendsFragment
{
@OverridepublicvoidonCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
}
@OverridepublicViewonCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
return inflater.inflate(R.layout.pagetwo_fragment, container, false);
}
@OverridepublicvoidonActivityCreated(Bundle savedInstanceState)
{
super.onActivityCreated(savedInstanceState);
}
@OverridepublicvoidonAttach(Activity activity)
{
super.onAttach(activity);
}
@OverridepublicvoidonStart()
{
super.onStart();
}
@OverridepublicvoidonResume()
{
super.onResume();
}
}
And as we did before for the PageOneFragment, let's create the layout for the second fragment too, as we mentioned before.
6. Create the layout for the PageTwoFragment, name it pagetwo_fragment.xml
This is a simple layout with a single TextView
, just to represent the content. You can build anything you want in here, it will live separated from the other fragments and tabs.
<?xml version="1.0" encoding="utf-8"?><LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"android:id="@+id/first_fragment"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"android:paddingLeft="@dimen/activity_horizontal_margin"android:paddingRight="@dimen/activity_horizontal_margin"android:paddingTop="@dimen/activity_vertical_margin"android:paddingBottom="@dimen/activity_vertical_margin"android:background="#ff4063ff"><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:textAppearance="?android:attr/textAppearanceMedium"android:text="Second Page"android:textColor="#FFFFFF"android:textStyle="bold"android:id="@+id/firstFragmentTextView"android:layout_gravity="center_horizontal|top" /></LinearLayout>
7. Call this fragment from your NavigationDrawer
If you want to call this fragment from your NavigationDrawer
, inside the switch
statement on your activity's displayView(int position)
method, you should do this in one of your case
statements, for example.
case0:
fragment = newMyFragment();
break;
Here is the final result
A ViewPager
running on a fragment, with two tabs each contains a unique fragment with a unique content.
That's it.
Hope this helps you.
Solution 2:
For error in step 7 "Type mismatch
make it:
replace **import android.app.Fragment** to **import android.support.v4.app.Fragment**
and in case:
android.support.v4.app.FragmentManagerfragmentManager= getSupportFragmentManager();
fragmentManager.beginTransaction().replace(R.id.frame_container, fragment).commit();
Solution 3:
publicvoidaddTab(TabHost.TabSpec tabSpec, Class<?> clss, Bundle args)
{
tabSpec.setContent(newDummyTabFactory(mContext));
Stringtag= tabSpec.getTag();
TabInfoinfo=newTabInfo(tag, clss, args);
mTabs.add(info);
mTabHost.addTab(tabSpec);
notifyDataSetChanged();
}
where declaration of mTabs variable
thanks
Post a Comment for "Swapable Tabs In Slider Menu Fragment"