上一节,我们通过SlidingMenu+Fragment来实现了当前最流行的侧滑,具体连接如下:http://www.krislq.com/2013/03/android_case_slidingmenu_fragment/ 本文主要是在前一个例子中进行了一些改进,不仅仅只使用fragment , 而我们很多实际的应用场景中我们需要一个更复杂的场景,比如说需要在一个菜单选项中集成多个tab来集中显示信息。这个时候 Viewpager就派上用场了。
添加slidingMenu的步骤我就不再重复了,可以看看上篇文章 ,编码为UTF-8 .
上一个实例中,我们点击么二个菜单,只是显示一个简单的fragment ,这次我们将把它改造成Viewpager+Fragment模式。在运行实例的时候,可以通过点击“Menu:ViewPager”菜单来看具体的效果。
首先我们需要添加一个PagerAdapter来自动适配Tab里面的Fragment ,就像ListView中的BaseAdapter差不多,只是需要实现的方法有一些区别。
DemoFragmentAdapter.java
public class DemoFragmentAdapter extends PagerAdapter {
private final FragmentManager mFragmentManager;
private FragmentTransaction mTransaction = null;
private List mFragmentList = new ArrayList(4);
public DemoFragmentAdapter(FragmentManager fm) {
mFragmentManager = fm;
mFragmentList.add(new ContentFragment("ViewPager#Frist"));
mFragmentList.add(new ContentFragment("ViewPager#Second"));
mFragmentList.add(new ContentFragment("ViewPager#Third"));
}
@Override
public int getCount() {
return mFragmentList.size();
}
@Override
public boolean isViewFromObject(View view, Object object) {
return ((Fragment) object).getView() == view;
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
if (mTransaction == null) {
mTransaction = mFragmentManager.beginTransaction();
}
String name = getTag(position);
Fragment fragment = mFragmentManager.findFragmentByTag(name);
if (fragment != null) {
mTransaction.attach(fragment);
} else {
fragment = getItem(position);
mTransaction.add(container.getId(), fragment,
getTag(position));
}
return fragment;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
if (mTransaction == null) {
mTransaction = mFragmentManager.beginTransaction();
}
mTransaction.detach((Fragment) object);
}
@Override
public void finishUpdate(ViewGroup container) {
if (mTransaction != null) {
mTransaction.commitAllowingStateLoss();
mTransaction = null;
mFragmentManager.executePendingTransactions();
}
}
public Fragment getItem(int position){
return mFragmentList.get(position);
}
public long getItemId(int position) {
return position;
}
protected String getTag(int position){
return mFragmentList.get(position).getText();
}
}
</pre>
代码解释:
instantiateItem 此方法返回一个对象,告诉PagerAdapter选择哪一个对象
destroyItem 此方法是移当前Object
finishUpdate 是在UI更新完成后的动作
isViewFromObject 判断是否由对象生成 view ,一般写法都比较固定
适配器写完了,接下来就是如何使用它了。我们知道在显示的时候是通过第二个菜单点击的。
我们重点来看一下第二个菜单点击后的动作即可:
else if("b".equals(key)) {
if(index == 1) {
((MainActivity)getActivity()).getSlidingMenu().toggle();
return true;
}
index = 1;
mFrameLayout.setVisibility(View.GONE);
mViewPager.setVisibility(View.VISIBLE);
DemoFragmentAdapter demoFragmentAdapter = new DemoFragmentAdapter(mActivity.getFragmentManager());
mViewPager.setOffscreenPageLimit(5);
mViewPager.setAdapter(demoFragmentAdapter);
mViewPager.setOnPageChangeListener(onPageChangeListener);
ActionBar actionBar = mActivity.getActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
actionBar.removeAllTabs();
actionBar.addTab(actionBar.newTab()
.setText("First Tab")
.setTabListener(tabListener));
actionBar.addTab(actionBar.newTab()
.setText("Second Tab")
.setTabListener(tabListener));
actionBar.addTab(actionBar.newTab()
.setText("Third Tab")
.setTabListener(tabListener));
代码解释:
1. 先还是判断,如果当前Content里面显示的就是该菜单的内容,则直接显示内容。
2.接下来是把Viewpager显示出来。在这里需要注意的是,我们的Viewpager是单独定义的,与其它 Menu显示区域是不同的,并且也是不能同时显示的。具体的布局变化请看frame_content.xml,在这里就不再列出来了。
3.紧接着就是初始化DemoFragmentAdapter,并且设置给Viewpager
4.当然我们需要将我们的ActionBar设置成TAB模式,并且 添加上TAB的标题。
在上面过程中有两个listener需要注意一下:
1. SimpleOnPageChangeListener.该监听是当我们的viewpager页面切换的时候会触发 ,在里面我们会去改变 tab的聚焦情况 。因为实现上viewpager与actionbar是独立的,需要我们手动同步 。代码如下:
ViewPager.SimpleOnPageChangeListener onPageChangeListener = new ViewPager.SimpleOnPageChangeListener() {
@Override
public void onPageSelected(int position) {
getActivity().getActionBar().setSelectedNavigationItem(position);
switch (position) {
case 0:
getSlidingMenu().setTouchModeAbove(SlidingMenu.TOUCHMODE_FULLSCREEN);
break;
default:
getSlidingMenu().setTouchModeAbove(SlidingMenu.TOUCHMODE_MARGIN);
break;
}
}
};
代码解释:
setSelectedNavigationItem 方法用于设置ActionBar的聚焦tab .
在接下来我们判断了SLidingMenu的手势力模式,如果ViewPager已经滑到了最左边,则我们把手势设置成全屏的,这样更往左滑动的时候,就会打开Menu .
2.tabListener 主要是用来监听当我们自己点击tab改变页面的时候,那么我们Viewpager的内容也得随着改变。代码如下:
ActionBar.TabListener tabListener = new ActionBar.TabListener() {
@Override
public void onTabSelected(ActionBar.Tab tab, FragmentTransaction ft) {
if (mViewPager.getCurrentItem() != tab.getPosition())
mViewPager.setCurrentItem(tab.getPosition());
}
@Override
public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction ft) {
}
@Override
public void onTabReselected(ActionBar.Tab tab, FragmentTransaction ft) {
}
};
代码解释:
Viewpager可以直接设置当前的Item .
到这里我们的讲解就算到了一段落了。
希望大用能经常使用这种模式。另外在3.0以下的系统中,support里面也提供了FragmentPagerAdapter ,使用方法比这个简单,大家就自己学着试用吧!
代码来啰 。。。
====================
SlidingMenu+Viewpager
====================