前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Android实现viewpager实现循环轮播效果

Android实现viewpager实现循环轮播效果

作者头像
砸漏
发布2020-11-04 20:24:34
1.3K0
发布2020-11-04 20:24:34
举报
文章被收录于专栏:恩蓝脚本恩蓝脚本

在网上看到很多利用viewpager实现轮播都是通过设置一个很大的值,让viewpager开始显示在这个数值区间的中间,但这种轮播个人感觉不是真正的轮播,因此自己实现了一个轮播的效果。大致思路是这样的,假如有5张图adcde是要轮播展示的,这时创建一个新的集合eadcdea,然后再让viewpager设置当前展示第一张图,也就是显示a。这样当往左滑时显示的是e,此时设置viewpager.setCurrentItem(5),当右滑到e的时候在往右滑,此时设置viewpager.setCurrentItem(1),这样就实现了轮播效果。

效果图如下所示:

话不多说上一下代码:

代码语言:javascript
复制
/**
* viewpager切换页面时动画
*/
public class MainActivity extends AppCompatActivity {
private ViewPager viewPager;
private ViewPaagerAdapter adapter;
private ArrayList<View  viewlist=new ArrayList< ();//承载图片
private ArrayList<TextView  tvList=new ArrayList< ();//底部圆点集合
private int []imgList={R.drawable.img8,R.drawable.img1,R.drawable.img2,R.drawable.img3,R.drawable.img4,R.drawable.img5,
R.drawable.img6, R.drawable.img7,R.drawable.img8,R.drawable.img1};//图片数组
boolean isStop=false;
private LinearLayout line;//小圆圈父视图
private ScheduledThreadPoolExecutor executor;
private int currentPage;
private Handler handler=new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case 1:
viewPager.setCurrentItem(msg.arg1);
break;
default:
break;
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
supportRequestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
viewPager= (ViewPager) findViewById(mybanner_viewpager);
line= (LinearLayout) findViewById(R.id.line);
setView();//设置轮播显示的底图
adapter=new ViewPaagerAdapter(this,viewlist);
viewPager.setAdapter(adapter);
viewPager.setCurrentItem(1);
viewPager.setOffscreenPageLimit(10);//加这个是为了防止第一张往左滑动会出现闪烁
startService();//启动轮播
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(final int position, float positionOffset, int positionOffsetPixels) {
Log.i("tag","位置"+position+"positionOffset"+positionOffset+"positionOffsetPixels"+positionOffsetPixels);
Log.i("tag","weizhi"+viewPager.getCurrentItem());
if (position==imgList.length-1) {
viewPager.setCurrentItem(1,false);
}else if(viewPager.getCurrentItem()==0&& positionOffsetPixels==0) {
viewPager.setCurrentItem(imgList.length-2, false);
}
currentPage=viewPager.getCurrentItem();
}
@Override
public void onPageSelected(final int position) {
Log.i("tag","位置wwwww"+position);
setEnbale();
if (position==imgList.length-1) {
tvList.get(0).setEnabled(true);
}
else if (position==0) {
tvList.get(imgList.length-3).setEnabled(true);
}
else{
tvList.get(position-1).setEnabled(true);
}
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
}
public void setView() {
LinearLayout.LayoutParams params=new LinearLayout.LayoutParams(15,15);
params.leftMargin=10;
params.rightMargin=10;
for (int i = 0; i < imgList.length; i++) {
View view= LayoutInflater.from(this).inflate(R.layout.layout,null,false);
ImageView img= (ImageView) view.findViewById(R.id.img);
img.setBackgroundResource(imgList[i]);
TextView textView= (TextView) view.findViewById(R.id.tv);
textView.setText(i+"");
viewlist.add(view);
}
for (int i = 0; i < imgList.length-2; i++) {
TextView view=new TextView(this);
view.setBackgroundResource(R.drawable.item);
view.setLayoutParams(params);
view.setEnabled(false);
line.addView(view);
tvList.add(view);
}
tvList.get(0).setEnabled(true);
}
public void setEnbale(){
for (TextView tvcycle: tvList) {
tvcycle.setEnabled(false);
}
}
/**
* 启动线程池开启循环任务
*/
public void startService(){
executor=new ScheduledThreadPoolExecutor(1);
executor.scheduleWithFixedDelay(runnable,1,2, TimeUnit.SECONDS);
}
/**
* 停止任务
*/
public void stopService(){
executor.shutdown();
}
Runnable runnable=new Runnable() {
@Override
public void run() {
currentPage=currentPage+1%10;
Message message= Message.obtain();
message.what=1;
message.arg1=currentPage;
handler.sendMessage(message);
}
};
@Override
protected void onDestroy() {
super.onDestroy();
stopService();
}
}

实现轮播的重点在这:

代码语言:javascript
复制
if (position==imgList.length-1) {
viewPager.setCurrentItem(1,false);
}else if(viewPager.getCurrentItem()==0&& positionOffsetPixels==0) {
viewPager.setCurrentItem(imgList.length-2, false);
}

这里解释一下onPageScrolled里三个参数的含义,第一个position,这个参数要特别注意一下。当用手指滑动时,如果手指按在页面上不动,position和当前页面index是一致的;如果手指向左拖动(相应页面向右翻动),这时候position大部分时间和当前页面是一致的,只有翻页成功的情况下最后一次调用才会变为目标页面;如果手指向右拖动(相应页面向左翻动),这时候position大部分时间和目标页面是一致的,只有翻页不成功的情况下最后一次调用才会变为原页面。

当直接设置setCurrentItem翻页时,如果是相邻的情况(比如现在是第二个页面,跳到第一或者第三个页面),如果页面向右翻动,大部分时间是和当前页面是一致的,只有最后才变成目标页面;如果向左翻动,position和目标页面是一致的。这和用手指拖动页面翻动是基本一致的。

如果不是相邻的情况,比如我从第一个页面跳到第三个页面,position先是0,然后逐步变成1,然后逐步变成2;我从第三个页面跳到第一个页面,position先是1,然后逐步变成0,并没有出现为2的情况。

positionOffset是当前页面滑动比例,如果页面向右翻动,这个值不断变大,最后在趋近1的情况后突变为0。如果页面向左翻动,这个值不断变小,最后变为0。positionOffsetPixels是当前页面滑动像素,变化情况和positionOffset一致。

这里采用线程池开启了一个循环任务,线程池的好处不说了,好了到此为止大概实现了viewpager的轮播了。

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

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020-09-11 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档