iewPager这个控件已经不算是陌生的了,各种玩Android的小伙伴们都有发表相应的文章来讲它。我看过一些文章,感觉其他网站博客贴的代码很不好看,文章排版也不好。小巫还是喜欢自己写写,弄些好看的效果图,把代码贴好一点,别人参考起来也会舒服很多。我之前也有在其他网站发表过文章,比如51CTO、虽然有时候也会麻烦一点,但相对而言,发表博客一定是个好去处。



先上几张效果图:

ViewPager扩展Tab标签指示_d3

ViewPager扩展Tab标签指示_ide_02






以上就是我实现Demo的效果啦


布局代码:


1. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
2. android:layout_width="match_parent"
3. android:layout_height="match_parent" >
4.   
5. <LinearLayout
6. android:id="@+id/ll_viewpager"
7. android:layout_width="match_parent"
8. android:layout_height="wrap_content"
9. android:orientation="horizontal" >
10.   
11. <TextView
12. android:id="@+id/tv_guid1"
13. android:layout_width="wrap_content"
14. android:layout_height="wrap_content"
15. android:layout_weight="1.0"
16. android:gravity="center"
17. android:text="特性1"
18. android:textSize="18sp"/>
19.   
20. <TextView
21. android:id="@+id/tv_guid2"
22. android:layout_width="wrap_content"
23. android:layout_height="wrap_content"
24. android:layout_weight="1.0"
25. android:gravity="center"
26. android:text="特性2"
27. android:textSize="18sp"/>
28.   
29. <TextView
30. android:id="@+id/tv_guid3"
31. android:layout_width="wrap_content"
32. android:layout_height="wrap_content"
33. android:layout_weight="1.0"
34. android:gravity="center"
35. android:text="特性3 "
36. android:textSize="18sp"/>
37.   
38. <TextView
39. android:id="@+id/tv_guid4"
40. android:layout_width="wrap_content"
41. android:layout_height="wrap_content"
42. android:layout_weight="1.0"
43. android:gravity="center"
44. android:text="特性4"
45. android:textSize="18sp"/>
46. </LinearLayout>
47.   
48. <ImageView
49. android:id="@+id/cursor"
50. android:layout_width="wrap_content"
51. android:layout_height="wrap_content"
52. android:layout_below="@+id/ll_viewpager"
53. android:scaleType="matrix"
54. android:src="@drawable/cursor" />
55.   
56. <android.support.v4.view.ViewPager
57. android:id="@+id/viewpager"
58. android:layout_width="wrap_content"
59. android:layout_height="wrap_content"
60. android:layout_below="@+id/cursor"
61. android:flipInterval="30"
62. android:persistentDrawingCache="animation" />
63.   
64. </RelativeLayout>



每一个标签页的布局




    1. <?xml version="1.0" encoding="UTF-8"?>
    2. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    3. android:layout_width="fill_parent"
    4. android:layout_height="fill_parent"
    5. android:background="@drawable/guide_1" >
    6. </RelativeLayout>



    其他都一样,不多贴


    布局搞定之后,定义一个适配器如下:


    1. package
    2.   
    3. import
    4.   
    5. import
    6. import
    7. import
    8.   
    9. /**
    10.  * ViewPager适配器
    11.  * 
    12.  * @author wwj
    13.  * 
    14.  */
    15. public class ViewPagerAdapter extends
    16. // 界面列表
    17. private
    18.   
    19. public
    20. this.views = views;  
    21.     }  
    22.   
    23. @Override
    24. public void destroyItem(ViewGroup container, int
    25.         container.removeView(views.get(position));  
    26.     }  
    27.   
    28. @Override
    29. public int
    30. if (views != null) {  
    31. return
    32.         }  
    33. return 0;  
    34.     }  
    35.   
    36. @Override
    37. public Object instantiateItem(ViewGroup container, int
    38. // 把被点击的图片放入缓存中
    39. return views.get(position); // 返回被点击图片对象
    40.     }  
    41.   
    42. @Override
    43. public boolean
    44. return
    45.     }  
    46. }


    适配器搞定之后,直接去Activity



    1. package
    2.   
    3. import
    4. import
    5.   
    6. import
    7. import
    8. import
    9. import
    10. import
    11. import
    12. import
    13. import
    14. import
    15. import
    16. import
    17. import
    18. import
    19. import
    20. import
    21.   
    22. public class MainActivity extends
    23.     ViewPager viewPager;  
    24.     ViewPagerAdapter pagerAdapter;  
    25. // 页面
    26. // Tab页面列表
    27.   
    28. // 指示图片
    29. // 页卡头标
    30. int offset = 0;         // 偏移量
    31. int currIndex = 0;      // 当前页卡编号
    32. int bmpW;               // 图片宽度
    33.   
    34. @Override
    35. protected void
    36. super.onCreate(savedInstanceState);  
    37.         setContentView(R.layout.activity_main);  
    38.   
    39.         initImageView();  
    40.         initTextView();  
    41.   
    42.         view1 = (View) findViewById(R.layout.viewpager1);  
    43.         view2 = (View) findViewById(R.layout.viewpager2);  
    44.         view3 = (View) findViewById(R.layout.viewpager3);  
    45.         view4 = (View) findViewById(R.layout.viewpager4);  
    46.   
    47. this);  
    48. null);  
    49. null);  
    50. null);  
    51. null);  
    52.   
    53. new
    54.         views.add(view1);  
    55.         views.add(view2);  
    56.         views.add(view3);  
    57.         views.add(view4);  
    58.   
    59. new
    60.         viewPager = (ViewPager) findViewById(R.id.viewpager);  
    61.         viewPager.setAdapter(pagerAdapter);  
    62.   
    63. 0);  
    64. new
    65.   
    66.     }  
    67. /**
    68.      * 初始化动画图片
    69.      * 
    70.      */
    71. private void
    72.         img_cursor = (ImageView) findViewById(R.id.cursor);  
    73.         bmpW = BitmapFactory.decodeResource(getResources(), R.drawable.cursor)  
    74.                 .getWidth();  
    75.   
    76. new
    77. this.getWindowManager().getDefaultDisplay().getMetrics(dm);  
    78. int screenW = dm.widthPixels; // 获取手机屏幕宽度分辨率
    79.   
    80. 4 - bmpW) / 2; // 获取图片偏移量
    81.   
    82. // imageview设置平移,使下划线平移到初始位置(平移一个offset)
    83. new
    84. 0);  
    85.         img_cursor.setImageMatrix(matrix);  
    86.   
    87.     }  
    88.   
    89. /**
    90.      * 
    91.      * 初始化TextView控件,和注册监听器
    92.      */
    93. private void
    94.         tv_guid1 = (TextView) findViewById(R.id.tv_guid1);  
    95.         tv_guid2 = (TextView) findViewById(R.id.tv_guid2);  
    96.         tv_guid3 = (TextView) findViewById(R.id.tv_guid3);  
    97.         tv_guid4 = (TextView) findViewById(R.id.tv_guid4);  
    98.   
    99.         tv_guid1.setOnClickListener(listener);  
    100.         tv_guid2.setOnClickListener(listener);  
    101.         tv_guid3.setOnClickListener(listener);  
    102.         tv_guid4.setOnClickListener(listener);  
    103.   
    104.     }  
    105.   
    106. new
    107.   
    108. @Override
    109. public void
    110. switch
    111. case
    112. 0);  
    113. break;  
    114. case
    115. 1);  
    116. break;  
    117. case
    118. 2);  
    119. break;  
    120. case
    121. 3);  
    122. break;  
    123.   
    124. default:  
    125. break;  
    126.             }  
    127.         }  
    128.     };  
    129.   
    130. // 当页面滑动时,开始动画并跳出Toast
    131. public class MyOnPageChangeListener implements
    132.   
    133. private int one = offset * 2 + bmpW; // 页面1到页面2的偏移量
    134.   
    135. @Override
    136. public void onPageScrollStateChanged(int
    137.   
    138.         }  
    139.   
    140. @Override
    141. public void onPageScrolled(int arg0, float arg1, int
    142.   
    143.         }  
    144.   
    145. // 即将要被显示的页卡的index
    146. @Override
    147. public void onPageSelected(int
    148. // 初始化移动的动画(从当前位置,x平移到即将要到的位置)
    149. new
    150. 0, 0);  
    151.   
    152.             currIndex = arg0;  
    153. true); // 动画终止时停留在最后一帧,不然会回到没有执行前的状态
    154. 200); // 动画持续时间,0.2秒
    155. // 是用imageview来显示动画
    156. int i = currIndex + 1;  
    157. this, "您选择了第" + i + "个页卡",  
    158.                     Toast.LENGTH_SHORT).show();  
    159.         }  
    160.   
    161.     }  
    162.   
    163. }



    代码并不复杂,这里主要要考虑的是每个标签下面的下划线怎么移动,移动的偏移量怎么计算,怎么设置动画,设置什么动画。这里当然要用平移动画