最近在学习撸撸的代码,发现他的轮播写法很独特,但是有bug,就重新修改了一下,现在支持左右点击和圆点自定义。

    BannerAdapter:(注意适配器自己看ImageView和onclick的自己项目的写法~)

package com.example.p029_banner_lunbo.adapter; import android.app.Activity; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import com.example.p029_banner_lunbo.bannerutils.BannerView; import com.example.p029_banner_lunbo.domain.Biaoge_listBean; import java.util.List; public class BannerAdapter extends BannerView.Adapter {     private List<Biaoge_listBean> mAdList;     private Object mReceiver;     public BannerAdapter(Object receiver, List<Biaoge_listBean> items) {         mReceiver = receiver;         mAdList = items;     }     @Override     public int getRealCount() {         return mAdList.size();     }     @Override     public Object instantiateItem(final ViewGroup container, int position) {         int size = mAdList.size();         if (size == 0) {             return null;         }         final int pos = position % size;         final Biaoge_listBean item = mAdList.get(pos);         ViewGroup.LayoutParams p = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,                 ViewGroup.LayoutParams.MATCH_PARENT);         ImageView iv = new ImageView(container.getContext());         iv.setScaleType(ImageView.ScaleType.FIT_XY);         iv.setAdjustViewBounds(true);         container.addView(iv, p);         iv.setBackgroundResource(item.getImg_url()); //        GlideUtil.display(container.getContext(), iv, item.getPic_url(), //                GlideOptionsFactory.get(GlideOptionsFactory.Type.RADIUS));         iv.setOnClickListener(new View.OnClickListener() {             @Override             public void onClick(View v) { //                MobEventHelper.onEvent(container.getContext(), "UI2_ec_index_banner"); //                    MobEventHelper.onEvent(container.getContext(), "UI2_ec_index_banner_" + String.valueOf(pos + 1));                 if (container.getContext() instanceof Activity) {                     Activity act = (Activity) container.getContext();                     //跳转bufen //                    HiosHelper.resolveAd(act, mReceiver, item.getUrl());                 }             }         });         return iv;     }     @Override     public void destroyItem(ViewGroup container, int position, Object object) {         container.removeView((View) object);     } }

    DotIndicatorView:(圆点的方法大部分都public了,大家可以DotIndicatorView.自定义~)    

package com.example.p029_banner_lunbo.bannerutils; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.util.AttributeSet; import android.util.DisplayMetrics; import android.util.TypedValue; import android.view.View; /**  * 圆点导航  * @author geek  *  */ public class DotIndicatorView extends View {    private Paint mPaint;    private int mPadding;    private int mCircleRadius;        private int mCurrentColor;    private int mNormalColor;        private int mCount = 3;        private int mCurrent;        public DotIndicatorView(Context context) {       super(context);       initView();    }        public DotIndicatorView(Context context, AttributeSet attrs) {       this(context, attrs, 0);    }    public DotIndicatorView(Context context, AttributeSet attrs, int defStyle) {       super(context, attrs, defStyle);       initView();    }    private void initView() {       DisplayMetrics dm = getResources().getDisplayMetrics();       mPadding = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 10, dm);       mCircleRadius = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 4, dm);       mCurrentColor = Color.WHITE;       mNormalColor = Color.argb(88, 91, 91, 91);              mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);    }        @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {       int width = mCircleRadius * 2 * mCount + mPadding * (mCount -1);       int height = mCircleRadius * 2;              setMeasuredDimension(width, height);    }        @Override    protected void onDraw(Canvas canvas) {       for (int i = 0; i < mCount; i++) {          canvas.save();          canvas.translate((mCircleRadius * 2 + mPadding) * i, 0);                    if(i == mCurrent) mPaint.setColor(mCurrentColor);          else mPaint.setColor(mNormalColor);                    canvas.drawCircle(mCircleRadius , mCircleRadius, mCircleRadius, mPaint);          canvas.restore();       }    }        /**     * 创建导航     * @param count 个数     */    public void create(int count) {       mCount = count;       requestLayout();       invalidate();    }        /**      * 选中当前     * @param position 选中位置     */    public void current(int position) {       mCurrent = position;       invalidate();    }        /**     * 获取当前选中的位置     * @return     */    public int current() {       return mCurrent;    } }

    BannerView:(自定义的View~)

    

package com.example.p029_banner_lunbo.bannerutils; import android.content.Context; import android.content.res.TypedArray; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.os.Parcelable; import android.support.v4.view.PagerAdapter; import android.support.v4.view.ViewPager; import android.support.v4.view.ViewPager.OnPageChangeListener; import android.util.AttributeSet; import android.view.Gravity; import android.view.MotionEvent; import android.view.View; import android.widget.FrameLayout; import com.example.p029_banner_lunbo.R; import java.lang.ref.WeakReference; public class BannerView extends FrameLayout {     private static final int MSG_RUN = 1;     private ViewPager mViewPager;     /**      * 导航的小点      */     private DotIndicatorView mIndicator;     private Adapter mAdapter;     /**      * 是否处于滑动的状态      */     private boolean isScrolling;     private int mIndicatorPosition; // center_hori  left     /**      * 是否显示indicator      */     private boolean isShowIndicator = true;     private boolean isTouch;     private Handler mHandler;     private BannerViewHelper mHelper;     private int mScrollTime;     public BannerView(Context context, AttributeSet attrs) {         this(context, attrs, 0);     }     public BannerView(Context context, AttributeSet attrs, int defStyle) {         super(context, attrs, defStyle);         TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.BannerView,                 defStyle, 0);         mIndicatorPosition = ta.getInt(R.styleable.BannerView_indicator_position, 0);         isShowIndicator = ta.getBoolean(R.styleable.BannerView_indicator_visible, true);         mScrollTime = ta.getInteger(R.styleable.BannerView_scroll_time, 3000);         isScrolling = ta.getBoolean(R.styleable.BannerView_auto_start, false);         ta.recycle();         initView(context);     }     private void initView(Context context) {         mViewPager = new ViewPager(context);         mViewPager.addOnPageChangeListener(mOnPageChangeListener);         addView(mViewPager);//, viewPagerParams);         mHandler = new H(mViewPager);         mIndicator = new DotIndicatorView(context);         LayoutParams indicatorParams =                 new LayoutParams(LayoutParams.WRAP_CONTENT,                         LayoutParams.WRAP_CONTENT);         if (mIndicatorPosition == 0) {             indicatorParams.gravity = Gravity.BOTTOM | Gravity.LEFT;         } else if (mIndicatorPosition == 1) {             indicatorParams.gravity = Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL;         } else if (mIndicatorPosition == 2) {             indicatorParams.gravity = Gravity.BOTTOM | Gravity.RIGHT;         }         indicatorParams.bottomMargin = 20;         if (!isShowIndicator) {             return;         }         addView(mIndicator, indicatorParams);     }     @Override     protected void onAttachedToWindow() {         if (isScrolling) {             startScroll();         }         super.onAttachedToWindow();         mHelper = new BannerViewHelper(this);     }     @Override     public boolean dispatchTouchEvent(MotionEvent ev) {         if (mHelper != null) {             mHelper.resolveTouchConflict(ev);         }         return super.dispatchTouchEvent(ev);     }     @Override     protected LayoutParams generateDefaultLayoutParams() {         return new LayoutParams(LayoutParams.MATCH_PARENT,                 LayoutParams.WRAP_CONTENT);     }     @Override     public LayoutParams generateLayoutParams(AttributeSet attrs) {         return new LayoutParams(getContext(), attrs);     }     @Override     protected android.view.ViewGroup.LayoutParams generateLayoutParams(             android.view.ViewGroup.LayoutParams p) {         return new LayoutParams(p);     }     @Override     protected boolean checkLayoutParams(android.view.ViewGroup.LayoutParams p) {         return p instanceof LayoutParams;     }     private OnPageChangeListener mOnPageChangeListener = new OnPageChangeListener() {         @Override         public void onPageSelected(int position) {             int relCount = mAdapter.getRealCount();             if (relCount <= 0) {                 mIndicator.current(0);             } else {                 mIndicator.current(position % relCount);             }         }         @Override         public void onPageScrolled(int arg0, float arg1, int arg2) {         }         @Override         public void onPageScrollStateChanged(int arg0) {             isTouch = arg0 == ViewPager.SCROLL_STATE_DRAGGING;             if (arg0 == ViewPager.SCROLL_STATE_IDLE && isScrolling) {                 mHandler.removeMessages(MSG_RUN);                 Message msg = mHandler.obtainMessage(MSG_RUN, isScrolling ? 1 : 0, isTouch ? 1 : 0);                 mHandler.sendMessageDelayed(msg, mScrollTime);             }         }     };     /**      * 开始自动滚动      */     public void startScroll() {         mHandler.removeMessages(MSG_RUN);         isScrolling = true;         Message msg = mHandler.obtainMessage(MSG_RUN, 1, isTouch ? 1 : 0);         mHandler.sendMessageDelayed(msg, mScrollTime);     }     /**      * 停止自动滚动      */     public void stopScroll() {         isScrolling = false;         if (mHandler != null) {             mHandler.removeMessages(MSG_RUN);         }     }     @Override     protected Parcelable onSaveInstanceState() {         Bundle bundle = new Bundle();         bundle.putBoolean("scroll", isScrolling);         bundle.putParcelable("state", super.onSaveInstanceState());         return bundle;     }     @Override     protected void onRestoreInstanceState(Parcelable state) {         Bundle bundle = (Bundle) state;         isScrolling = bundle.getBoolean("scroll");         state = bundle.getParcelable("state");         if (state != null) {             super.onRestoreInstanceState(state);         }     } // @Override // protected void onAttachedToWindow() { //    super.onAttachedToWindow(); //    if(isScrolling) mHandler.sendEmptyMessage(MSG_RUN); // }     @Override     protected void onDetachedFromWindow() {         mHandler.removeMessages(MSG_RUN);         super.onDetachedFromWindow();     }     /**      * 设置banner的数据集合      */     public void setAdapter(Adapter adapter) {         mAdapter = adapter;         mViewPager.setAdapter(adapter);         mIndicator.create(adapter.getRealCount());     }     /**      * 获取adapter      */     public Adapter getAdapter() {         return mAdapter;     }     public int getCurrent() {         return mViewPager.getCurrentItem() + 1;     }     public void setCurrent(int current) {         mViewPager.setCurrentItem(current);     }     private static class H extends Handler {         private WeakReference<ViewPager> mViewPager;         public H(ViewPager pager) {             mViewPager = new WeakReference<>(pager);         }         public void handleMessage(Message msg) {             if (mViewPager.get() == null) return;             boolean isScrolling = msg.arg1 == 1;             boolean isTouch = msg.arg2 == 1;             if (msg.what == MSG_RUN && isScrolling) {                 if (!isTouch) {                     int pos = mViewPager.get().getCurrentItem() + 1;                     mViewPager.get().setCurrentItem(pos); //             sendEmptyMessageDelayed(MSG_RUN, 3000);                 } else {                     removeMessages(MSG_RUN);                 }             }         }     }     public static abstract class Adapter extends PagerAdapter {         @Override         public final int getCount() {             return Integer.MAX_VALUE;         }         /**          * 获取真实的数据统计          *          * @return          */         public abstract int getRealCount();         @Override         public final boolean isViewFromObject(View arg0, Object arg1) {             return arg0 == arg1;         }         public Object getItem(int position) {             return position;         }     } }

    BannerViewHelper:(用于解决BannerView和SwipeRefreshLayout的冲突)

package com.example.p029_banner_lunbo.bannerutils; import android.support.v4.widget.SwipeRefreshLayout; import android.view.MotionEvent; import android.view.VelocityTracker; import android.view.ViewGroup; /**  * 用于解决BannerView和SwipeRefreshLayout的冲突  * @author geek  *  */ public class BannerViewHelper {    private BannerView mBannerView;    private SwipeRefreshLayout mSwipeRefreshLayout;        private VelocityTracker mVelocityTracker;        private float mAccuracy = 1.f;        public BannerViewHelper(BannerView bannerView) {       mBannerView = bannerView;       mSwipeRefreshLayout = findSwipeRefreshLayout();    }        public BannerViewHelper(BannerView bannerView, float accuracy) {       this(bannerView);       mAccuracy = accuracy;    }        public void resolveTouchConflict(MotionEvent event) {       if(mSwipeRefreshLayout == null) return;              setupVelocityTracker(event);       switch (event.getAction()) {       case MotionEvent.ACTION_MOVE:          if(!mSwipeRefreshLayout.isEnabled()) return;          mVelocityTracker.computeCurrentVelocity(1000);          if(Math.abs(mVelocityTracker.getXVelocity()) >              Math.abs(mVelocityTracker.getYVelocity()) * mAccuracy) {             mSwipeRefreshLayout.setEnabled(false);          }          break;       case MotionEvent.ACTION_UP:       case MotionEvent.ACTION_CANCEL:          mSwipeRefreshLayout.setEnabled(true);          recycleVelocityTracker();       default:          break;       }    }        private void setupVelocityTracker(MotionEvent event) {       if(mVelocityTracker == null) mVelocityTracker = VelocityTracker.obtain();       mVelocityTracker.addMovement(event);    }        private void recycleVelocityTracker() {       if(mVelocityTracker != null) {          mVelocityTracker.clear();          mVelocityTracker.recycle();          mVelocityTracker = null;       }    }        private SwipeRefreshLayout findSwipeRefreshLayout() {       ViewGroup parent = (ViewGroup) mBannerView.getParent();       while(parent != null && parent.getId() != android.R.id.content) {          if(parent instanceof SwipeRefreshLayout) return (SwipeRefreshLayout) parent;          parent = (ViewGroup) parent.getParent();       }       return null;    } }

    xml布局:

<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"     xmlns:app="http://schemas.android.com/apk/res-auto"     android:layout_width="match_parent"     android:layout_height="match_parent"     android:orientation="vertical">     <LinearLayout         android:layout_width="match_parent"         android:layout_height="wrap_content"         android:background="#ccc"         android:orientation="vertical">         <com.example.p029_banner_lunbo.bannerutils.BannerView             android:id="@+id/banner"             android:layout_width="match_parent"             android:layout_height="400dp"             app:indicator_position="center"             app:indicator_visible="false"             app:scroll_time="8000" />     </LinearLayout>     <TextView         android:id="@+id/tv_left"         android:layout_width="wrap_content"         android:layout_height="wrap_content"         android:background="@drawable/icon_left" />     <TextView         android:id="@+id/tv_right"         android:layout_width="wrap_content"         android:layout_height="wrap_content"         android:layout_alignParentRight="true"         android:background="@drawable/icon_right" /> </RelativeLayout>

    调用方法:

tv_left = (TextView) findViewById(R.id.tv_left); tv_left.setOnClickListener(new View.OnClickListener() {     @Override     public void onClick(View v) {         //左←         ToastUtil.showToastShort(MainActivity.this, "左");         mBannerView.setCurrent(mBannerView.getCurrent() - 2);     } }); tv_right = (TextView) findViewById(R.id.tv_right); tv_right.setOnClickListener(new View.OnClickListener() {     @Override     public void onClick(View v) {         //右→         ToastUtil.showToastShort(MainActivity.this, "右");         mBannerView.setCurrent(mBannerView.getCurrent());     } }); mBannerView = (BannerView) findViewById(R.id.banner); Data1(); mBannerView.setAdapter(new BannerAdapter(this, mList1)); mBannerView.stopScroll(); mBannerView.startScroll();

    代码已经整理好,效果如下图:

    图1:

    

    图2:

    

    图2:

    

    地址:https://github.com/geeklx/MyApplication/tree/master/p029_banner_lunbo

    附: