先给viewpager的用法可以主要用在:
①用在App第一次启动的时候作为引导页,引导页可以加入底部指示器,也可以使用最简单的直接来一个viewPager进行引导即可.
②第二种最为常见的就是用作一些首页顶部的广告刷新滚动,加入了底部的指示器,并且加入了循环滚动和对应的点击事件.
第一步,先介绍PagerAdapter:
ViewPager之前先要先去了解下PagerAdapter的相关介绍:
这个帖子写的很好http://blog.csdn.net/gaojinshan/article/details/16865719,内容如下:
官方英语原文地址:http://developer.android.com/reference/android/support/v4/view/PagerAdapter.html
(它是)基类,它提供适配器,该适配器能填充页面内容到ViewPager中。
你可能更喜欢使用它的特殊实现类,比如:FragmentPagerAdapter 或FragmentStatePagerAdapter。
当你实现一个PageAdapter的时候,你至少必须要重载(override)下面几个方法:
· instantiateItem(ViewGroup, int)--实例化条目
· destroyItem(ViewGroup, int, Object)--销毁条目
· getCount()--获取条目数量
· isViewFromObject(View, Object)
PagerAdapter,比AdapterViews所使用的适配器,更常用。
在更新过程中,ViewPager使用回调(callbacks),来指示到哪一步了,而不是提供一套View直接回收的机制。
如果需要的话,PagerAdapter可以实现一种View回收机制,或者使用一个更加复杂的方法,来管理page view,
例如,Fragment的处理方式:每个页面都由它自己的Fragment来展现。
ViewPager都关联一个key对象,而不是直接与Views关联。
这个key用来跟踪并唯一标识指定的页面,它独立于其在适配器中的位置。
对PagerAdapter的startUpdate(ViewGroup)方法的一次调用,标志着ViewPager的页面内容即将改变。
随后,会调用若干次instantiateItem(ViewGroup, int) 或destroyItem(ViewGroup, int, Object),
最后,会调用 finishUpdate(ViewGroup),这意味着本次更新将要结束了。
等到finishUpdate返回时,与instantiateItem返回的key对象关联的view,应该被添加到其父控件ViewGroup中了,
而与传递给destroyItem
的这些key关联的view,应该被移除了。
isViewFromObject(View, Object)方法用于判断某个view是否与key对象关联。
一个简单的PagerAdapter,可以用page Views本身当为key对象;
创建并添加到ViewGroup中后,可以instantiateItem(ViewGroup, int)中返回它;
对应的destroyItem(ViewGroup, int, Object)的实现,从父控件ViewGroup中删除它;
isViewFromObject(View, Object) 可以这样实现:return view == object;.
PagerAdapter支持数据集(data set)的变更更新。
但数据集变更,必须发生在主线程中,并且最后要调用notifyDataSetChanged()方法,
这点与从BaseAdapter派生的AdapterView的适配器,很相似。
数据集的改变,可以包含pages的添加,删除或位置改变。
ViewPager将保持当前的页面处于active状态,它由实现了getItemPosition(Object)方法的适配器提供。
public Object instantiateItem (ViewGroup container, int position)
在指定的位置创建页面;适配器负责添加view到这个容器中,然而它只保证在finishUpdate(ViewGroup)返回时才完成。
public void destroyItem (ViewGroup container, int position, Object object)
删除指定位置的页面;适配器负责从view容器中删除view,然而它只保证在finishUpdate(ViewGroup)返回时才完成。
public abstract int getCount ()
返回可用的view的数量。
public abstract boolean isViewFromObject (View view, Object object)
判断页面是否跟指定的key对象关联,key对象由instantiateItem(ViewGroup, int)返回。
class ViewPagerAdapter extends PagerAdapter { @Override public int getCount() { return views.size(); } @Override public boolean isViewFromObject(View view, Object object) { return view == object; } @Override public Object instantiateItem(ViewGroup container, int position) { container.addView(views.get(position)); return views.get(position); } @Override public void destroyItem(ViewGroup container, int position, Object object) { container.removeView(views.get(position)); } }
下面直接使用,先看下布局文件:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".MainActivity"> <android.support.v4.view.ViewPager android:id="@+id/viewpager" android:layout_width="match_parent" android:layout_height="match_parent" /> </LinearLayout>
之后直接使用,使用容器作为数据的承载,直接看代码:
public class MainActivity extends Activity { private List<View> views; private ViewPager vp; int[] imgIds = { R.mipmap.app__intro_01, R.mipmap.app__intro_02, R.mipmap.app__intro_03, R.mipmap.app__intro_04, R.mipmap.app__intro_05 }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initView(); } private void initView() { views = new ArrayList<>(); for (int imgId : imgIds) { RelativeLayout view = (RelativeLayout) this.getLayoutInflater().inflate(R.layout.app__intro_item, null); ImageView image = (ImageView) view.findViewById(R.id.intro_img); image.setImageResource(imgId); views.add(view); } // 初始化Adapter ViewPagerAdapter vpAdapter = new ViewPagerAdapter(); vp = (ViewPager) findViewById(R.id.viewpager); vp.setAdapter(vpAdapter); } class ViewPagerAdapter extends PagerAdapter { @Override public int getCount() { return views.size(); } @Override public boolean isViewFromObject(View view, Object object) { return view == object; } @Override public Object instantiateItem(ViewGroup container, int position) { container.addView(views.get(position)); return views.get(position); } @Override public void destroyItem(ViewGroup container, int position, Object object) { container.removeView(views.get(position)); } } }
这里为了最为简单的使用ViewPager作为引导页,所以直接在初始化view(initView())时候,就塞入了item布局.
作为一个完整的引导页.在引导页到最后一页时候当然是进入App之中,所以我们还要给vp(ViewPager)添加setOnPagerChangeListener()即可:
package com.fightzhao.introactivitydemo; import android.app.Activity; import android.os.Bundle; import android.support.v4.view.PagerAdapter; import android.support.v4.view.ViewPager; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.RelativeLayout; import android.widget.Toast; import java.util.ArrayList; import java.util.List; public class MainActivity extends Activity { private List<View> views; private ViewPager vp; int[] imgIds = { R.mipmap.app__intro_01, R.mipmap.app__intro_02, R.mipmap.app__intro_03, R.mipmap.app__intro_04, R.mipmap.app__intro_05 }; // 记录当前选中位置 // private int currentIndex; private boolean misScrolled; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initView(); } private void initView() { views = new ArrayList<>(); for (int imgId : imgIds) { RelativeLayout view = (RelativeLayout) this.getLayoutInflater().inflate(R.layout.app__intro_item, null); ImageView image = (ImageView) view.findViewById(R.id.intro_img); image.setImageResource(imgId); views.add(view); } // 初始化Adapter ViewPagerAdapter vpAdapter = new ViewPagerAdapter(); vp = (ViewPager) findViewById(R.id.viewpager); vp.setAdapter(vpAdapter); vp.setOnPageChangeListener(new MyOnPageChangeListener()); } class ViewPagerAdapter extends PagerAdapter { @Override public int getCount() { return views.size(); } @Override public boolean isViewFromObject(View view, Object object) { return view == object; } @Override public Object instantiateItem(ViewGroup container, int position) { container.addView(views.get(position)); return views.get(position); } @Override public void destroyItem(ViewGroup container, int position, Object object) { container.removeView(views.get(position)); } } /** * 页卡切换监听 */ public class MyOnPageChangeListener implements ViewPager.OnPageChangeListener { @Override public void onPageSelected(int arg0) { } @Override public void onPageScrolled(int arg0, float arg1, int arg2) { } @Override public void onPageScrollStateChanged(int arg0) { switch (arg0) { // 正在被拖动 case ViewPager.SCROLL_STATE_DRAGGING: misScrolled = false; break; // 最后的位置 case ViewPager.SCROLL_STATE_SETTLING: misScrolled = true; break; // 表明,ViewPager在空闲状态。当前页面完全在视图中,没有动画正在进行中。 case ViewPager.SCROLL_STATE_IDLE: if (vp.getCurrentItem() == vp.getAdapter().getCount() - 1 && !misScrolled) { Toast.makeText(MainActivity.this, "123", Toast.LENGTH_SHORT).show(); misScrolled = true; break; } } } } }
以上是最为简单的使用ViewPager作为引导也的用法.
如过项目中用到的很多可以这样写pagerAdapter
package com.fightzhao.introactivitydemo.ui.adapter; import android.content.Context; import android.support.v4.view.PagerAdapter; import android.view.View; import android.view.ViewGroup; import java.util.List; /** * Created by fightzhao on 15-9-21. */ public abstract class BaseSimplePagerAdapter<T> extends PagerAdapter { private List<T> views; private Context context; public BaseSimplePagerAdapter(Context context, List<T> views) { this.context = context; this.views = views; } @Override public int getCount() { return views.size(); } @Override public boolean isViewFromObject(View view, Object o) { return view == o; } @Override public Object instantiateItem(ViewGroup container, int position) { View view = CreateItemView(context); setViewData(view, views.get(position)); container.addView(view); return view; } protected abstract void setViewData(View view, T t); public abstract View CreateItemView(Context context); @Override public void destroyItem(ViewGroup container, int position, Object object) { container.removeView((View) object); } }
再写我们需要的:
package com.fightzhao.introactivitydemo.ui.adapter; import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.widget.ImageView; import com.fightzhao.introactivitydemo.R; import java.util.List; /** * Created by fightzhao on 15-9-21. */ public class MyPagerAdapter extends BaseSimplePagerAdapter<Integer>{ public MyPagerAdapter(Context context, List<Integer> views) { super(context, views); } @Override protected void setViewData(View view, Integer integer) { ImageView imag = (ImageView) view.findViewById(R.id.intro_img); imag.setImageResource(integer); } @Override public View CreateItemView(Context context) { return LayoutInflater.from(context).inflate(R.layout.app__intro_item,null); } }
使用:
package com.fightzhao.introactivitydemo; import android.app.Activity; import android.os.Bundle; import android.support.v4.view.ViewPager; import android.widget.Toast; import com.fightzhao.introactivitydemo.ui.adapter.MyPagerAdapter; import java.util.ArrayList; import java.util.List; public class MainActivity extends Activity { private List<Integer> views; private ViewPager vp; private boolean misScrolled; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initData(); initView(); } private void initData() { views = new ArrayList<>(); views.add(R.mipmap.app__intro_01); views.add(R.mipmap.app__intro_02); views.add(R.mipmap.app__intro_03); views.add(R.mipmap.app__intro_04); views.add(R.mipmap.app__intro_05); } private void initView() { // 初始化Adapter MyPagerAdapter vpAdapter = new MyPagerAdapter(this,views); vp = (ViewPager) findViewById(R.id.viewpager); vp.setAdapter(vpAdapter); vp.setOnPageChangeListener(new MyOnPageChangeListener()); } /** * 页卡切换监听 */ public class MyOnPageChangeListener implements ViewPager.OnPageChangeListener { @Override public void onPageSelected(int arg0) { } @Override public void onPageScrolled(int arg0, float arg1, int arg2) { } @Override public void onPageScrollStateChanged(int arg0) { switch (arg0) { // 正在被拖动 case ViewPager.SCROLL_STATE_DRAGGING: misScrolled = false; break; // 最后的位置 case ViewPager.SCROLL_STATE_SETTLING: misScrolled = true; break; // 表明,ViewPager在空闲状态。当前页面完全在视图中,没有动画正在进行中。 case ViewPager.SCROLL_STATE_IDLE: if (vp.getCurrentItem() == vp.getAdapter().getCount() - 1 && !misScrolled) { Toast.makeText(MainActivity.this, "123", Toast.LENGTH_SHORT).show(); misScrolled = true; break; } } } } }
<--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------->
<--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------->
<--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------->
第二种用法:目前最为常见的是作为首页广告的滚动,可以实现自动滚动+底部指示器+点击某个页面可以跳转.系统自带的Viewpager以及无法满足我们的需要了,所以我们需要自己去自定义一个
CustomViewPager,代码如下:
package com.fightzhao.mypageradapter2.ui.customviews; import android.content.Context; import android.os.Handler; import android.os.Message; import android.support.v4.view.PagerAdapter; import android.support.v4.view.ViewPager; import android.util.AttributeSet; /** * Created by fightzhao on 15-9-23. */ public class CustomViewPager extends ViewPager { private static final int DEFAULT_INTERVAL = 3000; private int mFlipInterval = DEFAULT_INTERVAL; private final int FLIP_MSG = 1; private boolean isAutoScroll = false; public CustomViewPager(Context context) { super(context); } public CustomViewPager(Context context, AttributeSet attrs) { super(context, attrs); } public void setScrollInterval(int milliseconds) { mFlipInterval = milliseconds; } private final Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { if (msg.what == FLIP_MSG) { if (isAutoScroll) { setCurrentItem(getNextItem(), true); msg = obtainMessage(FLIP_MSG); sendMessageDelayed(msg, mFlipInterval); } } } }; /** * 自动开始循环 */ public void startAutoScroll() { isAutoScroll = true; Message msg = mHandler.obtainMessage(FLIP_MSG); mHandler.sendMessageDelayed(msg, mFlipInterval); } /** * 停止循环 */ public void stopScroll() { isAutoScroll = false; if (mHandler.hasMessages(FLIP_MSG)) { mHandler.removeMessages(FLIP_MSG); } } /** * 重新开始循环 */ public void resumeScroll() { if (mHandler.hasMessages(FLIP_MSG)) { mHandler.removeMessages(FLIP_MSG); } startAutoScroll(); } private int getNextItem() { PagerAdapter adapter = getAdapter(); if (null != adapter) { // Index of currently displayed page. if (getCurrentItem() >= adapter.getCount() - 1) { return 0; } else { return getCurrentItem() + 1; } } return 0; } private int getPreviousItem() { PagerAdapter adapter = getAdapter(); if (null != adapter) { if (getCurrentItem() <= 0) { //show last displayed page return adapter.getCount() - 1; } else { return getCurrentItem() - 1; } } return 0; } }
代码大家肯定能看懂,就是对viewpager的自动循环中加入了Handler.