完美无限滚动轮播图 +小圆点解决方案

该博客介绍了如何通过在ViewPager中添加额外的View来创建一个无限滚动轮播图,并配合小圆点指示器。关键在于初始化adapter时添加额外的视图,并在轮播到首尾时进行无动画跳转,从而达到无缝滚动的效果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这段时间找了很多资料, 经过实践, 终于完成了一个完美的无限滚动轮播图, 话不多说, 直接上代码

界面代码如下 简单明了: 一个ViewPager +小圆点的容器
    <RelativeLayout
                android:id="@+id/rev_adlist"
                android:layout_width="match_parent"
                android:layout_height="110dp"
                android:layout_marginBottom="15dp"
                android:visibility="gone">

                <android.support.v4.view.ViewPager
                    android:id="@+id/vp_adlist"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent" />

                <LinearLayout
                    android:id="@+id/lin_adpoint"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_alignParentBottom="true"
                    android:layout_marginBottom="5dp"
                    android:layout_marginLeft="7dp"
                    android:orientation="horizontal" />
            </RelativeLayout>

public AdAdapter(Context context, List<AdListResponse.ValueBean> valueBeen) {
        mContext = context;
        this.valueBeen = valueBeen;
        LayoutInflater inflater = LayoutInflater.from(mContext);

        views = new ArrayList<>();
        if (valueBeen.size() == 0)
            return;
        if (valueBeen.size() == 1) {
            View inflate = inflater.inflate(R.layout.item_recycle_vp, null);
            views.add(inflate);
        } else {
            for (int i = 0; i < valueBeen.size() + 2; i++) {
                View inflate = inflater.inflate(R.layout.item_recycle_vp, null);
                views.add(inflate);
            }
        }

    }
    @Override
    public int getCount() {
        return valueBeen.size() > 1 ? valueBeen.size() + 2 : 1;
    }
adapter重点就是这个 在初始化adapter的时候 多添加两个View, 同时判断了轮播图个数是否大于1 (1个的时候也就没必要了对吧)

ViewPager 监听代码, 同时添加小圆点

for (int i = 0; i < valueBeen.size(); i++) {
            ImageView imgPoint = (ImageView) 
//添加小圆点            LayoutInflater.from(getContext()).inflate(R.layout.item_point, null);
            linAdpoint.addView(imgPoint);
        }
        //设置第一个小圆点为选中状态
        ((ImageView) linAdpoint.getChildAt(0)).setImageResource(R.mipmap.sel_point);
        adAdapter = new AdAdapter(getContext(), valueBeen);
        vpAdlist.setAdapter(adAdapter);
        vpAdlist.setCurrentItem(1, false);
        vpAdlist.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
            }

            @Override
            public void onPageSelected(int position) {
                for (int i = 0; i < valueBeen.size(); i++) {
                    ((ImageView) linAdpoint.getChildAt(i)).setImageResource(R.mipmap.unsel_point);
                }
                if (position == 0) {
                    ((ImageView) linAdpoint.getChildAt(valueBeen.size() - 1)).setImageResource(R.mipmap.sel_point);
                } else if (position == valueBeen.size() + 1) {
                    ((ImageView) linAdpoint.getChildAt(0)).setImageResource(R.mipmap.sel_point);
                } else {
                    ((ImageView) linAdpoint.getChildAt(position - 1)).setImageResource(R.mipmap.sel_point);
                }
            }

            @Override
            public void onPageScrollStateChanged(int state) {
                if (state == ViewPager.SCROLL_STATE_IDLE) {
                    handleSetCurrentItem(vpAdlist.getCurrentItem());
                }
            }

            private void handleSetCurrentItem(int position) {
                final int lastPosition = vpAdlist.getAdapter().getCount() - 1;
                if (position == 0) {
                    vpAdlist.setCurrentItem(lastPosition == 0 ? 0 : lastPosition - 1, false);
                } else if (position == lastPosition) {
                    vpAdlist.setCurrentItem(1, false);
                }
            }
        });

        vpAdlist.setOnTouchListener((v, event) -> {
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    if (handler != null)
                        handler.removeCallbacksAndMessages(null);
                    break;
                case MotionEvent.ACTION_CANCEL:
                case MotionEvent.ACTION_UP:
                    if (handler != null)
                        handler.sendEmptyMessageDelayed(100, 3000);
                    break;
            }
            return false;
        });
        //开启定时任务 3秒钟自动轮播一次
        if (handler != null)
            handler.sendEmptyMessageDelayed(100, 3000);
handler代码
    private Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case 100:
                    int count = adAdapter.getCount();
                    /**
                     * 解决自动翻页 动画问题
                     */
                    if (count > 2) { // 实际上,多于1个,就多于3个
                        int position = vpAdlist.getCurrentItem();
                        final int lastPosition = vpAdlist.getAdapter().getCount() - 1;
                        if (position == 0) {
                            vpAdlist.setCurrentItem(1, false);
                        } else if (position == lastPosition) {
                            vpAdlist.setCurrentItem(2, false);
                        }else {
                            vpAdlist.setCurrentItem(position+1, true);
                        }
                        handler.sendEmptyMessageDelayed(100, 3000);

                    }
                    break;
            }
        }
    };

代码分享到此结束, 重要部分都贴出来了, 看一下大概就明白了, 原理很简单: 在轮播图前边 加一个View 展示的是最后一张轮播图, 最后边加一个View 展示的是第一张轮播图, 在跳到头和尾这两个的时候 做相应的无动画跳转, ok 完美

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值