自定义 轮播图 BannerView

一、自定义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) {

}
}

你可能感兴趣的:(自定义 轮播图 BannerView)