Android自定义轮播图效果

 更新时间:2022年08月15日 17:10:13   作者:吹着空调哼着歌  
这篇文章主要为大家详细介绍了Android自定义轮播图效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

本文实例为大家分享了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;
            }
});

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

相关文章

  • Android基础之获取LinearLayout的宽高

    Android基础之获取LinearLayout的宽高

    LinearLayout是线性布局控件,它包含的子控件将以横向或竖向的方式排列,按照相对位置来排列所有的widgets或者其他的containers,超过边界时,某些控件将缺失或消失。有的时候,我们需要想获取LinearLayout宽高,下面通过这篇文章来跟着小编一起学习学习吧。
    2016-11-11
  • Kotlin与Java相互调用的完整实例

    Kotlin与Java相互调用的完整实例

    Kotlin的设计过程中就考虑到了与Java的互操作性,在Kotlin中可以直接调用既有的Java代码,反过来在Java中也可以很流畅地使用Kotlin代码,这篇文章主要给大家介绍了关于Kotlin与Java相互调用的相关资料,需要的朋友可以参考下
    2021-12-12
  • Android编程实现通讯录中联系人的读取,查询,添加功能示例

    Android编程实现通讯录中联系人的读取,查询,添加功能示例

    这篇文章主要介绍了Android编程实现通讯录中联系人的读取,查询,添加功能,涉及Android权限控制及通讯录相关操作技巧,需要的朋友可以参考下
    2017-07-07
  • android studio 3.4配置Android -jni 开发基础的教程详解

    android studio 3.4配置Android -jni 开发基础的教程详解

    这篇文章主要介绍了android studio 3.4配置Android -jni 开发基础,本文图文并茂给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2019-09-09
  • Android启动屏实现左右滑动切换查看功能

    Android启动屏实现左右滑动切换查看功能

    这篇文章主要介绍了Android启动屏实现左右滑动切换查看功能的相关资料,针对新功能属性介绍和启动屏进行详细讲解,感兴趣的小伙伴们可以参考一下
    2016-01-01
  • Flutter 枚举值enum和int互相转化总结

    Flutter 枚举值enum和int互相转化总结

    这篇文章主要为大家介绍了Flutter 枚举值enum和int互相转化总结分析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-02-02
  • Android实现悬浮窗的简单方法实例

    Android实现悬浮窗的简单方法实例

    相信大家应该也都发现了,现在很多应用都使用到悬浮窗,例如微信在视频的时候,点击Home键,视频小窗口仍然会在屏幕上显示,下面这篇文章主要给大家介绍了关于Android实现悬浮窗的简单方法,需要的朋友可以参考下
    2021-09-09
  • Android自定义Gradle插件的详细过程

    Android自定义Gradle插件的详细过程

    Groovy语言是一种jvm语言,最终也是编译成class文件然后在jvm上执行,所以所有的Java语言的特性Groovy都支持,我们可以完全混写Java和Groovy,对Android自定义Gradle插件相关知识,感兴趣的朋友跟随小编一起看看吧
    2021-07-07
  • 利用Android实现光影流动特效的方法详解

    利用Android实现光影流动特效的方法详解

    Flutter 的画笔类 Paint 提供了很多图形绘制的配置属性,来供我们绘制更丰富多彩的图形。本篇我们引入一个 Paint 类新的属性:maskFilter,再结合之前的 shader 和动画,制作出光影流动特效,感兴趣的可以尝试一下
    2022-07-07
  • Android ImageView Src 和Background 区别

    Android ImageView Src 和Background 区别

    这篇文章主要介绍了Android ImageView Src 和Background 区别的相关资料,需要的朋友可以参考下
    2016-09-09

最新评论