ViewPager是Android 3.0以上可以使用的API。
一、ViewPager能干什么?
1、微信5.0中连带滑动用ViewPager可以轻松实现。
2、实现类似于新浪微博的导航引导界面。
3、实现其他导航或菜单。
二、ViewPager的使用
1、添加布局
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <android.support.v4.view.ViewPager android:id="@+id/viewpager" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center"/> </LinearLayout>2、加载要显示的布局文件(View)
LayoutInflater lf = getLayoutInflater().from(this); view1 = lf.inflate(R.layout.layout_0, null); view2 = lf.inflate(R.layout.layout_1, null); view3 = lf.inflate(R.layout.layout_2, null);3、创建View集合
mListViews = new ArrayList<View>(); mListViews.add(view1); mListViews.add(view2); mListViews.add(view3);4、创建PagerAdapter
ViewPager的适配器是PagerAdapter,要实现PagerAdapter至少要实现以下方法:
(1)instantiateItem(ViewGroup, int) //添加
(2)destroyItem(ViewGroup, int, Object) //删除
(3)getCount()
(4)isViewFromObject(View, Object)
private class MyPageAdapter extends PagerAdapter { private List<View> mListViews; public MyPageAdapter(List<View> mListViews) { this.mListViews = mListViews; } /** * 删除页卡 */ @Override public void destroyItem(View container, int position, Object object) { ((ViewPager) container).removeView(mListViews.get(position)); } /** * 实例化页卡 */ @Override public Object instantiateItem(View container, int position) { ((ViewPager)container).addView(mListViews.get(position)); return mListViews.get(position); } /** * 返回页卡的数量 */ @Override public int getCount() { return mListViews.size(); } @Override public boolean isViewFromObject(View arg0, Object arg1) { return arg0 == arg1; //官方提示这样写 } }5、配置适配器
mViewPager.setAdapter(new MyPageAdapter(mListViews));
全部代码如下:
package com.example.viewpagetest; import java.util.ArrayList; import java.util.List; import android.app.Activity; import android.os.Bundle; import android.support.v4.view.PagerAdapter; import android.support.v4.view.ViewPager; import android.view.LayoutInflater; import android.view.View; public class MainActivity extends Activity { private List<View> mListViews; private View view1; private View view2; private View view3; private ViewPager mViewPager; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mViewPager = (ViewPager) findViewById(R.id.viewpager); //加载要显示的选项卡 LayoutInflater lf = getLayoutInflater().from(this); view1 = lf.inflate(R.layout.layout_0, null); view2 = lf.inflate(R.layout.layout_1, null); view3 = lf.inflate(R.layout.layout_2, null); mListViews = new ArrayList<View>(); mListViews.add(view1); mListViews.add(view2); mListViews.add(view3); mViewPager.setAdapter(new MyPageAdapter(mListViews)); } private class MyPageAdapter extends PagerAdapter { private List<View> mListViews; public MyPageAdapter(List<View> mListViews) { this.mListViews = mListViews; } /** * 删除页卡 */ @Override public void destroyItem(View container, int position, Object object) { ((ViewPager) container).removeView(mListViews.get(position)); } /** * 实例化页卡 */ @Override public Object instantiateItem(View container, int position) { ((ViewPager)container).addView(mListViews.get(position)); return mListViews.get(position); } /** * 返回页卡的数量 */ @Override public int getCount() { return mListViews.size(); } @Override public boolean isViewFromObject(View arg0, Object arg1) { return arg0 == arg1; //官方提示这样写 } } }各个页面代码:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:layout_width="match_parent" android:layout_height="match_parent" android:text="1" android:gravity="center" android:textSize="120sp" android:textColor="#33b5e5" /> </LinearLayout>运行效果:
三、实现微信的菜单联动
android.support.v4.view包中的接口和类如下:
从上面图片中我们可以看到PagerTabStrip和PagerTitleStrip
从字面意思上理解,PagerTabStrip是可以点击的导航选项卡,而PagerTitleStrip是不能互动的(点击)的导航选项卡。
下面我们修改布局文件如下:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <android.support.v4.view.ViewPager android:id="@+id/viewpager" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center"> <android.support.v4.view.PagerTabStrip android:id="@+id/pagertab" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="top"/> </android.support.v4.view.ViewPager> </LinearLayout>
layout_gravity可以设置Tab的位置
修改MainActvity
mTitleList = new ArrayList<String>(); mTitleList.add("聊天"); mTitleList.add("发现"); mTitleList.add("通讯录");在PagerAdapter中添加下面代码:
@Override
public CharSequence getPageTitle(int position) {
return mTitleList.get(position);
}
贴出全部代码,如下:
package com.example.viewpagetest; import java.util.ArrayList; import java.util.List; import android.app.Activity; import android.os.Bundle; import android.support.v4.view.PagerAdapter; import android.support.v4.view.ViewPager; import android.view.LayoutInflater; import android.view.View; public class MainActivity extends Activity { private List<String> mTitleList; private List<View> mListViews; private ViewPager mViewPager; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mViewPager = (ViewPager) findViewById(R.id.viewpager); //加载要显示的选项卡 LayoutInflater lf = getLayoutInflater().from(this); View view1 = lf.inflate(R.layout.layout_0, null); View view2 = lf.inflate(R.layout.layout_1, null); View view3 = lf.inflate(R.layout.layout_2, null); mListViews = new ArrayList<View>(); mListViews.add(view1); mListViews.add(view2); mListViews.add(view3); mTitleList = new ArrayList<String>(); mTitleList.add("聊天"); mTitleList.add("发现"); mTitleList.add("通讯录"); mViewPager.setAdapter(new MyPageAdapter(mListViews)); } private class MyPageAdapter extends PagerAdapter { private List<View> mListViews; public MyPageAdapter(List<View> mListViews) { this.mListViews = mListViews; } /** * 删除页卡 */ @Override public void destroyItem(View container, int position, Object object) { ((ViewPager) container).removeView(mListViews.get(position)); } /** * 实例化页卡 */ @Override public Object instantiateItem(View container, int position) { ((ViewPager)container).addView(mListViews.get(position)); return mListViews.get(position); } /** * 返回页卡的数量 */ @Override public int getCount() { return mListViews.size(); } @Override public boolean isViewFromObject(View arg0, Object arg1) { return arg0 == arg1; //官方提示这样写 } /** * 设置Tab */ @Override public CharSequence getPageTitle(int position) { return mTitleList.get(position); } } }运行效果:
上面虽然有了Tab,并能随着页面的切换改变,但是这个并不是我们要达到的效果。下面我们自己做一个静态的Tab底部和一个动画来实现。
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="#eeeeee" android:orientation="vertical" > <LinearLayout android:id="@+id/linearLayout1" android:layout_width="fill_parent" android:layout_height="32.0dip" android:background="#eeeeee" > <TextView android:id="@+id/text1" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="1.0" android:gravity="center" android:text="聊天" android:textColor="#000000" android:textSize="16.0dip" /> <TextView android:id="@+id/text2" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="1.0" android:gravity="center" android:text="发现" android:textColor="#000000" android:textSize="16.0dip" /> <TextView android:id="@+id/text3" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="1.0" android:gravity="center" android:text="通讯录" android:textColor="#000000" android:textSize="16.0dip" /> </LinearLayout> <ImageView android:id="@+id/cursor" android:layout_width="fill_parent" android:layout_height="wrap_content" android:scaleType="matrix" android:src="@drawable/a"/> <ImageView android:layout_width="match_parent" android:layout_height="1px" android:background="#cccccc"/> <android.support.v4.view.ViewPager android:id="@+id/vPager" android:layout_width="wrap_content" android:layout_height="0dp" android:layout_gravity="center" android:layout_weight="1.0" android:flipInterval="30" android:background="#ffffff" android:persistentDrawingCache="animation" /> </LinearLayout>
package com.example.wuye001; import java.util.ArrayList; import java.util.List; import android.app.Activity; import android.graphics.BitmapFactory; import android.graphics.Matrix; import android.os.Bundle; import android.support.v4.view.PagerAdapter; import android.support.v4.view.ViewPager; import android.support.v4.view.ViewPager.OnPageChangeListener; import android.util.DisplayMetrics; import android.view.LayoutInflater; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; import android.view.animation.Animation; import android.view.animation.TranslateAnimation; import android.widget.ImageView; import android.widget.TextView; import android.widget.Toast; public class MainActivity extends Activity { private ViewPager viewPager;//页卡内容 private ImageView imageView;// 动画图片 private TextView textView1,textView2,textView3; private List<View> views;// Tab页面列表 private int offset = 0;// 动画图片偏移量 private int currIndex = 0;// 当前页卡编号 private int bmpW;// 动画图片宽度 private View view1,view2,view3;//各个页卡 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); InitImageView(); InitTextView(); InitViewPager(); } private void InitViewPager() { viewPager=(ViewPager) findViewById(R.id.vPager); views=new ArrayList<View>(); LayoutInflater inflater=getLayoutInflater(); view1=inflater.inflate(R.layout.layout_0, null); view2=inflater.inflate(R.layout.layout_1, null); view3=inflater.inflate(R.layout.layout_2, null); views.add(view1); views.add(view2); views.add(view3); viewPager.setAdapter(new MyViewPagerAdapter(views)); viewPager.setCurrentItem(0); viewPager.setOnPageChangeListener(new MyOnPageChangeListener()); } /** * 初始化头标 */ private void InitTextView() { textView1 = (TextView) findViewById(R.id.text1); textView2 = (TextView) findViewById(R.id.text2); textView3 = (TextView) findViewById(R.id.text3); textView1.setOnClickListener(new MyOnClickListener(0)); textView2.setOnClickListener(new MyOnClickListener(1)); textView3.setOnClickListener(new MyOnClickListener(2)); } /** * 初始化动画,这个就是页卡滑动时,下面的横线也滑动的效果,在这里需要计算一些数据 */ private void InitImageView() { imageView= (ImageView) findViewById(R.id.cursor); bmpW = BitmapFactory.decodeResource(getResources(), R.drawable.a).getWidth();// 获取图片宽度 DisplayMetrics dm = new DisplayMetrics(); getWindowManager().getDefaultDisplay().getMetrics(dm); int screenW = dm.widthPixels;// 获取分辨率宽度 offset = (screenW / 3 - bmpW) / 2;// 计算偏移量 Matrix matrix = new Matrix(); matrix.postTranslate(offset, 0); imageView.setImageMatrix(matrix);// 设置动画初始位置 } /** * * 头标点击监听 3 */ private class MyOnClickListener implements OnClickListener{ private int index=0; public MyOnClickListener(int i){ index=i; } public void onClick(View v) { viewPager.setCurrentItem(index); } } public class MyViewPagerAdapter extends PagerAdapter{ private List<View> mListViews; public MyViewPagerAdapter(List<View> mListViews) { this.mListViews = mListViews; } @Override public void destroyItem(ViewGroup container, int position, Object object) { container.removeView(mListViews.get(position)); } @Override public Object instantiateItem(ViewGroup container, int position) { container.addView(mListViews.get(position), 0); return mListViews.get(position); } @Override public int getCount() { return mListViews.size(); } @Override public boolean isViewFromObject(View arg0, Object arg1) { return arg0==arg1; } } public class MyOnPageChangeListener implements OnPageChangeListener{ int one = offset * 2 + bmpW;// 页卡1 -> 页卡2 偏移量 int two = one * 2;// 页卡1 -> 页卡3 偏移量 public void onPageScrollStateChanged(int arg0) { } public void onPageScrolled(int arg0, float arg1, int arg2) { } public void onPageSelected(int arg0) { /*两种方法,这个是一种,下面还有一种,显然这个比较麻烦 Animation animation = null; switch (arg0) { case 0: if (currIndex == 1) { animation = new TranslateAnimation(one, 0, 0, 0); } else if (currIndex == 2) { animation = new TranslateAnimation(two, 0, 0, 0); } break; case 1: if (currIndex == 0) { animation = new TranslateAnimation(offset, one, 0, 0); } else if (currIndex == 2) { animation = new TranslateAnimation(two, one, 0, 0); } break; case 2: if (currIndex == 0) { animation = new TranslateAnimation(offset, two, 0, 0); } else if (currIndex == 1) { animation = new TranslateAnimation(one, two, 0, 0); } break; } */ Animation animation = new TranslateAnimation(one*currIndex, one*arg0, 0, 0);//显然这个比较简洁,只有一行代码。 currIndex = arg0; animation.setFillAfter(true);// True:图片停在动画结束位置 animation.setDuration(300); imageView.startAnimation(animation); } } }运行效果: