一、效果演示及分析

我们直接看两幅图。如下:

                 

上两幅图实现的效果就是:

(1)手指左右滑动时,中间的布局呈现不同的效果。而且下面的按钮也会做相应的改变。

(2)我们也可以不左右滑动,直接点击下面的按钮来改变中间的布局。

这就是android开发中经常要用到的Tab效果,可以最大限度的使用屏幕资源。中间的View可以显示复杂又不同的界面效果。这里为了学习上的简洁,我每一个界面都只是实现了一个TextView效果而已,但这足以将利用ViewPager实现Tab的原理将清楚了。

我们很容易想到,上面的布局可以由线程布局来完成,上、中、下分别是三个线性布局,而下面的一个布局里面装了四个按钮而已。因此编写布局并不难,下面我们就开始书写吧。

二、准备相应的资源

我们只需要准备一些图片即可,即每一个按钮都有两种状态,暗色和亮色。简单利用PS就可以处理了。

三、开始写实际的代码

(1)首先我们把上面和下面的布局构建完成。

上面的布局就是 一个线性布局,中间放了一个TextView而已。我们起名为top.xml,代码很简单,如下:

  1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  2. xmlns:tools="http://schemas.android.com/tools"
  3. android:layout_width="match_parent"
  4. android:layout_height="65dp"
  5. android:background="#fffccc"
  6. android:gravity="center">
  7.  
  8. <TextView
  9. android:layout_width="wrap_content"
  10. android:layout_height="wrap_content"
  11. android:text="Tab试验"
  12. android:textSize="25dp"/>
  13.  
  14. </LinearLayout>

下面的布局采用一个总的线性布局安水平方向摆放四个布局,每一个布局里再放置相应的图片和文字。我们起名为bottum.xml。代码如下:

  1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  2. xmlns:tools="http://schemas.android.com/tools"
  3. android:layout_width="match_parent"
  4. android:layout_height="wrap_content"
  5. android:background="#ccffff"
  6. >
  7.  
  8. <LinearLayout
  9. android:id="@+id/lay_hudie"
  10. android:layout_width="0dp"
  11. android:layout_height="match_parent"
  12. android:layout_weight="1"
  13. android:orientation="vertical"
  14. android:gravity="center">
  15.  
  16. <ImageButton
  17. android:id="@+id/ibtn_hudie"
  18. android:layout_width="wrap_content"
  19. android:layout_height="wrap_content"
  20. android:clickable="false"
  21. android:src="@drawable/hudie"/>
  22. <TextView
  23. android:layout_width="wrap_content"
  24. android:layout_height="wrap_content"
  25. android:text="蝴蝶"/>
  26. "
  27. </LinearLayout>
  28.  
  29. <LinearLayout
  30. android:id="@+id/lay_set"
  31. android:layout_width="0dp"
  32. android:layout_height="match_parent"
  33. android:layout_weight="1"
  34. android:orientation="vertical"
  35. android:gravity="center">
  36.  
  37. <ImageButton
  38. android:id="@+id/ibtn_set"
  39. android:clickable="false"
  40. android:layout_width="wrap_content"
  41. android:layout_height="wrap_content"
  42. android:src="@drawable/set"/>
  43. <TextView
  44. android:layout_width="wrap_content"
  45. android:layout_height="wrap_content"
  46. android:text="设置"/>
  47.  
  48. </LinearLayout>
  49. <LinearLayout
  50. android:id="@+id/lay_user"
  51. android:layout_width="0dp"
  52. android:layout_height="match_parent"
  53. android:layout_weight="1"
  54. android:orientation="vertical"
  55. android:gravity="center">
  56.  
  57. <ImageButton
  58. android:id="@+id/ibtn_user"
  59. android:clickable="false"
  60. android:layout_width="wrap_content"
  61. android:layout_height="wrap_content"
  62. android:src="@drawable/user"/>
  63. <TextView
  64. android:layout_width="wrap_content"
  65. android:layout_height="wrap_content"
  66. android:text="用户"/>
  67.  
  68. </LinearLayout>
  69. <LinearLayout
  70. android:id="@+id/lay_yang"
  71. android:layout_width="0dp"
  72. android:layout_height="match_parent"
  73. android:layout_weight="1"
  74. android:orientation="vertical"
  75. android:gravity="center">
  76.  
  77. <ImageButton
  78. android:id="@+id/ibtn_yang"
  79. android:clickable="false"
  80. android:layout_width="wrap_content"
  81. android:layout_height="wrap_content"
  82. android:src="@drawable/yang"/>
  83. <TextView
  84. android:layout_width="wrap_content"
  85. android:layout_height="wrap_content"
  86. android:text="羊羊"/>
  87.  
  88. </LinearLayout>
  89.  
  90. </LinearLayout>

注意:ImageButton里的点击事件要设定为false。这是因为在后面我们要对它的父view,即相应的LinearLayout设置点击事件,为了保证点击事件一定能被LinearLayout捕捉到,所以要将ImageButton的点击事件设定为false。否则,如果你点击ImageButton那一部分的屏幕区域,因为它是 放在LinearLayout里面,所以点击事件先被LinearLayout捕捉。但是LinearLayout发现他里面有一个按钮也是可以处理点击事件的,就会把点击事件传递给它处理(这是android里的规定)。但是我们却没有给ImageButton设定点击事件,因为就会造成点击事件不响应。所以为了让点击事件不向下传递,我们就将按钮的点击事件设为fasle,即让它不能处理点击事件。而TextView是本身就不能响应点击事件的,因为我们不用对它设定。

(2)搭建主界面,其中就包括ViewPager

现在我们将主界面的头和尾(即上面写的),以及中间的ViewPager搭建起来。取名为activity_main.xml代码也很简单,如下:

  1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  2. xmlns:tools="http://schemas.android.com/tools"
  3. android:layout_width="match_parent"
  4. android:layout_height="match_parent"
  5. android:orientation="vertical"
  6. >
  7.  
  8. <include layout="@layout/top"/>
  9.  
  10. <android.support.v4.view.ViewPager
  11. android:id="@+id/vp"
  12. android:layout_width="match_parent"
  13. android:layout_height="0dp"
  14. android:layout_weight="1" >
  15. </android.support.v4.view.ViewPager>
  16.  
  17. <include layout="@layout/bottum"/>"
  18. </LinearLayout>

注意:在这里我们应当记住,include语句是怎样引入布局的。还有ViewPager是怎样引入的。

(3)编写所有的Tab界面

从效果图上,我们可以看到Tab界面有4个(即中间黑色每滑动一次就出现不同的TextView)。很简单,我们编写四个就可以了,分别命名为Tab01.xml,Tab02.xml,Tab03.xml,Tab04.xml。代码如下:

  1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  2. xmlns:tools="http://schemas.android.com/tools"
  3. android:layout_width="match_parent"
  4. android:layout_height="match_parent"
  5. android:gravity="center">
  6.  
  7. <TextView
  8. android:layout_width="wrap_content"
  9. android:layout_height="wrap_content"
  10. android:text="这是一只蝴蝶"
  11. android:textSize="25dp"/>
  12.  
  13. </LinearLayout>

其他的一样,就是把中间的TextView显示的字改了一下而已。我就不重复了。

(4)写入活动中展示出来。

这一步还是比较复杂的。具体包括,要为按钮设定点击事件,要为ViewPager写适配器,并且要为它编写Item改变时的事件。具体看代码:

  1. import java.util.ArrayList;
  2. import java.util.List;
  3. import java.util.zip.Inflater;
  4. import android.os.Bundle;
  5. import android.app.Activity;
  6. import android.support.v4.view.PagerAdapter;
  7. import android.support.v4.view.ViewPager;
  8. import android.support.v4.view.ViewPager.OnPageChangeListener;
  9. import android.view.LayoutInflater;
  10. import android.view.Menu;
  11. import android.view.View;
  12. import android.view.View.OnClickListener;
  13. import android.view.ViewGroup;
  14. import android.widget.ImageButton;
  15. import android.widget.LinearLayout;
  16.  
  17. public class MainActivity extends Activity implements OnClickListener{
  18.  
  19. private ViewPager vp;
  20.  
  21. private PagerAdapter mAdapter;//适配器
  22.  
  23. private List<View> mViews = new ArrayList<View>();//数据集
  24.  
  25. private LinearLayout mlay1;
  26. private LinearLayout mlay2;
  27. private LinearLayout mlay3;
  28. private LinearLayout mlay4;
  29.  
  30. private ImageButton img1;
  31. private ImageButton img2;
  32. private ImageButton img3;
  33. private ImageButton img4;
  34.  
  35. protected void onCreate(Bundle savedInstanceState) {
  36. super.onCreate(savedInstanceState);
  37. setContentView(R.layout.activity_main);
  38.  
  39. initView();
  40.  
  41. initEvent();//用来 初始化点击事件
  42.  
  43. }
  44.  
  45. //初始化点击事件
  46. private void initEvent() {
  47.  
  48. mlay1.setOnClickListener(this);
  49. mlay2.setOnClickListener(this);
  50. mlay3.setOnClickListener(this);
  51. mlay4.setOnClickListener(this);
  52.  
  53. //设置滑动ViewPager时的事件
  54.  
  55. vp.setOnPageChangeListener(new OnPageChangeListener() {
  56.  
  57. //主要在这个方法里操作,当选中相应的view时一系列的响应事件
  58. public void onPageSelected(int arg0) {
  59.  
  60. resetImg();
  61. int item = vp.getCurrentItem();
  62. switch(item){
  63.  
  64. case 0:
  65. img1.setImageResource(R.drawable.hudie2);
  66. break;
  67. case 1:
  68. img2.setImageResource(R.drawable.set2);
  69. break;
  70. case 2:
  71. img3.setImageResource(R.drawable.user2);
  72. break;
  73. case 3:
  74. img4.setImageResource(R.drawable.yang2);
  75. break;
  76. }
  77.  
  78. }
  79.  
  80. public void onPageScrolled(int arg0, float arg1, int arg2) {
  81. // TODO Auto-generated method stub
  82.  
  83. }
  84.  
  85. public void onPageScrollStateChanged(int arg0) {
  86. // TODO Auto-generated method stub
  87.  
  88. }
  89. });
  90. }
  91.  
  92. //该方法初始化各个view
  93. private void initView() {
  94.  
  95. vp = (ViewPager) findViewById(R.id.vp);
  96.  
  97. //获取底部的各个线性布局
  98. mlay1 = (LinearLayout) findViewById(R.id.lay_hudie);
  99. mlay2 = (LinearLayout) findViewById(R.id.lay_set);
  100. mlay3 = (LinearLayout) findViewById(R.id.lay_user);
  101. mlay4 = (LinearLayout) findViewById(R.id.lay_yang);
  102.  
  103. //获取各个imageView
  104. img1 = (ImageButton) findViewById(R.id.ibtn_hudie);
  105. img2 = (ImageButton) findViewById(R.id.ibtn_set);
  106. img3 = (ImageButton) findViewById(R.id.ibtn_user);
  107. img4 = (ImageButton) findViewById(R.id.ibtn_yang);
  108.  
  109. //下面将view加入到数据集中
  110. View v1 = LayoutInflater.from(this).inflate(R.layout.tab01, null);
  111. View v2 = LayoutInflater.from(this).inflate(R.layout.tab02, null);
  112. View v3 = LayoutInflater.from(this).inflate(R.layout.tab03, null);
  113. View v4 = LayoutInflater.from(this).inflate(R.layout.tab04, null);
  114.  
  115. mViews.add(v1);
  116. mViews.add(v2);
  117. mViews.add(v3);
  118. mViews.add(v4);
  119.  
  120. //然后再根据数据集配置适配器
  121.  
  122. mAdapter = new PagerAdapter() {
  123.  
  124. //销毁item
  125. public void destroyItem(ViewGroup container, int position,
  126. Object object) {
  127.  
  128. container.removeView(mViews.get(position));
  129. }
  130.  
  131. //初始化item
  132. public Object instantiateItem(ViewGroup container, int position) {
  133.  
  134. View view = mViews.get(position);
  135. container.addView(view);
  136. return view;
  137. }
  138.  
  139. //TODO
  140. //这个方法是什么意思,有待进一步查解
  141. public boolean isViewFromObject(View arg0, Object arg1) {
  142.  
  143. return arg0 == arg1;
  144. }
  145.  
  146. //获得适配的总数目
  147. public int getCount() {
  148.  
  149. return mViews.size();
  150. }
  151. };
  152.  
  153. //为ViewPager设置适配器
  154.  
  155. vp.setAdapter(mAdapter);
  156.  
  157. }
  158.  
  159. //点击事件,会把执行点击的控件传进来,即view
  160. public void onClick(View v) {
  161. resetImg();
  162. switch(v.getId()){
  163.  
  164. case R.id.lay_hudie:
  165. vp.setCurrentItem(0);//设置ViewPager当前的view
  166. img1.setImageResource(R.drawable.hudie2);
  167. break;
  168. case R.id.lay_set:
  169. vp.setCurrentItem(1);//设置ViewPager当前的view
  170. img2.setImageResource(R.drawable.set2);
  171. break;
  172. case R.id.lay_user:
  173. vp.setCurrentItem(2);//设置ViewPager当前的view
  174. img3.setImageResource(R.drawable.user2);
  175. break;
  176. case R.id.lay_yang:
  177. vp.setCurrentItem(3);//设置ViewPager当前的view
  178. img4.setImageResource(R.drawable.yang2);
  179. break;
  180.  
  181. }
  182. }
  183.  
  184. //该方法用来将图片还原到初始状态
  185. private void resetImg(){
  186. img1.setImageResource(R.drawable.hudie);
  187. img2.setImageResource(R.drawable.set);
  188. img3.setImageResource(R.drawable.user);
  189. img4.setImageResource(R.drawable.yang);
  190. }
  191. }

好了,所有的工作完成了,我们可以运行程序看看效果了。

四、总结

来看看编写代码的过程中,有那些重要的android知识。

(1)在一个布局中引入另外一个布局,可采用如下语句:

  1. <include layout="@layout/top"/>

(2)在布局中书写ViewPager的代码,关键是要记住它的包名:

  1. <android.support.v4.view.ViewPager
  2. android:id="@+id/vp"
  3. android:layout_width="match_parent"
  4. android:layout_height="0dp"
  5. android:layout_weight="1" >
  6. </android.support.v4.view.ViewPager>

(3)ViewPager的适配器,除了书写它默认的两个方法外,还要重写如下两个方法:

  1. public void destroyItem(ViewGroup container, int position,
  2. Object object)
  3. public Object instantiateItem(ViewGroup container, int position)

(4)当ViewPager状态发生改变时,我们想做出一系列响应,应该设置监听接口,并主要在onPageSelected进行操作。例如:

  1. vp.setOnPageChangeListener(new OnPageChangeListener() {
  2.  
  3. //主要在这个方法里操作,当选中相应的view时一系列的响应事件
  4. public void onPageSelected(int arg0) {
  5. int item = vp.getCurrentItem();
  6. switch(item){
  7. case 0:
  8. img1.setImageResource(R.drawable.hudie2);
  9. break;
  10. case 1:
  11. img2.setImageResource(R.drawable.set2);
  12. break;
  13. case 2:
  14. img3.setImageResource(R.drawable.user2);
  15. break;
  16. case 3:
  17. img4.setImageResource(R.drawable.yang2);
  18. break;
  19.  
  20. }
  21. public void onPageScrolled(int arg0, float arg1, int arg2) {
  22. }
  23. public void onPageScrollStateChanged(int arg0) {
  24.  
  25. }
  26. });
  27. }

使用ViewPager实现Tab的更多相关文章

  1. 无需SherlockActionbar的SlidingMenu使用详解(二)——向Fragment中添加ViewPager和Tab

    之前我们对大体框架有了一定的认识,现在我们来做Fragment界面,其实这里面和这个框架的关系就不大了,但因为有些同学对于在SlidingMenu中切换fragment还是有问题,所以我就在本篇进行详 ...

  2. Android开源框架ViewPageIndicator和ViewPager实现Tab导航

    前言: 关于使用ViewPageIndicator和ViewPager实现Tab导航,在开发社区里已经有一堆的博客对其进行了介绍,假设我还在这里写怎样去实现.那简直就是老生常谈,毫无新奇感,并且.我也 ...

  3. ViewPager与Tab结合使用

    我们有时候需要 标题页卡与ViewPager结合使用,其实原理也很简单. 不过工程中要引入android-support-design.jar 首先是布局文件 <android.support. ...

  4. FragmentPagerAdapter+ViewPager实现Tab切换效果

    1.Activity  加载布局文件,获取Viewpager控件   给ViewPager填充适配器. import android.app.ActionBar; import android.app ...

  5. 66、多种多样的App主界面Tab(1)------ ViewPager实现Tab

    <?xml version="1.0" encoding="utf-8"?> <!-- bottom.xml --> <Linea ...

  6. RadioGroup和ViewPager实现Tab

    Activity的布局文件 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" ...

  7. Android:Fragment+ViewPager实现Tab滑动

    public class FragAdapter extends FragmentPagerAdapter { private List<Fragment> fragments ; pub ...

  8. 69、ViewPagerIndicator+ViewPager实现Tab

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools=&q ...

  9. 68、 FragmentPagerAdapter+ViewPager实现Tab

    <LinearLayout *** <android.support.v4.view.ViewPager android:id="@+id/id_viewpager" ...

随机推荐

  1. jenkins启动脚本

    [root@localhost system]# cat /etc/init.d/jenkins #!/bin/sh # # SUSE system statup script for Jenkins ...

  2. jquery 使用整理机制

    短路表达式 与 多重短路表达式 短路表达式这个应该人所皆知了.在 jQuery 中,大量的使用了短路表达式与多重短路表达式. 短路表达式:作为"&&"和" ...

  3. IE9 和IE10 兼容性判断及效果

    仅IE9可识别 .d1{ width:100px; height:100px; background:blue; } IE9及一下使用<!--[if IE 8]><![endif]- ...

  4. 微信小程序开发框架整理

    目前除了原生的微信小程序开发外,各大厂商陆续造了自己的开发框架,现整理如下: WePY 腾讯官方开源的小程序组件化开发框架,目前有15K+Star ,一直在更新着,社区活跃,掉坑能快速的找到方法爬出来 ...

  5. PHP+MySql实现图书管理系统

    这个图书管理系统是我学完PHP时写的一个练手项目,功能参考了自己学校的图书管理系统.为了锻炼自己的动手能力以及加深对代码的理解,前端和后端均由自己完成,前端使用了一些基本的框架(毕竟我主攻后端开发方向 ...

  6. C10K问题摘要

    本文的内容是下面几篇文章阅读后的内容摘要: http://www.kegel.com/c10k.html (英文版) http://www.oschina.net/translate/c10k (中文 ...

  7. untiy3d小工具——修改scene与prefab中的sprite

    坑1:因为替换图片要获取所有包含image的组件,开始我使用的是gameobject.getComponents<Image>()和FindObjectsOfType<Image&g ...

  8. unity3d之如何控制人物移动、旋转和动画播放

    代码源自噩梦射手,记录一下方便后续使用,顺便将老师的解释给备注上去_(:з」∠)_ using UnityEngine; using UnitySampleAssets.CrossPlatformIn ...

  9. JS里的居民们5-数组(栈)

    编码1(栈顶在最右) 练习如何使用数组来实现栈,综合考虑使用数组的 push,pop,shift,unshift操作 基于代码,实现如按钮中描述的功能: 实现如阅读材料中,队列的相关进栈.退栈.获取栈 ...

  10. jquery not() 方法

    1.not(expression) 根据表达式参数的值,从包装集里删除元素 example : $('img[alt]').not('[alt*=joy]') 返回包含属性alt的img元素,但img ...