一行代码写一个自动滚动的广告栏

/**
 * 订阅页面轮播图适配器
 *
 * @author ryze
 * @since 1.0  2019/07/17
 */
public abstract class AutoLoopSwitchBaseAdapter extends PagerAdapter {

    public AutoLoopSwitchBaseAdapter() {
    }

    public static final int VIEWPAGER_RADIX = 100;

    /**
     * 实际轮播图个数
     */
    public abstract int getDataCount();

    public abstract View getView(int position);

    public abstract Object getItem(int position);

    /**
     * 如果数据为空的时候,这里最好不为空
     */
    public abstract View getEmptyView();

    /**
     * 当数据改变时,ViewPager预加载的View需要重新设置数据
     */
    public abstract void updateView(View view, int position);

    @Override
    public final int getCount() {
        if (getDataCount() > 1) {
            //如果轮播个数大于1个,那么需要轮播,增加基数,同时在首尾加上一个,
            return getDataCount() * VIEWPAGER_RADIX + 2;
        } else {
            return getDataCount();
        }
    }

    /**
     * 得到实际页面index
     */
    public final int getActualIndex(int index) {
        int position = index;
        if (getDataCount() > 1) {
            if (index == 0) {
                position = getDataCount() - 1;
            } else if (index == getCount() - 1) {
                position = 0;
            } else {
                position = index - 1;
            }
        }
        return position;
    }

    /**
     * @param container
     * @param position
     * @return
     */
    @Override
    public final Object instantiateItem(ViewGroup container, int position) {

        position = getActualIndex(position);

        position %= getDataCount();

        View v = getView(position);

        if (v == null) {
            v = getEmptyView();
        }

        v.setTag(position);

        container.addView(v);

        return v;
    }

    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
//    super.destroyItem(container, position, object);
        container.removeView((View) object);
    }


    @Override
    public final boolean isViewFromObject(View view, Object o) {
        return view == o;
    }


}

AutoLoopSwitchBaseView.java

/**
 * 手动自动可以滚动
 *
 * @author ryze
 * @since 1.0  2019/07/17
 */
public abstract class AutoLoopSwitchBaseView extends RelativeLayout implements ViewPager.OnPageChangeListener {

    private final int VIEWPAGER_SCROLL_DURTION = 400;

    protected ViewPager mViewPager;
    protected PageShowView mPageShowView;

    protected View mFailtView;
    //
    private int mCurrentItem = 1;

    protected LoopHandler mHandler;

    protected boolean mIsDragging = false;

    protected AutoLoopSwitchBaseAdapter mPagerAdapter;

    //监听数据变化,用于去除 重试View
    private DataSetObserver mObserver;


    //正在切页
    private boolean isLoopSwitch = false;

    private boolean mCurrentVisible = true;

    public AutoLoopSwitchBaseView(Context context) {
        super(context);
        initView();
    }

    public AutoLoopSwitchBaseView(Context context, AttributeSet attrs) {
        super(context, attrs);
        initView();
    }

    public AutoLoopSwitchBaseView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initView();
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    public AutoLoopSwitchBaseView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        initView();
    }

    /**
     * 页面切换回调
     *
     * @param model adapter getItem
     */
    protected abstract void onSwitch(int index, Object model);

    /**
     * 滚动延时时间
     */
    protected abstract long getDurtion();

    /**
     * 如果需要网络异常处理
     */
    protected abstract View getFailtView();

    @Override
    protected void onVisibilityChanged(View changedView, int visibility) {
        super.onVisibilityChanged(changedView, visibility);
        if (visibility == VISIBLE) {
            mCurrentVisible = true;
        } else {
            mCurrentVisible = false;
        }
    }

    public boolean isCurrentVisible() {
        return mCurrentVisible;
    }

    public void setCurrentVisible(boolean mCurrentVisible) {
        this.mCurrentVisible = mCurrentVisible;
    }

    private void initView() {
        mViewPager = new ViewPager(getContext());
        mViewPager.setId(R.id.autoloopswitch_viewpager_id);
        mViewPager.addOnPageChangeListener(this);
        addView(mViewPager, generalLayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
        controlViewPagerSpeed();

        LayoutParams params;
        mPageShowView = new PageShowView(getContext());
        mPageShowView.setId(R.id.autoloopswitch_pagershow_id);//此处以及上面的id为values下ids中的id  自己添加就好
        DisplayMetrics displayMetrics = new DisplayMetrics();
        WindowManager windowManager = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);
        windowManager.getDefaultDisplay().getMetrics(displayMetrics);
        params = generalLayoutParams(LayoutParams.MATCH_PARENT, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 10, displayMetrics));
        params.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
        params.addRule(RelativeLayout.CENTER_HORIZONTAL);
        addView(mPageShowView, params);

        mHandler = new LoopHandler(this);
    }

    private LayoutParams generalLayoutParams(int w, int h) {
        LayoutParams params = new LayoutParams(w, h);
        return params;
    }

    @Override
    public void onPageScrolled(int i, float v, int i1) {

    }

    @Override
    public void onPageSelected(int i) {

        if (isLoopSwitch) {
            isLoopSwitch = false;
            return;
        }

        mCurrentItem = i;

        int datacount = mPagerAdapter.getDataCount();

        if (datacount > 1) {
            int index = mPagerAdapter.getActualIndex(i) % datacount;
            mPageShowView.setCurrentView(index, datacount);
            onSwitch(index, mPagerAdapter.getItem(index));
        }

    }

    @Override
    public void onPageScrollStateChanged(int i) {

        if (i == ViewPager.SCROLL_STATE_DRAGGING) {
            mIsDragging = true;
        } else if (i == ViewPager.SCROLL_STATE_IDLE) {
            if (mViewPager.getCurrentItem() == 0) {
                isLoopSwitch = true;
                mViewPager.setCurrentItem(mPagerAdapter.getCount() - 2, false);
            } else if (mViewPager.getCurrentItem() == mPagerAdapter.getCount() - 1) {
                isLoopSwitch = true;
                mViewPager.setCurrentItem(1, false);
            }
            mCurrentItem = mViewPager.getCurrentItem();

            if (mIsDragging && mHandler != null) {
                //如果从dragging状态到不是mIsDragging
                mHandler.sendEmptyMessageDelayed(LoopHandler.MSG_UPDATE, getDurtion());
            }

            mIsDragging = false;

            Log.e("ryze", "onPageScrollStateChanged  " + i);
        }
    }


    private void notifyDataSetChanged() {
        if (mPagerAdapter != null) {
            int datacount = mPagerAdapter.getDataCount();

            int currentIndex = 0;
            if (datacount > 1) {
                mCurrentItem = mPagerAdapter.getCount() / 2;
                currentIndex = mPagerAdapter.getActualIndex(mCurrentItem) % datacount;
            } else {
                mCurrentItem = 1;
                currentIndex = 0;
            }
            mViewPager.setCurrentItem(mCurrentItem);
            mPageShowView.setCurrentView(currentIndex, datacount);

            if (mFailtView != null && datacount > 0) {
                removeView(mFailtView);
                mFailtView = null;
            }

            updateView();
        }
    }

    private void updateView() {
        for (int i = 0; i < mViewPager.getChildCount(); i++) {
            View v = mViewPager.getChildAt(i);
            if (v != null) {
                int position = (Integer) v.getTag();
                mPagerAdapter.updateView(v, position);
            }
        }

    }


    public void setAdapter(AutoLoopSwitchBaseAdapter adapter) {
        if (mPagerAdapter != null) {
            mPagerAdapter.unregisterDataSetObserver(mObserver);
        }
        this.mPagerAdapter = adapter;
        if (mPagerAdapter != null) {
            if (mObserver == null) {
                mObserver = new PagerObserver();
            }
            mPagerAdapter.registerDataSetObserver(mObserver);

            if (mViewPager != null) {
                mViewPager.setAdapter(mPagerAdapter);
            }
            //如果没有数据,同时没有网络的情况
            if (mPagerAdapter.getDataCount() <= 0) {
                mFailtView = getFailtView();
                if (mFailtView != null) {
                    addView(mFailtView, generalLayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
                }
            }

        } else {
            throw new NullPointerException("AutoLoopSwitchBaseAdapter can not null");
        }
    }


    public void destory() {
        if (mHandler != null) {
            mHandler.close();
        }
    }

    protected static class LoopHandler extends Handler {
        //请求更新显示的View。
        private static final int MSG_UPDATE = 1;
        //请求暂停轮播。
        public static final int MSG_STOP = 2;
        //请求恢复轮播。
        public static final int MSG_REGAIN = 3;

        private AutoLoopSwitchBaseView mView;

        private boolean mIsStop = false;

        public LoopHandler(AutoLoopSwitchBaseView mView) {
            this.mView = new WeakReference<AutoLoopSwitchBaseView>(mView).get();
        }

        public boolean isStop() {
            return mIsStop;
        }

        public void close() {
            removeMessages(MSG_UPDATE);
            removeMessages(MSG_REGAIN);
            removeMessages(MSG_STOP);
        }

        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            if (mView == null || mView.mHandler == null || mView.mPagerAdapter == null || mView.mIsDragging) {
                return;
            }

            Log.e("ryze", "stop: " + mIsStop);

            switch (msg.what) {
                case MSG_UPDATE:
                    if (mIsStop || hasMessages(MSG_UPDATE)) {
                        return;
                    }
                    if (mView.mPagerAdapter.getCount() > 1) {
                        mView.mCurrentItem++;
                        mView.mCurrentItem %= mView.mPagerAdapter.getCount();
                        mView.mViewPager.setCurrentItem(mView.mCurrentItem, true);
                        sendEmptyMessageDelayed(MSG_UPDATE, mView.getDurtion());
                    }
                    break;
                case MSG_STOP:
                    if (hasMessages(MSG_UPDATE)) {
                        removeMessages(MSG_UPDATE);
                    }
                    mIsStop = true;
                    Log.e("ryze", "stop: MSG_STOP " + mIsStop);
                    break;
                case MSG_REGAIN:
                    if (hasMessages(MSG_UPDATE)) {
                        removeMessages(MSG_UPDATE);
                    }
                    sendEmptyMessageDelayed(MSG_UPDATE, mView.getDurtion());
                    mIsStop = false;
                    Log.e("ryze", "stop: MSG_REGAIN " + mIsStop);
                    break;
            }
        }
    }

    private class PagerObserver extends DataSetObserver {
        private PagerObserver() {
        }

        public void onChanged() {
            Log.e("ryze", "PagerObserver onChanged ");
            notifyDataSetChanged();
        }

        public void onInvalidated() {
            Log.e("ryze", "PagerObserver onInvalidated ");

            notifyDataSetChanged();
        }
    }


    public ViewPager getViewPager() {
        return mViewPager;
    }


    private void controlViewPagerSpeed() {
        try {
            Field mField;

            mField = ViewPager.class.getDeclaredField("mScroller");
            mField.setAccessible(true);

            FixedSpeedScroller mScroller = new FixedSpeedScroller(getContext(),
                    new DecelerateInterpolator());
            mScroller.setmDuration(VIEWPAGER_SCROLL_DURTION);
            mField.set(mViewPager, mScroller);

            mField = ViewPager.class.getDeclaredField("mFlingDistance");
            mField.setAccessible(true);
            mField.set(mViewPager, 20);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    private class FixedSpeedScroller extends Scroller {

        private int mDuration = 600; // default time is 600ms

        public FixedSpeedScroller(Context context) {
            super(context);
        }

        public FixedSpeedScroller(Context context, Interpolator interpolator) {
            super(context, interpolator);
        }

        @Override
        public void startScroll(int startX, int startY, int dx, int dy, int duration) {
            // Ignore received duration, use fixed one instead
            super.startScroll(startX, startY, dx, dy, mDuration);
        }

        @Override
        public void startScroll(int startX, int startY, int dx, int dy) {
            // Ignore received duration, use fixed one instead
            super.startScroll(startX, startY, dx, dy, mDuration);
        }

        /**
         * set animation time
         */
        public void setmDuration(int time) {
            mDuration = time;
        }

        /**
         * get current animation time
         */
        public int getmDuration() {
            return mDuration;
        }
    }

}

AutoSwitchView.java

public class AutoSwitchView extends AutoLoopSwitchBaseView {

    public AutoSwitchView(Context context) {
        super(context);
    }

    public AutoSwitchView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public AutoSwitchView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    public AutoSwitchView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }


    @Override
    protected void onSwitch(int index, Object o) {
        GoodsPojo model = (GoodsPojo) o;
        if (model != null) {
        }
    }

    @Override
    protected View getFailtView() {
        return null;
    }

    @Override
    protected long getDurtion() {
        return 3000;
    }

    @Override
    public void setAdapter(AutoLoopSwitchBaseAdapter adapter) {
        super.setAdapter(adapter);
        mHandler.sendEmptyMessage(LoopHandler.MSG_REGAIN);
    }
    public void setFocusable(boolean f){
        mViewPager.setFocusable(f);
    }
}

PageShowView.java

public class PageShowView extends View {

  int colorCurrent = 0;

  int colorOther = 0;

  int total = 0;

  int current = 0;

  private Paint mPaint = null;

  public PageShowView(Context context) {
    this(context, null);
  }

  public PageShowView(Context context, AttributeSet attrs) {
    super(context, attrs);
    initColor();
  }

  protected void initColor() {
    colorCurrent = getResources().getColor(R.color.colorPrimary);//当前显示的图片页码颜色

    colorOther = getResources().getColor(R.color.gray_99);//其余的页码颜色

    mPaint = new Paint();
  }

  public void setCurrentView(int current, int total) {
    this.current = current;
    this.total = total;
    invalidate();
  }


  @Override
  protected void dispatchDraw(Canvas canvas) {

    super.dispatchDraw(canvas);

    int view_height = getHeight() - getPaddingBottom() - getPaddingBottom();

    int view_width = getWidth() - getPaddingLeft() - getPaddingRight();

    int height = view_height / 6;

    int width = height * 4;

    if (total > 1) {

      if (width * total + height * (total - 1) > view_width) {
        width = (view_width - (height * (total - 1))) / total;
      }

      int posX = view_width / 2 - (width * total + height * (total - 1) * 3) / 2;

      mPaint.setStrokeWidth(height);
      mPaint.setAntiAlias(false);
      for (int i = 0; i < total; i++) {
        if (i != current) {
          mPaint.setColor(colorOther);
        } else {
          mPaint.setColor(colorCurrent);
        }

        canvas.drawCircle(posX, view_height / 3, view_height / 3, mPaint);

        posX += height * 3 + width;
      }
    }

  }

  /**
   * 获取当前显示的位置
   */
  public int getCurrent() {
    return this.current;
  }

}

AutoSwitchAdapter.java

public class AutoSwitchAdapter extends AutoLoopSwitchBaseAdapter {

    private Context mContext;

    //GoodsPojo是实体类  你可以根据你自己的需求替换
    private List<GoodsPojo> mDatas;

    public AutoSwitchAdapter() {
        super();
    }

    public AutoSwitchAdapter(Context mContext, List<GoodsPojo> mDatas) {
        this.mContext = mContext;
        this.mDatas = mDatas;
    }

    @Override
    public int getDataCount() {
        return mDatas == null ? 0 : mDatas.size();
    }

    @Override
    public View getView(final int position) {
        ImageView imageView = new ImageView(mContext);
        imageView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.MATCH_PARENT));
        final GoodsPojo pojo = (GoodsPojo) getItem(position);
        imageView.setScaleType(ImageView.ScaleType.FIT_XY);

        GlideImageLoader.onDisplayImage(mContext,imageView,mDatas.get(position).url);

        imageView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View _view) {
                //此处写图片点击事件
            }
        });
        return imageView;
    }

    @Override
    public Object getItem(int position) {
        if (position >= 0 && position < getDataCount()) {

            return mDatas.get(position);
        }
        return null;
    }


    @Override
    public View getEmptyView() {
        return null;
    }

    @Override
    public void updateView(View view, int position) {

    }

    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        super.destroyItem(container, position, object);
    }
}

xml布局文件中使用

<com.****.****.AutoSwitchView /*此处为AutoSwitchView的绝对路径*/
    android:id="@+id/vp"
    android:layout_width="match_parent"
    android:layout_height="160dp"
    app:layout_scrollFlags="scroll"/>

代码中调用

vp.setAdapter(new AutoSwitchAdapter(Context,GoodsPojos));

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值