Android多屏滑动:ViewPager基础使用及PagerTabStrip先天缺陷(附源码)

来源:互联网 发布:sai mac版安装教程 编辑:程序博客网 时间:2024/05/03 01:59

最近要用ViewPager,看了几个人的帖子都说的不太明白,干脆自己写个demo总结下。例子很简单,Activity里有三个界面可以滑动,每一个界面都有一个button并设置好了监听。PagerTabStrip也就是滑动时的那个标识线,在View的下方。下为代码:

activity_main.xml(主布局)

[html] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. <span style="font-family:Comic Sans MS;font-size:18px;"><RelativeLayout 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:paddingBottom="@dimen/activity_vertical_margin"  
  6.     android:paddingLeft="@dimen/activity_horizontal_margin"  
  7.     android:paddingRight="@dimen/activity_horizontal_margin"  
  8.     android:paddingTop="@dimen/activity_vertical_margin"  
  9.     tools:context=".MainActivity" >  
  10.   
  11.     <TextView  
  12.         android:layout_width="wrap_content"  
  13.         android:layout_height="wrap_content"  
  14.         android:text="@string/hello_world" />  
  15.   
  16.     <android.support.v4.view.ViewPager  
  17.         android:id="@+id/viewpager"  
  18.         android:layout_width="match_parent"  
  19.         android:layout_height="wrap_content"  
  20.         android:layout_centerInParent="true" >  
  21.   
  22.         <android.support.v4.view.PagerTabStrip  
  23.             android:id="@+id/pagertab"  
  24.             android:layout_width="match_parent"  
  25.             android:layout_height="wrap_content"   
  26.             android:layout_gravity="bottom"/>  
  27.     </android.support.v4.view.ViewPager>  
  28.   
  29. </RelativeLayout></span>  

下面是三个view布局,都差不多:

first_pager_layout.xml

[html] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. <span style="font-family:Comic Sans MS;font-size:18px;"><?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="match_parent"  
  5.     android:orientation="vertical"   
  6.     android:background="@android:color/holo_blue_bright">  
  7.       
  8. <Button   
  9.     android:id="@+id/btn_in_first"  
  10.     android:layout_width="wrap_content"  
  11.     android:layout_height="wrap_content"  
  12.     android:text="请点击"  
  13.     android:layout_gravity="center"/>  
  14. </LinearLayout>  
  15. </span>  

second_pager_layout.xml

[html] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. <span style="font-family:Comic Sans MS;font-size:18px;"><?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="match_parent"  
  5.     android:orientation="vertical"   
  6.     android:background="@android:color/holo_green_light">  
  7.  <Button   
  8.     android:id="@+id/btn_in_second"  
  9.     android:layout_width="wrap_content"  
  10.     android:layout_height="wrap_content"  
  11.     android:text="请点击"  
  12.     android:layout_gravity="center"/>     
  13.   
  14. </LinearLayout>  
  15. </span>  

third_pager_layout.xml

[html] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. <span style="font-family:Comic Sans MS;font-size:18px;"><?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="match_parent"  
  5.     android:orientation="vertical"   
  6.     android:background="@android:color/holo_red_light">  
  7.       
  8. <Button   
  9.     android:id="@+id/btn_in_third"  
  10.     android:layout_width="wrap_content"  
  11.     android:layout_height="wrap_content"  
  12.     android:text="请点击"  
  13.     android:layout_gravity="center"/>  
  14. </LinearLayout>  
  15. </span>  

MainActivity.java(这是主程序里,在里面实例化ViewPager并设置它的适配器)

[java] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. <span style="font-family:Comic Sans MS;font-size:18px;">package org.yanzi.testviewpager1;  
  2.   
  3. import java.util.ArrayList;  
  4. import java.util.List;  
  5.   
  6. import android.app.Activity;  
  7. import android.content.Context;  
  8. import android.graphics.Color;  
  9. import android.os.Bundle;  
  10. import android.support.v4.view.PagerTabStrip;  
  11. import android.support.v4.view.PagerTitleStrip;  
  12. import android.support.v4.view.ViewPager;  
  13. import android.support.v4.view.ViewPager.OnPageChangeListener;  
  14. import android.view.LayoutInflater;  
  15. import android.view.Menu;  
  16. import android.view.View;  
  17. import android.widget.Button;  
  18. import android.widget.Toast;  
  19.   
  20. public class MainActivity extends Activity {  
  21.   
  22.     List<View> mViews = new ArrayList<View>();  
  23.     String[] mTitles = {"页面1""页面2""页面3"};  
  24.     MyPagerAdapter pagerAdapter;  
  25.     PagerTabStrip pagerTabStrip;  
  26.     PagerTitleStrip pagerTitleStrip;  
  27.     ViewPager viewPager;  
  28.     View view1, view2, view3;  
  29.     Button btn1, btn2, btn3;  
  30.     BtnListener btnListener;  
  31.   
  32.     @Override  
  33.     protected void onCreate(Bundle savedInstanceState) {  
  34.         super.onCreate(savedInstanceState);  
  35.         setContentView(R.layout.activity_main);  
  36.         initUI();  
  37.         LayoutInflater flater = (LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);  
  38.   
  39.         view1 = flater.inflate(R.layout.first_pager_layout, null);  
  40.         view2 = flater.inflate(R.layout.second_pager_layout, null);  
  41.         view3 = flater.inflate(R.layout.third_pager_layout, null);  
  42.         mViews.add(view1);  
  43.         mViews.add(view2);  
  44.         mViews.add(view3);  
  45.         pagerAdapter = new MyPagerAdapter(mViews, mTitles);  
  46.         viewPager.setAdapter(pagerAdapter);  
  47.         viewPager.setCurrentItem(1);  
  48.   
  49.         //设置pagerTabStrip  
  50.         pagerTabStrip.setTabIndicatorColor(Color.RED);  
  51.         pagerTabStrip.setTextColor(Color.RED);  
  52.         pagerTabStrip.setClickable(false);  
  53.         pagerTabStrip.setTextSpacing(40);  
  54.         pagerTabStrip.setBackgroundColor(Color.GRAY);  
  55.         pagerTabStrip.setDrawFullUnderline(true);  
  56.         /*      pagerTitleStrip.setTextColor(Color.RED); 
  57.         pagerTitleStrip.setTextSpacing(40);*/  
  58.   
  59.         //ViewPager滑动监听  
  60.         viewPager.setOnPageChangeListener(new OnPageChangeListener() {  
  61.   
  62.             @Override  
  63.             public void onPageSelected(int arg0) {  
  64.                 // TODO Auto-generated method stub  
  65.                 showToast("切换至:" + mTitles[arg0]);  
  66.             }  
  67.   
  68.             @Override  
  69.             public void onPageScrolled(int arg0, float arg1, int arg2) {  
  70.                 // TODO Auto-generated method stub  
  71.   
  72.             }  
  73.   
  74.             @Override  
  75.             public void onPageScrollStateChanged(int arg0) {  
  76.                 // TODO Auto-generated method stub  
  77.   
  78.             }  
  79.         });  
  80.           
  81.         initBtns();  
  82.   
  83.     }  
  84.   
  85.     @Override  
  86.     public boolean onCreateOptionsMenu(Menu menu) {  
  87.         // Inflate the menu; this adds items to the action bar if it is present.  
  88.         getMenuInflater().inflate(R.menu.main, menu);  
  89.         return true;  
  90.     }  
  91.     private void initUI(){  
  92.         viewPager = (ViewPager)findViewById(R.id.viewpager);  
  93.         pagerTabStrip = (PagerTabStrip)findViewById(R.id.pagertab);  
  94.         //      pagerTitleStrip = (PagerTitleStrip)findViewById(R.id.pagertab);  
  95.     }  
  96.     private void initBtns(){  
  97.         if(view1 != null){  
  98.             btn1 = (Button)view1.findViewById(R.id.btn_in_first);  
  99.   
  100.         }  
  101.         if(view2 != null){  
  102.             btn2 = (Button)view2.findViewById(R.id.btn_in_second);  
  103.         }  
  104.         if(view3 != null){  
  105.             btn3 = (Button)view3.findViewById(R.id.btn_in_third);  
  106.         }  
  107.         btnListener = new BtnListener();  
  108.           
  109.         btn1.setOnClickListener(btnListener);  
  110.         btn2.setOnClickListener(btnListener);  
  111.         btn3.setOnClickListener(btnListener);  
  112.     }  
  113.     class BtnListener implements View.OnClickListener{  
  114.   
  115.         @Override  
  116.         public void onClick(View v) {  
  117.             // TODO Auto-generated method stub  
  118.             switch (v.getId()){  
  119.             case R.id.btn_in_first:  
  120.                 showToast("您点击了第一个界面");  
  121.                 break;  
  122.             case R.id.btn_in_second:  
  123.                 showToast("您点击了第2个界面");  
  124.                 break;  
  125.             case R.id.btn_in_third:  
  126.                 showToast("您点击了第3个界面");  
  127.                 break;  
  128.             default:break;  
  129.             }  
  130.         }  
  131.   
  132.     }  
  133.     private void showToast(String s){  
  134.         Toast.makeText(getApplicationContext(), s, Toast.LENGTH_SHORT).show();  
  135.     }  
  136.   
  137. }  
  138. </span>  

MyPagerAdapter.java(这是ViewPager的适配器,继承PagerAdapter,将其单独写到一个文件里了)

[java] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. <span style="font-family:Comic Sans MS;font-size:18px;">package org.yanzi.testviewpager1;  
  2.   
  3. import java.util.List;  
  4.   
  5. import android.support.v4.view.PagerAdapter;  
  6. import android.view.View;  
  7. import android.view.ViewGroup;  
  8.   
  9. public class MyPagerAdapter extends PagerAdapter {  
  10.     private List<View> mListViews;  
  11.     private String[] mTitles;  
  12.     public MyPagerAdapter(List<View> views, String[] titles){  
  13.         this.mListViews = views;  
  14.         this.mTitles = titles;  
  15.     }  
  16.     @Override  
  17.     public int getCount() {  
  18.         // TODO Auto-generated method stub  
  19.         return mListViews.size();  
  20.     }  
  21.   
  22.     @Override  
  23.     public boolean isViewFromObject(View arg0, Object arg1) {  
  24.         // TODO Auto-generated method stub  
  25.         return (arg0==arg1);  
  26.     }  
  27.     @Override  
  28.     public void destroyItem(ViewGroup container, int position, Object object) {  
  29.         // TODO Auto-generated method stub  
  30.         container.removeView(mListViews.get(position));  
  31.     }  
  32.     @Override  
  33.     public Object instantiateItem(ViewGroup container, int position) {  
  34.         // TODO Auto-generated method stub  
  35.         container.addView(mListViews.get(position), 0);  
  36.         return mListViews.get(position);  
  37.     }  
  38.     @Override  
  39.     public CharSequence getPageTitle(int position) {  
  40.         // TODO Auto-generated method stub  
  41.         return mTitles[position];  
  42.     }  
  43.       
  44.   
  45.   
  46. }  
  47. </span>  

要点:

1、ViewPager说白了就是个控件,在使用时包名要带全是Android.support.v4.view.ViewPager。由于我的ADT-Bundle版本比较高,这个包默认自带了,且默认是随apk打包导出的。如下图:



如果在Android Private Libraries里没这个包,则要自己在属性的Libraries里自己添加。添加后记得在上图所示的Order and Export里将其打勾。

2.理论上说要实现滑屏只要一个ViewPager就可以了,不需要再在里面嵌套如下:

        <android.support.v4.view.PagerTabStrip
            android:id="@+id/pagertab"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" 
            android:layout_gravity="bottom"/>

这个PagerTabStrip就是个横线,如果想用它来标识当前在哪个View的话可以加它,当然最后你会发现这就是个坑爹的玩意。除了PagerTabStrip,还有一个PagerTitleStrip,两者的用法地位都是一样的,均要嵌套在ViewPager里。区别是:

a、PagerTabStrip在效果上包含了PagerTitleStrip,如果只添加PagerTabStrip可以看到只有线,但是它占的布局是有一定高度的。默认是不显示标题的,如果要显示需在适配器里重写:

@Override
public CharSequence getPageTitle(int position) {
// TODO Auto-generated method stub
return mTitles[position];
}

就会显示标题了。关于标题及这个线的颜色,和整个标识View的背景可以再代码里设置,demo里有示例。

b、PagerTitleStrip只显示标题而没有那个线。

c、PagerTabStrip可以点击切换View,而PagerTitleStrip不能点击。更多参见链接

两者相对父亲ViewPager的位置,也就是标识是在View的上面还是下面,通过PagerTabStrip的属性android:layout_gravity="bottom"来设置。

3、就像ListView的一样,ViewPager的关键在于适配器,而要用正常使用需要至少重写以下四个方法:

[java] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. <span style="font-family:Comic Sans MS;font-size:18px;">    @Override  
  2.     public int getCount() {  
  3.         // TODO Auto-generated method stub  
  4.         return mListViews.size();  
  5.     }  
  6.   
  7.     @Override  
  8.     public boolean isViewFromObject(View arg0, Object arg1) {  
  9.         // TODO Auto-generated method stub  
  10.         return (arg0==arg1);  
  11.     }  
  12.     @Override  
  13.     public void destroyItem(ViewGroup container, int position, Object object) {  
  14.         // TODO Auto-generated method stub  
  15.         container.removeView(mListViews.get(position));  
  16.     }  
  17.     @Override  
  18.     public Object instantiateItem(ViewGroup container, int position) {  
  19.         // TODO Auto-generated method stub  
  20.         container.addView(mListViews.get(position), 0);  
  21.         return mListViews.get(position);  
  22.     }</span>  

下面这个方法是用来显示标题的,一般不重写,因为PagerTabStrip是个中看不中用的玩意。

[java] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. <span style="font-family:Comic Sans MS;font-size:18px;">    @Override  
  2.     public CharSequence getPageTitle(int position) {  
  3.         // TODO Auto-generated method stub  
  4.         return mTitles[position];  
  5.     }</span>  

4、在设置适配器后,通过viewPager.setCurrentItem(1);来设置默认的ViewPager显示哪一个View。1标识第二个界面。

5、每个View里都用子控件,通过initBtns()来获得,注意findViewById时一定要前面加上它的父亲.如下:

btn1 = (Button)view1.findViewById(R.id.btn_in_first);更为严谨的做法是只有显示当前View时,这个View里的控件才可以被监听。

6、当ViewPager的View发生变化时,设置监听:

//ViewPager滑动监听
viewPager.setOnPageChangeListener(new OnPageChangeListener() {


@Override
public void onPageSelected(int arg0) {
// TODO Auto-generated method stub
showToast("切换至:" + mTitles[arg0]);
}


@Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
// TODO Auto-generated method stub


}


@Override
public void onPageScrollStateChanged(int arg0) {
// TODO Auto-generated method stub


}
});

7、PagerTabStrip里的很多方法都是没有效果的如pagerTabStrip.setTextSpacing(40); 

pagerTabStrip.setDrawFullUnderline(true);

下面是效果图:




可以看到显示页面3时,下面的PageTabStrip竟然发生移位了,没人会需要这样的体验,真是个坑爹的玩意啊。本来我还不死心想找到不自己写PageTabStrip情况下解决问题,看到链接 彻底放弃了。关于标识还是自己来写吧,后续文章会再给出完整示例。

代码下载:http://download.csdn.net/detail/yanzi1225627/7223287

0 0
原创粉丝点击