Answer on Question#39759- Programming, Other
Swipe + Tabs - scrolling screens and their Tabs
1. Project preparation
Before embarking on this task, we need to connect the library backward compatibility.
2. Preparation resources
Open the file main.xml and mount the following code:
android:id="@android:id/tabhost"
android:layout_width="match_parent"
android:layout_height="match_parent" >
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
android:id="@android:id/tabcontent"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="0" />
android:id="@+id/pager"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
android:id="@android:id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0"
android:orientation="horizontal" />
3. Preparation Activity
To implement this example, we will not be inherited from Activity, and from FragmentActivity (we'll talk about fragments in the next article):
public class MainActivity extends FragmentActivity
In the onCreate method, type the following:
private TabHost mTabHost;
private ViewPager mViewPager;
private TabsAdapter mTabsAdapter;
@Override
public void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTabHost = (TabHost) findViewById(android.R.id.tabhost);
mTabHost.setup();
mViewPager = (ViewPager) findViewById(R.id.pager);
mTabsAdapter = new TabsAdapter(this, mTabHost, mViewPager);
mTabsAdapter.addTab(mTabHost.newTabSpec("simple").setIndicator("Android"), AndroidFragment.class, null);
mTabsAdapter.addTab(mTabHost.newTabSpec("contacts").setIndicator("IOs"), IOsFragment.class, null);
mTabsAdapter.addTab(mTabHost.newTabSpec("custom").setIndicator("Windows"), WindowsFragment.class, null);
mTabsAdapter.addTab(mTabHost.newTabSpec("throttle").setIndicator("DOS"), DOSFragment.class, null);
if (savedInstanceState != null) {
mTabHost.setCurrentTabByTag(savedInstanceState.getString("tab"));
}
}
4. Implementing Adapter
Create a adapter that we will inherit from FragmentPagerAdapter, as well as for the treatment of clicks on Tabs we will subscribe to the event handler TabHost.OnTabChangeListener for scrolling pages also subscribe to ViewPager.OnPageChangeListener.
The full code can be seen below:
public static class TabsAdapter extends FragmentPagerAdapter implements TabHost.OnTabChangeListener,
ViewPager.OnPageChangeListener {
private final Context mContext;
private final TabHost mTabHost;
private final ViewPager mViewPager;
private final ArrayList mTabs = new ArrayList();
static final class TabInfo {
private final String tag;
private final Class clss;
private final Bundle args;
TabInfo(final String _tag, final Class _class, final Bundle _args) {
tag = _tag;
clss = _class;
args = _args;
}
}
static class DummyTabFactory implements TabHost.TabContentFactory {
private final Context mContext;
public DummyTabFactory(final Context context) {
mContext = context;
}
@Override
public View createTabContent(final String tag) {
View v = new View(mContext);
v.setMinimumWidth(0);
v.setMinimumHeight(0);
return v;
}
}
public TabsAdapter(final FragmentActivity activity, final TabHost tabHost, final ViewPager pager) {
super(activity.getSupportFragmentManager());
mContext = activity;
mTabHost = tabHost;
mViewPager = pager;
mTabHost.setOnTabChangedListener(this);
mViewPager.setAdapter(this);
mViewPager.setOnPageChangeListener(this);
}
public void addTab(final TabHost.TabSpec tabSpec, final Class clss, final Bundle args) {
tabSpec.setContent(new DummyTabFactory(mContext));
String tag = tabSpec.getTag();
TabInfo info = new TabInfo(tag, clss, args);
mTabs.add(info);
mTabHost.addTab(tabSpec);
notifyDataSetChanged();
}
@Override
public int getCount() {
return mTabs.size();
}
@Override
public Fragment getItem(final int position) {
TabInfo info = mTabs.get(position);
return Fragment.instantiate(mContext, info.clss.getName(), info.args);
}
@Override
public void onTabChanged(final String tabId) {
int position = mTabHost.getCurrentTab();
mViewPager.setCurrentItem(position);
}
@Override
public void onPageScrolled(final int position, final float positionOffset, final int positionOffsetPixels) {
}
@Override
public void onPageSelected(final 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.
TabWidget widget = mTabHost.getTabWidget();
int oldFocusability = widget.getDescendantFocusability();
widget.setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS);
mTabHost.setCurrentTab(position);
widget.setDescendantFocusability(oldFocusability);
}
@Override
public void onPageScrollStateChanged(final int state) {
}
}
5. The final stage
Of paragraph 2 shows that we have 4 new fragment. So let them create.
AndroidFragment:
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class AndroidFragment extends Fragment {
@Override
public View onCreateView(final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.android_fragment, container, false);
return view;
}
}
IOsFragment:
public class IOsFragment extends Fragment {
@Override
public View onCreateView(final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.ios_fragment, container, false);
return view;
}
}
WindowsFragment:
public class WindowsFragment extends Fragment {
@Override
public View onCreateView(final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.windows_fragment, container, false);
return view;
}
}
DOSFragment:
public class DOSFragment extends Fragment {
@Override
public View onCreateView(final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.dos_fragment, container, false);
return view;
}
}
Now we need to create another 4 xml file that we use in fragments
android_fragment.xml
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Android" />
dos_fragment.xml
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="DOS" />
ios_fragment.xml
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="IOs" />
windows_fragment.xml
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Windows" />
Comments
Leave a comment