当前位置 : 主页 > 手机开发 > android >

Android自定义轮播图效果

来源:互联网 收集:自由互联 发布时间:2023-02-01
本文实例为大家分享了Android自定义轮播图的具体代码,供大家参考,具体内容如下 定义Banner 主要使用ViewPager实现滑动 public class Banner extends FrameLayout {    public Context context;    private

本文实例为大家分享了Android自定义轮播图的具体代码,供大家参考,具体内容如下

定义Banner

主要使用ViewPager实现滑动

public class Banner extends FrameLayout {
    public Context context;
    private @LayoutRes
    int layoutId = R.layout.banner_view;
    private View inflate;
    private ViewPager pager;
    private AutoHandler mHandler;
    private PagerAdapter adapter;
    public IndicatorView indicatorView;

    public Banner(@NonNull Context context) {
        this(context, null);
    }

    public Banner(@NonNull Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, -1);
    }

    public Banner(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context, attrs, defStyleAttr);
    }

    public void setAdapter(PagerAdapter adapter) {
        this.adapter = adapter;
        pager.setAdapter(adapter);
        indicatorView.setPager(pager);
    }

    private void init(Context context, AttributeSet attrs, int defStyleAttr) {
        this.context = context;
        inflate = LayoutInflater.from(context).inflate(layoutId, this, true);
        pager = inflate.findViewById(R.id.banner_pager);
        indicatorView = inflate.findViewById(R.id.indicatorView);

        mHandler = new AutoHandler(pager);

        mHandler.start();

    }

    public abstract static class BannerAdapter extends PagerAdapter {
        private List list;
        private Context context;

        public BannerAdapter(List list, Context context) {
            this.list = list;
            this.context = context;
        }

        @Override
        public int getCount() {
            if (null == list || list.size() == 0) {
                return 1;
            } else {
                return list.size();
            }
        }

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

        @NonNull
        @Override
        public Object instantiateItem(@NonNull ViewGroup container, int position) {
            if (getLayout() > 0) {
                View inflate = LayoutInflater.from(context).inflate(getLayout(), container, false);
                container.addView(inflate);
                setView(inflate, position);
                return inflate;
            } else {
                ImageView imageView = new ImageView(context);
                container.addView(imageView);
                if (list.size() > 0) {
                    Glide.with(context).load(list.get(position))
                            .apply(new RequestOptions().centerCrop())
                            .into(imageView);
                } else {
//                    Glide.with(context)
//                            .load(R.mipmap.ic_launcher)
//                            .apply(new RequestOptions().centerCrop())
//                            .into(imageView);
                    imageView.setBackgroundResource(R.mipmap.ic_launcher);
                }
                return imageView;
            }

        }

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

        protected abstract void setView(View inflate, int position);

        protected abstract int getLayout();

    }


}

定义定时器Handler

主要处理ViewPager的滚动 开启定时任务 ViewPager自动滚动

public class AutoHandler extends Handler {
    private ViewPager pager;
    public static int TIME = 1000 * 2;
    public boolean stopHandler;

    public AutoHandler(ViewPager pager) {
        this.pager = pager;
    }

    @Override
    public void handleMessage(@NonNull Message msg) {
        super.handleMessage(msg);
        switch (msg.what) {
            case 100:
                if (!stopHandler) {

                    sendEmptyMessageDelayed(100, TIME);

                    int position = pager.getCurrentItem() + 1;

                    if (position >= pager.getAdapter().getCount()) {
                        position = 0;
                    }
                    pager.setCurrentItem(position);

                } else {
                    removeMessages(100);
                }
                break;
            default:
                removeMessages(100);
                break;
        }
    }

    public void start() {
        stopHandler = false;
        if (!hasMessages(100)) {
            sendEmptyMessageDelayed(100, TIME);
        }
    }

    public void stop() {
        stopHandler = true;
        if (hasMessages(100)) {
            removeMessages(100);
        }
    }

}

绘制一个下标指示器

主要根据需求自行绘制 可有可无 和ViewPager关联在一起 实现联动

public class IndicatorView extends View {
    private Context context;
    private ValueAnimator valueAnimator;
    private float value;
    public int indiWidth;
    public int indiHeight;
    public int indiDivide;
    //0圆角   1直角
    public int mode;
    private int normalColor;
    private int selectColor;
    private int curPosition;
    private int count;
    private Paint paint;
    private int width;
    private int height;
    private double lastPosition;
    private ViewPager pager;
    private PagerAdapter adapter;
    private DataSetObserver dataSetObserver;

    public void setPager(final ViewPager pager) {
        this.pager = pager;
        this.adapter = pager.getAdapter();
        dataSetObserver = new DataSetObserver() {
            @Override
            public void onChanged() {
                super.onChanged();
                setCount(adapter.getCount());
                setCurPosition(pager.getCurrentItem());
            }
        };
        if (null != adapter) {
            setCount(adapter.getCount());
            setCurPosition(pager.getCurrentItem());
            adapter.registerDataSetObserver(dataSetObserver);
        }

        pager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
                lastPosition = position;
            }

            @Override
            public void onPageSelected(int position) {
                curPosition = position;
                setCurPosition(position);
            }

            @Override
            public void onPageScrollStateChanged(int state) {

            }
        });

        pager.addOnAdapterChangeListener(new ViewPager.OnAdapterChangeListener() {
            @Override
            public void onAdapterChanged(@NonNull ViewPager viewPager, @Nullable PagerAdapter oldAdapter, @Nullable PagerAdapter newAdapter) {
                if (oldAdapter != newAdapter) {
                    adapter = newAdapter;
                    setCount(adapter.getCount());
                    setCurPosition(viewPager.getCurrentItem());
                }
            }
        });
    }

    public void setCount(int count) {
        this.count = count;
        if (count <= 1) {
            setVisibility(INVISIBLE);
        }
        requestLayout();
        postInvalidate();
    }

    public void setCurPosition(int curPos) {
        /*记录上次记录*/
        //lastPos = this.curPos;
        this.curPosition = curPos;
        //postInvalidate();
        valueAnimator.start();
    }


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

    public IndicatorView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, -1);
    }

    public IndicatorView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context, attrs, defStyleAttr);
    }

    private void init(Context context, AttributeSet attrs, int defStyleAttr) {
        this.context = context;
        valueAnimator = ValueAnimator.ofFloat(0, 1f);
        valueAnimator.setDuration(200);
        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                value = (float) animation.getAnimatedValue();
                postInvalidate();
            }
        });

        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.IndicatorView);

        indiHeight = (int) typedArray.getDimension(R.styleable.IndicatorView_indi_height, getResources().getDimension(R.dimen.dp4));
        indiWidth = (int) typedArray.getDimension(R.styleable.IndicatorView_indi_width, getResources().getDimension(R.dimen.dp4));

        indiDivide = (int) typedArray.getDimension(R.styleable.IndicatorView_indi_divier, getResources().getDimension(R.dimen.dp4));

        normalColor = typedArray.getColor(R.styleable.IndicatorView_indi_color, Color.parseColor("#66dddddd"));
        selectColor = typedArray.getColor(R.styleable.IndicatorView_indi_color_select, Color.parseColor("#eedddddd"));

        mode = typedArray.getInteger(R.styleable.IndicatorView_indi_mode, 0);

        curPosition = 0;
        count = 0;

        paint = new Paint();
        paint.setAntiAlias(true);

        paint.setColor(normalColor);

    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        width = indiWidth * count + (count - 1) * indiDivide;//每个的宽度加上中间间距的宽度
        height = indiHeight;

        setMeasuredDimension(width, height);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        for (int i = 0; i < count; i++) {
            int x = i * (indiDivide + indiWidth);

            if (mode == 0) {
                paint.setColor(normalColor);
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                    canvas.drawRoundRect(x, 0, x + indiWidth, indiHeight, indiHeight / 2, indiHeight / 2, paint);
                }

                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                    if (curPosition == i) {
                        paint.setColor(selectColor);
                        if (curPosition > lastPosition) {
                            canvas.drawRoundRect(x, 0, x + value * indiWidth, indiHeight, indiHeight / 2, indiHeight / 2, paint);
                        } else {
                            canvas.drawRoundRect(x + (1 - value) * indiWidth, 0, x + indiWidth, indiHeight, indiHeight / 2, indiHeight / 2, paint);
                        }
                    }

                }

                if (mode == 1) {
                    paint.setColor(normalColor);
                    canvas.drawRect(x, 0, x + indiWidth, indiHeight, paint);


                    if (curPosition == i) {
                        paint.setColor(selectColor);

                        if (curPosition > lastPosition) {
                            canvas.drawRect(x, 0, x + value * indiWidth, indiHeight, paint);
                        } else {
                            canvas.drawRect(x + (1 - value) * indiWidth, 0, x + indiWidth, indiHeight, paint);
                        }
                    }

                }
            }
        }
    }
}

在Activity中使用

banner.setAdapter(new Banner.BannerAdapter(strings, this) {
            @Override
            protected void setView(View inflate, int position) {
                ImageView img = inflate.findViewById(R.id.img);
                Glide.with(MainActivity.this).load(strings.get(position))
                        .apply(new RequestOptions().centerCrop())
                        .into(img);
            }

            @Override
            protected int getLayout() {
                return R.layout.img;
//                return 0;
            }
});

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持自由互联。

上一篇:AndroidPickerView底部选择框实现流程详解
下一篇:没有了
网友评论