ViewPager + Fragment 替換 TabActivity
Fragment+ViewPager 替換 TabActivity
之前首頁的框架採用TabActivity+Activity的形式實現,首頁頁面切換時,性能消耗較大,本次修改可以大大節約頁面切換性能。
下面是這次框架調整的一些具體內容
思路
使用ViewPager作爲首頁的容器,替換TabActivity;
使用Fragment作爲具體頁面的容器,替換Activity;
將Fragment添加到ViewPager中,以實現頁面切換。
實現
ViewPager實現
引入:
ViewPager可以通過layout
- <android.support.v4.view.ViewPager xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="fill_parent"
- android:background="#ffffff"
- android:flipInterval="30"
- android:persistentDrawingCache="animation"
- android:layout_centerInParent="true"
- >
- </android.support.v4.view.ViewPager>
適配器:
因爲ViewPager中存放的是一系列的Fragment,所以需要一個Fragment的適配器,該適配器中保存了對首頁各個Fragment的列表的引用。
- public class MainFragmentPagerAdapter extends FragmentPagerAdapter {
- private ArrayList<Fragment> fragments;
- public MainFragmentPagerAdapter(FragmentManager fm) {
- super(fm);
- // TODO Auto-generated constructor stub
- }
- public MainFragmentPagerAdapter(FragmentManager fm,ArrayList<Fragment> fragments){
- super(fm);
- this.fragments = fragments;
- }
- /* (non-Javadoc)
- * @see android.support.v4.app.FragmentPagerAdapter#getItem(int)
- */
- @Override
- public Fragment getItem(int arg0) {
- return fragments.get(arg0);
- }
- /* (non-Javadoc)
- * @see android.support.v4.view.PagerAdapter#getCount()
- */
- @Override
- public int getCount() {
- return fragments.size();
- }
- @Override
- public int getItemPosition(Object object) {
- // TODO Auto-generated method stub
- return super.getItemPosition(object);
- }
- }
事件:
這裏主要處理兩個事件,1.OnPageChange事件;2.OnTouch事件
這兩個事件的任務是:
1.OnPageChange事件,當頁面發生切換時,通知底部工具欄改變焦點,以實現底部工具欄和頁面之間同步。
2.OnTouch事件,該事件用於分發touch事件,解決與“主頁”中的Gallery橫屏時事件衝突的問題。
- viewPager.setOnPageChangeListener(pageChangeListener);
- viewPager.setOnTouchListener(touchListener);
- pageChangeListener定義如下:
- private OnPageChangeListener pageChangeListener = new OnPageChangeListener() {
- @Override
- public void onPageSelected(int arg0) {
- setIconSelected(arg0);
- }
- @Override
- public void onPageScrolled(int arg0, float arg1, int arg2) {
- }
- @Override
- public void onPageScrollStateChanged(int arg0) {
- }
- };
touchListener定義如下:
- private OnTouchListener touchListener = new OnTouchListener(){
- @Override
- public boolean onTouch(View v, MotionEvent event) {
- if (currentIndex != 0) {
- return false;
- }
- int[] location = new int[2];
- homeFragment.gallery.getLocationOnScreen(location);
- if (location[0] != 0) {
- return false;
- }
- if (event.getRawY() > location[1]
- && event.getRawY() - location[1] < homeFragment.gallery
- .getHeight()) {
- return homeFragment.gallery.dispatchTouchEvent(event);
- }
- return false;
- }
- };
Fragment實現
Fragment的實現方式和Activity的實現方式基本相同,所需要注意的是要重寫onCreateView方法。主要的內容是將Activity的onCreate方法中的內容寫到Fragment的onCrateView方法中。例如SettingActivity中的onCrate方法如下:
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.setting);
- getView();
- setListener();
- }
對應的Fragment中的onCrateView方法爲:
- public View onCreateView(LayoutInflater inflater, ViewGroup container,
- Bundle savedInstanceState) {
- Utils.log("onCreateView");
- View v = inflater.inflate(R.layout.setting, container, false);
- getViews(v);
- setListener();
- return v;
- }
注意點
ViewPager與底部工具欄同步
Viewpager改變通知底部工具欄索引改變:
viewPager.setOnPageChangeListener(pageChangeListener);然後再onPageSelected方法中處理
底部工具欄索引發生改變通知ViewPager切換頁面
viewPager.setCurrentItem(i);
與Gallery衝突解決
爲ViewPager註冊Touch事件
- private OnTouchListener touchListener = new OnTouchListener(){
- @Override
- public boolean onTouch(View v, MotionEvent event) {
- if (currentIndex != 0) {
- return false;
- }
- int[] location = new int[2];
- homeFragment.gallery.getLocationOnScreen(location);
- if (location[0] != 0) {
- return false;
- }
- if (event.getRawY() > location[1]
- && event.getRawY() - location[1] < homeFragment.gallery
- .getHeight()) {
- return homeFragment.gallery.dispatchTouchEvent(event);
- }
- return false;
- }
- };
默認情況下ViewPager內的Gallery拖動時沒有效果,可以參考android的事件傳遞模型,這裏是在touch的時候指定某一區域的事件傳遞到Gallery中去,算是一個補丁吧。