一、自定义BannerViewPager
①、继承自ViewPager,重写构造
②、自定义BannerViewPagerAdapter 继承PagerAdapter
public class BannerViewPager extends ViewPager{
public BannerViewPager(Context context) {
this(context, null);
}
public BannerViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
}
private class BannerViewPagerAdapter extends PagerAdapter{
@Override
public int getCount() {
}
@Override
public boolean isViewFromObject(View view, Object object) {
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
}
}
}
③、创建setAdapter()
public void setAdapter(BannerAdapter adapter) {
this.mAdapter=adapter;
//设置父类 ViewPager的Adapter
setAdapter(new BannerViewPagerAdapter());
//可以向左滑动
setCurrentItem(mAdapter.getCount() * 1000);
}
其中BannerAdapter 为
public abstract class BannerAdapter {
/**
* 根据位置获取ViewPage中的子View
* @param position
* @return
*/
public abstract View getView(int position,View convertView);
/***
* 获取有多少条
* @return
*/
public abstract int getCount();
}
适配器方法
public int getCount() {
//实现无线循环
return Integer.MAX_VALUE;
}
/**
* 创建条目回调的方法
*
* @param container
* @param position
* @return
*/
@Override
public Object instantiateItem(ViewGroup container, int position) {
//用Adapter设计模式 可以自定义view position%mAdapter.getCount())取余
position %= mAdapter.getCount();
if (position<0){
position=mAdapter.getCount()+position;
}
View bannerItemView = mAdapter.getView(position, getConvertView());
//添加到viewpage中
container.addView(bannerItemView);
return bannerItemView;
}
/**
* 销毁条目回调的方法
* @param container
* @param position
* @param object
*/
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((View)object);
//界面复用
mConvertViews.add((View) object);
}
界面复用
/**
* 界面复用
* @return
*/
public View getConvertView() {
for (int i = 0; i < mConvertViews.size(); i++) {
//获取没有添加到ViewPage 中的View
if (mConvertViews.get(i).getParent()==null){
return mConvertViews.get(i);
}
}
return null;
}
④自动轮播
/**
* 开始轮播
*/
public void startRoll(){
isRoll=true;
//清楚消息
mHandler.removeMessages(SCROLL_MSG);
//发送延迟消息 实现轮播
mHandler.sendEmptyMessageDelayed(SCROLL_MSG, mCutDownTime);
}
mHandler接收
// 发送消息的 msg
private final int SCROLL_MSG=0x0011;
//默认轮播时间
private int mCutDownTime=3500;
//是否轮播
private boolean isRoll=false;
private Handler mHandler=new Handler(){
@Override
public void handleMessage(Message msg) {
//调用 父类方法 切换到下一页
setCurrentItem(getCurrentItem()+1);
//不断循环调用
startRoll();
}
};
⑤、改变切换速率 利用反射
public BannerViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
try {
//改变切换速率 duration 持续时间为局部变量 要想改变通过反射
Field field= ViewPager.class.getDeclaredField("mScroller");
//设置参数
bannerScroller = new BannerScroller(context);
//设置强制改变 private
field.setAccessible(true);
field.set(this, bannerScroller);
} catch (Exception e) {
e.printStackTrace();
}
mConvertViews=new ArrayList<>();
}
BannerScroller类
public class BannerScroller extends Scroller {
//动画持续的时间
private int mScrollerDuration=950;
/**
* 设置动画切换的时间
* @param mScrollerDuration
*/
public void setmScrollerDuration(int mScrollerDuration) {
this.mScrollerDuration = mScrollerDuration;
}
public BannerScroller(Context context) {
super(context);
}
public BannerScroller(Context context, Interpolator interpolator) {
super(context, interpolator);
}
public BannerScroller(Context context, Interpolator interpolator, boolean flywheel) {
super(context, interpolator, flywheel);
}
@Override
public void startScroll(int startX, int startY, int dx, int dy, int duration) {
super.startScroll(startX, startY, dx, dy, mScrollerDuration);
}
}
⑥、触摸时停止轮播
/**
* 触摸监听 停止自动轮播
* @param ev
* @return
*/
@Override
public boolean onTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_MOVE:
//从消息队列中移除所有message
//停止轮播
if (isRoll){
mHandler.removeMessages(SCROLL_MSG);
}
break;
case MotionEvent.ACTION_UP:
if (isRoll){
//重新发送
mHandler.sendEmptyMessageDelayed(SCROLL_MSG, mCutDownTime);
}
break;
}
return super.onTouchEvent(ev);
}
⑦、防止泄漏
/**
* Activity销毁 时回调该方法
*
* 防止内存泄露
*/
@Override
protected void onDetachedFromWindow() {
mHandler.removeMessages(SCROLL_MSG);
mHandler=null;
//解除绑定
((Activity) getContext()).getApplication().unregisterActivityLifecycleCallbacks(activityLifecycleCallbacks);
super.onDetachedFromWindow();
}
⑧、不可见时,停止发送
//Activity生命周期管理
Application.ActivityLifecycleCallbacks activityLifecycleCallbacks=new DefaultActivityLifecycleCallbacks() {
@Override
public void onActivityResumed(Activity activity) {
//实现轮播 是否是当前的Activity
if (activity==getContext()&& isRoll){
//发送延迟消息 实现轮播
mHandler.sendEmptyMessageDelayed(SCROLL_MSG, mCutDownTime);
}
}
@Override
public void onActivityPaused(Activity activity) {
if (activity==getContext()&& isRoll){
//停止轮播
mHandler.removeMessages(SCROLL_MSG);
}
}
};
DefaultActivityLifecycleCallbacks类实现
public class DefaultActivityLifecycleCallbacks implements Application.ActivityLifecycleCallbacks {
@Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
}
@Override
public void onActivityStarted(Activity activity) {
}
@Override
public void onActivityResumed(Activity activity) {
}
@Override
public void onActivityPaused(Activity activity) {
}
@Override
public void onActivityStopped(Activity activity) {
}
@Override
public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
}
@Override
public void onActivityDestroyed(Activity activity) {
}
}