最近在学习撸撸的代码,发现他的轮播写法很独特,但是有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:
地址:https://github.com/geeklx/MyApplication/tree/master/p029_banner_lunbo
    附:
本文出自 “梁肖技术中心” 博客,请务必保留此出处http://liangxiao.blog.51cto.com/3626612/1953066
Android Studio - 第四十六期 不会AAR的轮播写法
原文:http://liangxiao.blog.51cto.com/3626612/1953066