今天我们要实现的这个效果呢,在Android的应用中十分地常见,我们可以看到下面两张图,无论是系统内置的联系人应用,还是AnyView的阅读器应用,我们总能找到这样的影子,当我们滑动屏幕时,Tab可以相应地完成切换,而当我们点击Tab时,我们的屏幕同样可以完成切换。讲到滑动,我们会立即想到PagerView,讲到ActionBar,我们立即会想到将ActionBar的导航模式。那么,我们今天要做的一件事情就是,通过这些组件的组合,来实现这样一个效果。

按照一般的思路,我们或许会这么做:首先,使用getActionBar()方法获得操作栏,然后我们将操作栏的导航模式设置为Tab,并添加一些Tab,然后实现TabListener接口;其次,我们将多个布局通过Inflater()方法变成View,然后放到ViewPager里面(其实呢,ViewPager就是个容器啦,你换成FrameLayout也是一样的,所以这里可以用Fragment替换就是这个道理),并实现OnPageChangeListener接口就可以了。由此我们可以写出下面的代码:

  1. package com.Android.AnyViewUI;
  2. import java.util.ArrayList;
  3. import android.os.Bundle;
  4. import android.support.v4.app.FragmentActivity;
  5. import android.support.v4.app.FragmentManager;
  6. import android.support.v4.view.ViewPager;
  7. import android.support.v4.view.ViewPager.OnPageChangeListener;
  8. import android.app.ActionBar;
  9. import android.app.ActionBar.Tab;
  10. import android.app.ActionBar.TabListener;
  11. import android.app.Activity;
  12. import android.app.FragmentTransaction;
  13. import android.view.LayoutInflater;
  14. import android.view.View;
  15. public class MainActivity extends FragmentActivity implements TabListener,OnPageChangeListener {
  16. private ActionBar mActionBar;
  17. private ViewPager mViewPager;
  18. private TabPagerAdapter mAdapter;
  19. private ArrayList<View> mViews;
  20. private ArrayList<ActionBar.Tab> mTabs;
  21. @Override
  22. protected void onCreate(Bundle savedInstanceState) {
  23. super.onCreate(savedInstanceState);
  24. setContentView(R.layout.layout_main);
  25. //取得ActionBar
  26. mActionBar=getActionBar();
  27. //以Tab方式导航
  28. mActionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
  29. //禁用ActionBar标题
  30. mActionBar.setDisplayShowTitleEnabled(false);
  31. //禁用ActionBar图标
  32. mActionBar.setDisplayUseLogoEnabled(false);
  33. //禁用ActionBar返回键
  34. mActionBar.setDisplayShowHomeEnabled(false);
  35. //添加Tabs
  36. mTabs=new ArrayList<ActionBar.Tab>();
  37. ActionBar.Tab tab0=mActionBar.newTab();
  38. tab0.setText("界面一");
  39. tab0.setTabListener(this);
  40. mTabs.add(tab0);
  41. mActionBar.addTab(tab0);
  42. ActionBar.Tab tab1=mActionBar.newTab();
  43. tab1.setText("界面二");
  44. tab1.setTabListener(this);
  45. mTabs.add(tab1);
  46. mActionBar.addTab(tab1);
  47. ActionBar.Tab tab2=mActionBar.newTab();
  48. tab2.setText("界面三");
  49. tab2.setTabListener(this);
  50. mTabs.add(tab2);
  51. mActionBar.addTab(tab2);
  52. //获取ViewPager
  53. mViewPager=(ViewPager)findViewById(R.id.ViewPager);
  54. //初始化mViews
  55. mViews=new ArrayList<View>();
  56. mViews.add(LayoutInflater.from(this).inflate(R.layout.layout_0, null));
  57. mViews.add(LayoutInflater.from(this).inflate(R.layout.layout_1, null));
  58. mViews.add(LayoutInflater.from(this).inflate(R.layout.layout_2, null));
  59. //初始化mAdapter
  60. mAdapter=new TabPagerAdapter(mViews);
  61. mViewPager.setAdapter(mAdapter);
  62. mViewPager.setOnPageChangeListener(this);
  63. //默认显示第二项
  64. mViewPager.setCurrentItem(2);
  65. }
  66. @Override
  67. public void onTabReselected(Tab mTab, FragmentTransaction arg1)
  68. {
  69. }
  70. @Override
  71. public void onTabSelected(Tab mTab, FragmentTransaction arg1)
  72. {
  73. if(mViewPager!=null)
  74. {
  75. mViewPager.setCurrentItem(mTab.getPosition());
  76. }
  77. }
  78. @Override
  79. public void onTabUnselected(Tab mTab, FragmentTransaction arg1)
  80. {
  81. }
  82. @Override
  83. public void onPageScrollStateChanged(int arg0)
  84. {
  85. }
  86. @Override
  87. public void onPageScrolled(int arg0, float arg1, int arg2)
  88. {
  89. }
  90. @Override
  91. public void onPageSelected(int Index)
  92. {
  93. //设置当前要显示的View
  94. mViewPager.setCurrentItem(Index);
  95. //选中对应的Tab
  96. mActionBar.selectTab(mTabs.get(Index));
  97. }
  98. }

其中,TabPagerAdapter是一个继承自PagerAdapter的适配器类:

  1. package com.Android.AnyViewUI;
  2. import java.util.ArrayList;
  3. import android.support.v4.view.PagerAdapter;
  4. import android.support.v4.view.ViewPager;
  5. import android.view.View;
  6. public class TabPagerAdapter extends PagerAdapter
  7. {
  8. private ArrayList<View> mViews;
  9. public TabPagerAdapter(ArrayList<View> mViews)
  10. {
  11. this.mViews=mViews;
  12. }
  13. @Override
  14. public void destroyItem(View container, int position, Object object)
  15. {
  16. ((ViewPager)container).removeView(mViews.get(position));
  17. }
  18. @Override
  19. public Object instantiateItem(View container, int position)
  20. {
  21. ((ViewPager)container).addView(mViews.get(position), 0);
  22. return mViews.get(position);
  23. }
  24. @Override
  25. public int getCount()
  26. {
  27. return mViews.size();
  28. }
  29. @Override
  30. public boolean isViewFromObject(View mView, Object mObject)
  31. {
  32. return (mView==mObject);
  33. }
  34. }

我们的代码从逻辑上来讲是没有什么问题的,但是当我们试图运行这段代码的时候,我们发现这段代码出了问题,而问题就出在OnTabSelected()上。但是我们冷静下来想了想,没有错啊,那么问题到底出在哪里呢?看到网上的朋友说,这里这个适配器应该继承自FragmentPagerAdapter:

  1. package com.Android.AnyViewUI;
  2. import android.support.v4.app.Fragment;
  3. import android.support.v4.app.FragmentManager;
  4. import android.support.v4.app.FragmentPagerAdapter;
  5. public class ViewPagerAdapter extends FragmentPagerAdapter {
  6. //定义三个Fragment的索引
  7. public static final int Fragment_Index_0=0;
  8. public static final int Fragment_Index_1=1;
  9. public static final int Fragment_Index_2=2;
  10. public ViewPagerAdapter(FragmentManager fragmentManager)
  11. {
  12. super(fragmentManager);
  13. }
  14. @Override
  15. public Fragment getItem(int Index)
  16. {
  17. Fragment mFragemnt=null;
  18. switch(Index)
  19. {
  20. case Fragment_Index_0:
  21. mFragemnt=new Fragment_0();
  22. break;
  23. case Fragment_Index_1:
  24. mFragemnt=new Fragment_1();
  25. break;
  26. case Fragment_Index_2:
  27. mFragemnt=new Fragment_2();
  28. break;
  29. }
  30. return mFragemnt;
  31. }
  32. @Override
  33. public int getCount()
  34. {
  35. return 3;
  36. }
  37. }

其中,Fragment_0、Fragment_1、Fragment_2是继承自Fragment的类,由于三个布局基本一样,这里只给出Fragment_0的代码:

  1. package com.Android.AnyViewUI;
  2. import android.os.Bundle;
  3. import android.support.v4.app.Fragment;
  4. import android.view.LayoutInflater;
  5. import android.view.View;
  6. import android.view.ViewGroup;
  7. public class Fragment_0 extends Fragment
  8. {
  9. public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState)
  10. {
  11. View mView=inflater.inflate(R.layout.layout_0, container, false);
  12. return mView;
  13. }
  14. }

现在,我们将开始写好的代码中的mAdapter用这个适配器类去替换,然后我们发现程序可以运行了,可是为什么啊?看了Android文档,上面说FragmentPagerAdapter是实现了PagerAdapter,换句话说,真正起作用的还是PagerAdapter这个类,好,我们回头看这个类,在我们开始的代码中,我们在instantiateItem()、destroyItem()操作的对象始终是View,如果我们把这个View换成Fragment,把View[]换成Fragment[],在类内部使用FragmentManager对Fragment进行管理,我们会发现这样的效果和继承FragmentPagerAdapter是一样的,这样对于这两个适配器的关系我们就已经很明确了。可是,我还是想知道为什么刚开始的那个方法不行呢?希望知道这个问题的答案的朋友,可以告诉我,最后放上效果图:

ViewPager相关文章:

1、Android开发之ViewPager+ActionBar+Fragment实现响应式可滑动Tab

2、Android开发学习之基于ViewPager实现Gallery画廊效果

3、Android开发学习之使用ViewPager+PagerTabStrip制作可滑动的Tab

4、Android开发学习之使用ViewPager打造应用引导界面面

Android开发之ViewPager+ActionBar+Fragment实现响应式可滑动Tab的更多相关文章

  1. Android开发之ViewPager的简单使用

    ViewPager是V4包中的,如果你的编译器敲不出ViewPager,那么你就需要添加,看下面: 第一步:点击+号 第二步:选择第一个Library 第三步:添加这个包: 然后点击ok-->o ...

  2. Android开发之ViewPager

    什么是ViewPager? ViewPager是安卓3.0之后提供的新特性,继承自ViewGroup,专门用以实现左右滑动切换View的效果. 如果想向下兼容就必须要android-support-v ...

  3. Android开发之ViewPager实现轮播图(轮播广告)效果的自定义View

    最近开发中需要做一个类似京东首页那样的广告轮播效果,于是采用ViewPager自己自定义了一个轮播图效果的View. 主要原理就是利用定时任务器定时切换ViewPager的页面. 效果图如下: 主页面 ...

  4. Android开发之ViewPager实现多页面切换及动画效果(仿Android的Launcher效果)

    Android开发中经常会有引导页或者切换页面等效果,本文采用ViewPager结合动画效果来实现仿Launcher以及页面切换的效果.源码地址在文章最后给出下载. 效果图如下:       1.Vi ...

  5. Android开发之ViewPager做新手引导界面

    先看一下我们要开发的界面(三张图片,滑到最后一个会出现开始体验的Button,下面的小红点会跟着一起滑动): 首先看一下布局文件: <?xml version="1.0" e ...

  6. Android开发之viewpager导报错误解决方法:错误代码 Caused by: java.lang.ClassNotFoundException: Didn't find class

    作者:程序员小冰,CSDN博客:http://blog.csdn.net/qq_21376985 Caused by: java.lang.ClassNotFoundException: Didn't ...

  7. Android开发之旅: Intents和Intent Filters(理论部分)

    引言 大部分移动设备平台上的应用程序都运行在他们自己的沙盒中.他们彼此之间互相隔离,并且严格限制应用程序与硬件和原始组件之间的交互. 我们知道交流是多么的重要,作为一个孤岛没有交流的东西,一定毫无意义 ...

  8. Android开发之Java必备基础

    Android开发之Java必备基础 Java类型系统 Java语言基础数据类型有两种:对象和基本类型(Primitives).Java通过强制使用静态类型来确保类型安全,要求每个变量在使用之前必须先 ...

  9. [置顶] Android开发之MediaPlayerService服务详解(一)

    前面一节我们分析了Binder通信相关的两个重要类:ProcessState 和 IPCThreadState.ProcessState负责打开Binder 驱动,每个进程只有一个.而 IPCThre ...

随机推荐

  1. 初识 MySQL 5.6 新功能、参数

    摘要: 继上一篇的文章 初识 MySQL 5.5 新功能.参数 之后,现在MySQL5.6 针对 MySQL5.5 各个方面又提升了很多,特别在性能和一些新参数上面,现在看看大致提升了哪些方面(后续不 ...

  2. Effective C++ -----条款12: 复制对象时勿忘其每一个成分

    Copying函数应该确保复制“对象内的所有成员变量”及“所有base class成分”. 不要尝试以某个copying函数实现另一个copying函数.应该将共同机能放进第三个函数中,并由两个cop ...

  3. 【python】类中的super().__init__()

    来源:百度知道 python中的super( test, self).__init__()是什么意思? 首先找到test的父类(比如是类A),然后把类test的对象self转换为类A的对象,然后&qu ...

  4. iOS计算字符串的宽度高度

    OC开发中会遇到根据字符串和字体大小来算计算出字符串所占的宽高->> 封装方法如下: #import <Foundation/Foundation.h> #import < ...

  5. 3ds max删除了对象后,还是将原来所有对象输出的原因

    原因是场景中除了 几何体 外还有 图形,如下图 将这些图形删除,几何体就都正常输出了.

  6. chaper3_exercise_Uva1585_score

    #include<iostream> #include<string> using namespace std; int main(void) { , j = ; string ...

  7. MyISAM表的维护和恢复

    本节将讨论如何使用myisamchk检查和修复MyISAM表. 同时,你可以用myisamchk来检查,修复和优化数据库表.下面将讲述如何执行这些操作并建立维护计划. 虽然使用myisamchk很安全 ...

  8. Mysql之performance Schema

    Performance schema是用于监控Mysql执行,具有如下特征: 1.用于在运行时探查Mysql Server的执行过程,是由Performance_schema引擎和 Performan ...

  9. 51nod1019逆序数(归并排序/树状数组)

    题目链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1019 题意:中文题诶- 思路: 方法1:归并排序- 归并排序过 ...

  10. nyoj998(euler)

    题意:题意:给出n和m,求满足条件gcd(x, n)>=m的x的gcd(x, n)的和,其中1<=x<=n,1<= n, m <= 1e9:思路:此题和nyoj1007差 ...