【自定义view】 图片轮播+小圆点

图片轮播,小圆点可支持居中或居右设置,颜色可自定义,效果如下: 

【自定义view】 图片轮播+小圆点_第1张图片


 关键代码如下:

public class BannerView extends RelativeLayout {
    private boolean isRight;
    private int point_size;
    private int point_bg;
    private int nomalColor;
    private int selectColor;

    private ViewPager vp;
    private RelativeLayout pointLayout;
    private List pictureList;
    private T t;
    //是否在没有图片的情况下占位
    private boolean isNeedStaticLocaltion;
    //是否轮播
    private boolean isPlay = false;
    private static int MARGIN = ScreenUtil.dip2px(BaseApplication.getBaseApplication(), 5);
    private List myCilcleViews;
    private List imageViews;
    private UserControal userControal;
    private int FLAG = 1;
    private int currentPosition = 0;

    private float currentX = 0;
    private float currentY = 0;
    private float MINE_XY = 20;
    public static final int MARGIN_LEFtT = ScreenUtil.dip2px(BaseApplication.getBaseApplication(), 19);
    private int mDefaultImg = R.mipmap.ic_launcher;
    //宽高比例
    private float proportion = 0.6F;
    private Handler hander = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            if (null != msg) {
                if (msg.what == FLAG) {
                    hander.removeMessages(FLAG);
                    vp.setCurrentItem(currentPosition + 1);
                    hander.sendEmptyMessageDelayed(FLAG, 3000);
                }
            }
        }
    };

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

    public BannerView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public BannerView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.BannerView);
        point_size = (int) array.getDimension(R.styleable.BannerView_point_size, 15);
        //point_bg = array.getColor(R.styleable.BannerView_point_bg, 0x00000000);
        point_bg = Color.parseColor("#00000000");
        isRight = array.getBoolean(R.styleable.BannerView_is_right, false);
        isPlay = array.getBoolean(R.styleable.BannerView_is_play, true);
        isNeedStaticLocaltion = array.getBoolean(R.styleable.BannerView_is_static_location, true);
        nomalColor = array.getColor(R.styleable.BannerView_point_color_unselect, Color.WHITE);
        selectColor = array.getColor(R.styleable.BannerView_point_color_select, Color.BLACK);
        proportion = array.getFloat(R.styleable.BannerView_banner_proportion, 0.6f);
        array.recycle();
    }

    /**
     * 添加ViewPager和指向器布局
     */
    private void init() {
        vp = new ViewPager(getContext());
        pointLayout = new RelativeLayout(getContext());
        addView(vp);
        addView(pointLayout);
        LayoutParams lpVp = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
        LayoutParams lp = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        lp.rightMargin = 38;
        pointLayout.setBackgroundColor(point_bg);
        vp.setLayoutParams(lpVp);
        pointLayout.setLayoutParams(lp);
    }

    /**
     * 生成圆点指示器
     */
    public void initPoint() {

        if (null == pictureList || pictureList.size() < 2) {
            return;
        }
        LinearLayout layout = new LinearLayout(getContext());
        int size = pictureList.size();
        layout.setOrientation(LinearLayout.HORIZONTAL);
        myCilcleViews = new ArrayList<>();
        for (int i = 0; i < size; i++) {
            MyCilcleView cilcleView = new MyCilcleView(getContext());
            layout.addView(cilcleView);
            LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(point_size, point_size);
            lp.setMargins(MARGIN, 0, MARGIN, 0);
            cilcleView.setLayoutParams(lp);
            if (i == 0) {
                cilcleView.drawPoint(selectColor, point_size);
            } else {
                cilcleView.drawPoint(nomalColor, point_size);
            }
            myCilcleViews.add(cilcleView);
        }
        LayoutParams lp = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        if (isRight) {
            //右侧出现
            pointLayout.addView(layout, lp);
        } else {
            pointLayout.addView(layout, lp);
        }

    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int w = MeasureSpec.getSize(widthMeasureSpec);
        int h = (int) (w * proportion);
        int count = getChildCount();
        for (int i = 0; i < count; i++) {
            View child = getChildAt(i);
            if (i == 0 && child instanceof ViewPager) {
                int hM = MeasureSpec.makeMeasureSpec(h, MeasureSpec.EXACTLY);
                child.measure(widthMeasureSpec, hM);
            } else {
                int hM = MeasureSpec.makeMeasureSpec(h, MeasureSpec.AT_MOST);
                child.measure(widthMeasureSpec, hM);
            }
        }
        //setMeasuredDimension(w, h);
        int MW = MeasureSpec.makeMeasureSpec(w,MeasureSpec.EXACTLY);
        int MH =  MeasureSpec.makeMeasureSpec(h,MeasureSpec.EXACTLY);
        super.onMeasure(MW, MH);
    }


    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        super.onLayout(changed, l, t, r, b);
        int count = getChildCount();
        for (int i = 0; i < count; i++) {
            View v = getChildAt(i);
            if (v == vp) {
                v.layout(0, 0, getMeasuredWidth(), getMeasuredHeight());
            }
            if (v == pointLayout) {
                pointLayout.layout(0, getMeasuredHeight() - pointLayout.getMeasuredHeight() - 30, getMeasuredWidth(), getMeasuredHeight());
                int c = pointLayout.getChildCount();
                if (c == 1) {
                    View view = pointLayout.getChildAt(0);
                    int w = pointLayout.getMeasuredWidth();
                    int ww = view.getMeasuredWidth();
                    int centerW = (w - ww) / 2;
                    int h = pointLayout.getMeasuredHeight();
                    int hh = view.getMeasuredHeight();
                    int centerH = (h - hh) / 2;
                    if (!isRight) {
                        view.layout(centerW, centerH, centerW + ww, centerH + hh);
                    } else {
                        view.layout(w - ww - 30, centerH, w - 30, centerH + hh);
                    }
                }
            }

        }
    }

    public void setConfig(List pictureList, boolean needStaticLocaltion, boolean isPlay, UserControal userControal) {
        removeAllViews();
        this.pictureList = pictureList;
        isNeedStaticLocaltion = needStaticLocaltion;
        this.isPlay = isPlay;
        this.userControal = userControal;
        init();
        initPoint();
        initVp();
        autoPlay();
    }

    public void notifyBanner(List pictureList) {
        removeAllViews();
        this.pictureList = pictureList;
        init();
        initPoint();
        initVp();
        autoPlay();
    }

    /**
     * 暴露的方法,开始轮播
     */
    public void autoPlay() {
        if (pictureList == null) {
            return;
        }
        if (!isPlay && pictureList.size() > 1) {
            return;
        }
        hander.sendEmptyMessageDelayed(FLAG, 3000);
    }

    private void initVp() {
        imageViews = new ArrayList<>();
        if (pictureList == null || pictureList.size() == 0) {
            if (isNeedStaticLocaltion) {
                ImageView img = new ImageView(getContext());
                img.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
                img.setImageResource(mDefaultImg);
                img.setScaleType(ImageView.ScaleType.CENTER_CROP);
                imageViews.add(img);
                initImg(0);
            } else {
                setVisibility(GONE);
                return;
            }
        } else {
            setVisibility(VISIBLE);
            int size = pictureList == null ? 0 : pictureList.size() + 1;
            if (pictureList != null && pictureList.size() == 1) {
                size = 1;
            }
            for (int i = 0; i < size; i++) {
                ImageView img = new ImageView(getContext());
                img.setImageResource(mDefaultImg);
                img.setScaleType(ImageView.ScaleType.CENTER_CROP);
                img.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
                imageViews.add(img);
                initImg(i);
            }
        }

        BannerAdapter adapter = new BannerAdapter();
        vp.setAdapter(adapter);
        vp.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

            }

            @Override
            public void onPageSelected(int position) {
                if (pictureList == null || pictureList.size() <= 1) {
                    return;
                }
                if (position == pictureList.size()) {
                    vp.setCurrentItem(0, false);
                    myCilcleViews.get(0).drawPoint(selectColor, point_size);
                    myCilcleViews.get(position - 1).drawPoint(nomalColor, point_size);
                    currentPosition = 0;
                    return;
                }
                myCilcleViews.get(currentPosition).drawPoint(nomalColor, point_size);
                myCilcleViews.get(position).drawPoint(selectColor, point_size);
                currentPosition = position;
            }

            @Override
            public void onPageScrollStateChanged(int state) {

            }
        });

        vp.setOnTouchListener(new OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {

                switch (event.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                        currentX = event.getX();
                        currentY = event.getY();
                        stop();
                        break;
                    case MotionEvent.ACTION_MOVE:
                        break;
                    case MotionEvent.ACTION_UP:
                        if (Math.max(Math.abs(currentX - event.getX()), Math.abs(currentY - event.getY())) > MINE_XY) {
                            //属于滑动了
                            autoPlay();
                        } else {
                            if (userControal != null) {
                                userControal.pageClick(currentPosition, t);
                            }
                        }
                        break;
                }
                return false;
            }
        });
    }

    private void initImg(int position) {
        if (pictureList == null || pictureList.size() == 0) {
            imageViews.get(position).setImageResource(mDefaultImg);
            return;
        }
        if (userControal != null) {
            if (position < pictureList.size()) {
                //imageViews的个数比pircture的数量多1
                userControal.initPicture(imageViews.get(position), pictureList.get(position), position);
            } else {
                userControal.initPicture(imageViews.get(position), pictureList.get(0), 0);
            }
        }
    }

    public interface UserControal {
        void initPicture(ImageView img, T t, int position);

        void pageClick(int position, T t);
    }

    class BannerAdapter extends PagerAdapter {

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

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

        @Override
        public Object instantiateItem(ViewGroup container, int position) {
            container.addView(imageViews.get(position));
            return imageViews.get(position);
        }

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

    /**
     * 暴露的方法,停止轮播
     */
    public void stop() {
        hander.removeMessages(FLAG);
    }


    /**
     * point
     */
    public class MyCilcleView extends TextView {

        private int mColor = Color.BLACK;
        private int mRadius = 7;

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

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

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

        @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
            Paint p = new Paint();
            p.setColor(mColor);
            //画笔是否实心
            p.setStyle(Paint.Style.FILL);
            //抗锯齿
            p.setAntiAlias(true);
            int mineRadius = Math.min(getWidth() / 2, getHeight() / 2);
            if (mRadius > mineRadius) {
                mRadius = mineRadius;
            }
            canvas.drawCircle(getWidth() / 2, getHeight() / 2, mRadius, p);
        }

        public void drawPoint(int mColor, int mRadius) {
            this.mColor = mColor;
            this.mRadius = mRadius;
            invalidate();
        }
    }
}

styles.xml 设置属性:

 
    
        
        
        
        
        
        
        
        
    

初始化:

 /**
     * 顶部的轮播图
     */
    private void initTopBanner() {
        bannerView.setConfig(null, true, true, new BannerView.UserControal() {
            @Override
            public void initPicture(ImageView img, IndexBannerBean.ListBean indexBannerBean, int position) {
                //显示图片
                img.setScaleType(ImageView.ScaleType.CENTER_CROP);
                Glide.with(getActivity()).load(indexBannerBean.getImage())
                        .error(R.mipmap.ic_place_banner_0_6)
                        .skipMemoryCache(true).centerCrop()
                        .into(img);
            }

            @Override
            public void pageClick(int position, IndexBannerBean.ListBean indexBannerBean) {
                //点击事件,根据自己的需求写
     
            }
        });
    }

 @Override
    public void onResume() {
        super.onResume();
        if (bannerView != null) {
            bannerView.autoPlay();
        }
    }

    @Override
    public void onStop() {
        super.onStop();
        if (bannerView != null) {
            bannerView.stop();
        }
    }

通过接口获取图片list数据之后调用下面notifyBanner方法就可以使用了: 

private List list;
//
bannerView.notifyBanner(list);

xml里面:

is_play:是否轮播

is_right:小圆点是否居右  false:居中 true:居右

is_static_location:是否在没有图片的情况下占位

point_bg:小圆点背景颜色

point_color_select:小圆点选中颜色

point_color_unselect:小圆点未选中颜色

point_size:小圆点直径

你可能感兴趣的:(【自定义view】 图片轮播+小圆点)