Android ViewPager导航小圆点实现无限循环效果
作者:flowerff 发布时间:2022-07-09 13:10:33
标签:ViewPager,导航,无限循环
之前用View Pager做了一个图片切换的推荐栏(就类似与淘宝、头条客户端顶端的推荐信息栏),利用View Pager很快就能实现,但是一次无意间使用淘宝APP的时候,突然发现它的效果和我做的还不一样,淘宝APP的推荐栏可以左右无限循环切换,而ViewPager自身其实并没有支持这个功能。
其实实现这个无限循环不难,只需要在数据源的首尾各添加一张多余的图片,在onPagerChangeListener()中监听position<1和position>(总数据条目-1)就可以了。另外一点需要注意的是,这里的数据源+2,而导航小圆点却比数据源少2,这样在无限循环的时候,小圆点的切换就不好办了。本人最开始也是写逻辑在onPageSelected()里面判断条件,总感觉挺麻烦的,有没有更好的实现方式呢。答案是肯定的。只需将小圆点也首尾各家一个,并设置为invisible不就好了?
我的代码实现如下:
xml布局:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v4.view.ViewPager
android:id="@+id/vp_homepage"
android:layout_width="match_parent"
android:layout_height="match_parent"
></android.support.v4.view.ViewPager>
<LinearLayout
android:id="@+id/ll_dots_homepage_top"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_marginBottom="8dp"
android:gravity="center"
android:orientation="horizontal">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clickable="true"
android:padding="5dp"
android:visibility="invisible"
android:src="@drawable/dots"/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clickable="true"
android:padding="5dp"
android:src="@drawable/dots"/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clickable="true"
android:padding="5dp"
android:src="@drawable/dots"/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clickable="true"
android:padding="5dp"
android:src="@drawable/dots"/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clickable="true"
android:padding="5dp"
android:src="@drawable/dots"/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clickable="true"
android:padding="5dp"
android:visibility="invisible"
android:src="@drawable/dots"/>
</LinearLayout>
</RelativeLayout>
界面实现:
public class HomePageFragment extends BaseFragment {
private View view;
private ViewPager mViewPager;//顶部信息推荐栏
private MyViewPagerAdapter mViewPagerAdapter;
private LinearLayout ll_dots_homepage_top;//顶部信息推荐栏导航点
private int GUIDE_NUMBER = 4; //顶部信息推荐栏的数量
private ImageView[] dotImages; //顶部信息推荐栏引导小圆点
private int dotCurrentIndex; //顶部信息推荐栏小圆点偏移量
private MyOnPageChangeListener mOnPageChangeListener;
private List<View> mListDataViewPage;
private Context context;
@Override
public void onAttach(Context context) {
super.onAttach(context);
this.context = context;
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable
Bundle savedInstanceState) {
view = inflater.inflate(R.layout.frament_homepage, container, false);
initData();
initView();
return view;
}
/**
* 初始化一些基础数据
*/
private void initData() {
if (mListDataViewPage != null) {
mListDataViewPage.clear();
mListDataViewPage = null;
} else {
mListDataViewPage = new ArrayList<>();
// 为了实现无限循环,首位两张图片都是重复的
int[] resource = new int[]{
R.drawable.test_viewpager_homepage_4, R.drawable.test_viewpager_homepage_1, R.drawable.test_viewpager_homepage_2, R
.drawable.test_viewpager_homepage_3, R.drawable.test_viewpager_homepage_4,R.drawable.test_viewpager_homepage_1,};
for (int i = 0; i < 6; i++) {
WeakReference<Bitmap> bitmao = new WeakReference<Bitmap>(BitmapFactory
.decodeResource(getResources(), resource[i]));
ImageView imageView = new ImageView(context);
imageView.setImageBitmap(bitmao.get());
imageView.setScaleType(ImageView.ScaleType.FIT_XY);
mListDataViewPage.add(imageView);
}
}
}
/**
* 初始化底部推信息推荐栏引导小圆点View
*/
private void initDots() {
dotImages = new ImageView[mListDataViewPage.size()];
for (int i = 0; i < mListDataViewPage.size(); i++) {
dotImages[i] = (ImageView) ll_dots_homepage_top.getChildAt(i);
dotImages[i].setEnabled(false);
}
**//将第一个小圆点设置为高亮,这里的第一个偏移量是1,不是0
dotImages[1].setEnabled(true);
dotCurrentIndex = 1;**
}
/**
* initView
*/
private void initView() {
findLayout();
findView();
}
/**
* findLayout
*/
private void findLayout() {
ll_dots_homepage_top = (LinearLayout) view.findViewById(R.id.ll_dots_homepage_top);
initDots();
}
/**
* 初始化控件
*/
private void findView() {
mViewPager = (ViewPager) view.findViewById(R.id.vp_homepage);
mViewPagerAdapter = new MyViewPagerAdapter(mListDataViewPage);
mOnPageChangeListener = new MyOnPageChangeListener();
mViewPager.setAdapter(mViewPagerAdapter);
mViewPager.setOnPageChangeListener(mOnPageChangeListener);
**mViewPager.setCurrentItem(1,false); //默认选中第二张图片**
}
private class MyOnPageChangeListener implements ViewPager.OnPageChangeListener {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
if (position < 0 || position > mListDataViewPage.size() || position == dotCurrentIndex) {
return;
}
if ( mListDataViewPage.size() > 1) { //多于1,才会循环跳转
if ( position < 1) { //首位之前,跳转到末尾(N)
position = 4;
mViewPager.setCurrentItem(position,false);
} else if ( position > 4) { //末位之后,跳转到首位(1)
position = 1;
mViewPager.setCurrentItem(position,false); //false:不显示跳转过程的动画
}else {
dotImages[dotCurrentIndex].setEnabled(false);
dotImages[position].setEnabled(true);
dotCurrentIndex = position;
}
}
}
@Override
public void onPageScrollStateChanged(int state) {
}
}
}
注意代码中加粗的代码。初始的小圆点选中和ViewPager的position选中。
来源:http://blog.csdn.net/flowerff/article/details/77429618


猜你喜欢
- 这个问题困扰了很久,有些类不是controller在使用autowired注入的类显示为空,找到网上的方法是在类初始化时主动注入被Autow
- 本文实例讲述了C#使用GZipStream解压缩数据文件的方法。分享给大家供大家参考。具体分析如下:GZipStream用于从一个流读取数据
- JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式,采用完全独立于语言的文本格式,是理想的数据交换
- springboot项目启动,初始化方法加载参数今天我看到项目中用到了 @PostConstruct 这个注解,之前没看到过,特地查了一下,
- 最近项目进行适配的时候发现部分(如华为手机)存在底部虚拟按键的手机会因为虚拟按键的存在导致挡住部分界面,因为需要全屏显示,故调用虚拟按键隐藏
- 1. 效果图展示2. 工程目录结构注意: webapp下的resources目录放置easyui和js(jQuery文件是另外的) 
- 本文实例讲述了Android编程单选项框RadioGroup用法。分享给大家供大家参考,具体如下:今天介绍的是RadioGroup 的组事件
- 本文实例为大家分享了Android实现蓝牙原理代码,供大家参考,具体内容如下package com.example.se7en.testbl
- 今天做项目的时候,遇到一个问题,如果我调用某个服务的接口,但是这个服务挂了,同时业务要求这个接口的结果是必须的,那我该怎么办呢,答案是通过h
- 一、HandlerThread的介绍及使用举例  
- 前言:需求是这样的,在与第三方对接过程中,对方提供了token进行时效性验证,过一段时间token就会失效.后台有定时任务在获取,但是偶尔会
- 1,IDEA中Lombok作用数据库: 库 表 字段 对应的值 user表(id,name,age)实体对象pojo: 用来封装数据库中的数
- 前言这是上周在开发 C# 中使用 Proxy 代理时开发的一些思考和实践。主要需求是这样的,用户可以配置每次请求是否需要代理,用户可以配置
- 1、String类1.1两种对象实例化方式对于String在之前已经学习过了基本使用,就是表示字符串,那么当时使用的形式采取了直接赋值:pu
- 方式一 通过Map.keySet使用iterator遍历@Testpublic void testHashMap1() { Map<I
- 本文实例为大家分享了java斗地主发牌的具体代码,供大家参考,具体内容如下分析这是一个模仿斗地主发牌的例子;按照斗地主的规则,完成洗牌发牌的
- 1、修改application.properties新建 Mapper、实体类 相应的文件夹,将不同数据源的文件保存到对应的文件夹下# te
- KMP算法是一种神奇的字符串匹配算法,在对 超长字符串 进行模板匹配的时候比暴力匹配法的效率会高不少。接下来我们从思路入手理解KMP算法。在
- C语言字符串大小比较#include <stdio.h>#include <string.h>int fun(cha
- 1. Dom概述Dom方式创建XML,应用了标准xml构造器 javax.xml.parsers.DocumentBuilder 来创建 X