重复造轮子--自定义轮播图banner

项目大版本更新,设计给了新的效果图,其中banner换成了如下图所示。两头都要留一点出来。哈罗单车也有类似的banner。可以设置中间的图片比两边大。


重复造轮子--自定义轮播图banner_第1张图片
效果图截图.png

大概构思:自定义FrameLayout,然后轮播图和指示器(就是小圆点)都用RecyclerView实现。

文字能力太差,还是上代码吧。
1.自定义属性

        
        
        
        
        
        
        
    

interval:自动轮播的间隔时间。
showIndicator:是否显示指示器小圆点。
orientation:轮播方向(水平、竖直)。
autoPlaying:是否自动轮播。
itemSpace:两个banner之间的间距
centerScale:中间banner的倍数(设置为1.0就是一样大)。
moveSpeed:轮播图的移动速度。

2.初始化属性。
public class BannerLayout extends FrameLayout {
//省略部分代码
    public BannerLayout(Context context) {
        this(context, null);
    }

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

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

    private void initView(Context context, AttributeSet attrs) {
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.BannerLayout);
        showIndicator = typedArray.getBoolean(R.styleable.BannerLayout_showIndicator, true);
        autoPlayDuration = typedArray.getInt(R.styleable.BannerLayout_interval, 4000);
        isAutoPlaying = typedArray.getBoolean(R.styleable.BannerLayout_autoPlaying, true);
        itemSpace = typedArray.getInt(R.styleable.BannerLayout_itemSpace, 30);
        //设置为1.0就是两边的图跟中间的一样高度,设置1.2就是两边的图比中间的图小一点
        centerScale = typedArray.getFloat(R.styleable.BannerLayout_centerScale, 1.2f);
        moveSpeed = typedArray.getFloat(R.styleable.BannerLayout_moveSpeed, 1.0f);
  }
}
3.绘制小圆点
  if (mSelectedDrawable == null) {
            //绘制默认选中状态图形
            GradientDrawable selectedGradientDrawable = new GradientDrawable();
            selectedGradientDrawable.setShape(GradientDrawable.OVAL);
            selectedGradientDrawable.setColor(Color.RED);
            selectedGradientDrawable.setSize(dp2px(5), dp2px(5));
            selectedGradientDrawable.setCornerRadius(dp2px(5) / 2);
            mSelectedDrawable = new LayerDrawable(new Drawable[]{selectedGradientDrawable});
        }
        if (mUnselectedDrawable == null) {
            //绘制默认未选中状态图形
            GradientDrawable unSelectedGradientDrawable = new GradientDrawable();
            unSelectedGradientDrawable.setShape(GradientDrawable.OVAL);
            unSelectedGradientDrawable.setColor(Color.GRAY);
            unSelectedGradientDrawable.setSize(dp2px(5), dp2px(5));
            unSelectedGradientDrawable.setCornerRadius(dp2px(5) / 2);
            mUnselectedDrawable = new LayerDrawable(new Drawable[]{unSelectedGradientDrawable});
        }
4.轮播图与指示器
   //轮播图部分
        mRecyclerView = new RecyclerView(context);
        LayoutParams vpLayoutParams = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                ViewGroup.LayoutParams.MATCH_PARENT);
        addView(mRecyclerView, vpLayoutParams);
        mLayoutManager = new BannerLayoutManager(getContext(), orientation);
        mLayoutManager.setItemSpace(itemSpace);
        mLayoutManager.setCenterScale(centerScale);
        mLayoutManager.setMoveSpeed(moveSpeed);
        mRecyclerView.setLayoutManager(mLayoutManager);
        new CenterSnapHelper().attachToRecyclerView(mRecyclerView);

        //指示器部分
        indicatorContainer = new RecyclerView(context);
        LinearLayoutManager indicatorLayoutManager = new LinearLayoutManager(context, orientation, false);
        indicatorContainer.setLayoutManager(indicatorLayoutManager);
        indicatorAdapter = new IndicatorAdapter();
        indicatorContainer.setAdapter(indicatorAdapter);
        LayoutParams params = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
                ViewGroup.LayoutParams.WRAP_CONTENT);
        params.gravity = Gravity.BOTTOM | gravity;
        params.setMargins(marginLeft, 0, marginRight, marginBottom);
        addView(indicatorContainer, params);
        if (!showIndicator) {
            indicatorContainer.setVisibility(GONE);
        }
5.轮播图小圆点的适配器
protected class IndicatorAdapter extends RecyclerView.Adapter {

        int currentPosition = 0;

        public void setPosition(int currentPosition) {
            this.currentPosition = currentPosition;
        }

        @Override
        public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

            ImageView bannerPoint = new ImageView(getContext());
            RecyclerView.LayoutParams lp = new RecyclerView.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
                    ViewGroup.LayoutParams.WRAP_CONTENT);
            lp.setMargins(indicatorMargin, indicatorMargin, indicatorMargin, indicatorMargin);
            bannerPoint.setLayoutParams(lp);
            return new RecyclerView.ViewHolder(bannerPoint) {
            };
        }

        @Override
        public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
            ImageView bannerPoint = (ImageView) holder.itemView;
            bannerPoint.setImageDrawable(currentPosition == position ? mSelectedDrawable : mUnselectedDrawable);

        }

        @Override
        public int getItemCount() {
            return bannerSize;
        }
    }
6.测试的demo(后续会放到百度网盘供下载查看)

链接:https://pan.baidu.com/s/1mH8KxWCWYv8DDGgB3qfmJg 密码:2eig

7.其中的代码,很大一部分是参考github上几个项目的(有国人的,有外国的),只是需求满足不了我,略作部分修改。感谢。

你可能感兴趣的:(重复造轮子--自定义轮播图banner)