ViewPager实现无限循环切换和手势滑动效果
来源:互联网 发布:淘宝不能登陆 编辑:程序博客网 时间:2024/05/29 09:00
在上一次的代码中加入了无限循环的功能,这一次我详细讲解一下我的逻辑。
1.实现添加imageview 进入viewpager
a.首先写一个CusViewpage继承自ViewPager
public class CusViewpage extends ViewPager{public CusViewpage(Context context, AttributeSet attrs) {super(context, attrs);}}b.定义变量 List<ImageView> viewPagerImage和展示小点的LinearLayout
private List<ImageView> viewPagerImage; private LinearLayout dotslayout;
c.自定义OnPageChangListener,和PagerAdapter,传说ViewPager如果不传入这个两个东西就会报错,我也没试过额,有兴趣的大虾们试试后告诉我一声哈,
/** * * @author 任爱民 * 自定义的OnPageChangeListener */public class ImagePagerChangeListener implements OnPageChangeListener {/** * 1是手指滑动 * 2是结束滑动 * 0是开始滑动 */public void onPageScrollStateChanged(int n) {}public void onPageScrolled(int arg0, float arg1, int arg2) {// TODO Auto-generated method stub}public void onPageSelected(int position) {}}/** * * @author 任爱民 * 自定义的PagerAdapter */public class ImagePagerAdapter extends PagerAdapter {private List<ImageView> list;public ImagePagerAdapter(List<ImageView> list) {this.list = list;}@Overridepublic void destroyItem(View view, int index, Object arg2) {((ViewPager) view).removeView(list.get(index));}@Overridepublic void finishUpdate(View arg0) {// TODO Auto-generated method stub}@Overridepublic int getCount() {// TODO Auto-generated method stubreturn list.size();}@Overridepublic Object instantiateItem(View view, int index) {((ViewPager) view).addView(list.get(index), 0);return list.get(index);}@Overridepublic boolean isViewFromObject(View view, Object object) {// TODO Auto-generated method stubreturn view == (object);}@Overridepublic void restoreState(Parcelable arg0, ClassLoader arg1) {// TODO Auto-generated method stub}@Overridepublic Parcelable saveState() {// TODO Auto-generated method stubreturn null;}@Overridepublic void startUpdate(View arg0) {// TODO Auto-generated method stub}}d,init()方法初始化数据
public void init(List<ImageView> viewPagerImage,LinearLayout dotslayout){this.viewPagerImage = viewPagerImage;this.dotslayout = dotslayout;initImagePager();if(dotslayout != null)initDots();} /** * 初始化viewPage */ private void initImagePager() { if(viewPagerImage != null){ this.setImageStyle(); this.setAdapter(new ImagePagerAdapter(viewPagerImage)); this.setOnPageChangeListener(new ImagePagerChangeListener()); } } /** * 设置图片的一些风格 */ public void setImageStyle(){ android.widget.FrameLayout.LayoutParams viewparams = new android.widget.FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); for(ImageView imagaview:viewPagerImage){ imagaview.setLayoutParams(viewparams); //允许拉伸,填充屏幕 imagaview.setScaleType(ScaleType.FIT_XY); } } /** * 添加小点 */ // 主页面切换的小点资源id private int[] imagedotsid = { R.drawable.dotwhite, R.drawable.dotorange }; private void initDots() { //在这里为什么dots[]的长度要减2,后面我会详细说明。 dots = new ImageView[viewPagerImage.size() - 2]; for (int i = 0; i < dots.length; i++) { dots[i] = new ImageView(getContext()); dots[i].setLayoutParams(new android.widget.FrameLayout.LayoutParams(15, 15)); if (i == 0) dots[i].setImageResource(imagedotsid[1]); else dots[i].setImageResource(imagedotsid[0]); TextView tv = new TextView(getContext()); tv.setLayoutParams(new android.widget.FrameLayout.LayoutParams(10, 30)); dotslayout.addView(dots[i]); dotslayout.addView(tv); } }现在已经可以显示出PagerView了,后面我们添加图片的自动循环切换
2.现在我们实现图片的手动循环切换,并且添加点的改变
先说一下无限循环的简单逻辑, 先看图,看颜色。
如图所示,如果我要无限循环四张图片,那么我需要添加6张图片进去,第一张是要显示的第四张图片,最后一张是需要展示的第一张图片,初始化时实际是显示的第二张图片,这样我们才可以向前滑动到前一张即第四张图片,当滑动到此图时且动作完毕时,立即切换到最后一张的前一张图片,位置是list.size()-2。前后一直滑动的道理也是一样的。
其实这就是一个简单的循环逻辑,为了保留滑动动作,才加入了最前后两张图片循环。
所以我们需要传入多的两张图片,之前设置点的数量才是list.size() - 2;
所以在初始化init()方法中时,我们需要将图片的显示位置设为1
setCurrentItem(1, false);
在自定义的切换事件中,我们加入上面的逻辑代码
public class ImagePagerChangeListener implements OnPageChangeListener { /** * 1是手指滑动 * 2是结束滑动 * 0是开始滑动 */ public void onPageScrollStateChanged(int n) { //这里是加入的代码 if(n == 0){ if(dotint == 0){ setCurrentItem(viewPagerImage.size()-2, false); }else if(dotint == viewPagerImage.size()-1){ setCurrentItem(1, false); } } }
a,实现改变的点的方法。
/** * 改变小点 */ // 记录现在的原点位置 private int dotint = 0; //记录原点应该显示的位置 private int dotprint = 0 ; // 图片的位置 private static int imagemoveid = 1; private void changedot(int dotintnew) { if(dots != null){dots[dotprint].setImageResource(imagedotsid[0]);if(dotintnew == 0){dotprint = viewPagerImage.size() - 3;}else if(dotintnew == viewPagerImage.size() - 1){dotprint = 0;}else{dotprint = dotintnew - 1;}dots[dotprint].setImageResource(imagedotsid[1]);imagemoveid = dotintnew;dotint = dotintnew; }}
b.在切换图片时,会响应OnPageChangeListener事件,所以我们在自定义的OnPageChangeListener中加入改变小点的方法
public void onPageSelected(int position) {// 改变小点if(dotslayout != null)changedot(position);}
现在我们已经实现了手动无线循环切换的pagerview,
3.实现自动无限切换图片
这里我先说明一个问题,我在实现这个功能的时候,开始是用的定时器Timer,过0.4秒就滑动一次。实现以后,在配合手动切换时,会出现,手动滑动一张图片后,立马就会自动切换到下一张图,这样的体验不是很好。后面我又改为线程去解决这个问题,每次手滑以后就重设线程,并设置0.1秒检测一次时候是否正在滑动.
a.创建滑动的线程
/** * 自动切换 创建线程 */ public boolean isMove = true; private Handler switcherHandler; //自动切换的时间 private int timelong = 40; //消息int private int message = 0x123; //给线程唯一性加锁 public static boolean isHaveLoop = true; private void startLoop() { new Thread() { public void run() { //表示已经有Loop开始运行 isHaveLoop = true; try {// 如果移动了则休眠四秒钟 //将检测ismove提高到0.1秒检测一次 int time = 0; while (isMove) { Thread.sleep(100); if(time++ >= timelong){ switcherHandler.sendEmptyMessage(message); time = 0; } } } catch (InterruptedException e) { e.printStackTrace(); } //表示Loop运行结束 isHaveLoop = false; }; }.start(); }
b.在init()初始化时,启动线程,并且在主线程中改变PagerView的位置
/** * 设置广告图片切换的计时器 */private void setSwitcherImage() {switcherHandler = new Handler() {@Overridepublic void handleMessage(Message msg) {if (msg.what == message && isMove) {int m = ++imagemoveid % (viewPagerImage.size());setCurrentItem(m);}super.handleMessage(msg);}};startLoop();}在init()中执行这个方法。
setSwitcherImage();c.重写onTouch()方法,检测触控事件,每次手动滑动时,都应该重开线程。
/** * 检测是否手势滑动 * 如果有收手势滑动则取消Loop线程,滑动结束后重新建立Loop线程 */ @Overridepublic boolean onTouchEvent(MotionEvent arg0) {if(arg0.getAction() == MotionEvent.ACTION_DOWN||arg0.getAction()==arg0.ACTION_MOVE){isMove = false;}else if(arg0.getAction() == MotionEvent.ACTION_UP){isMove =true;//如果不存在loop后,可以再次创建loopif(!isHaveLoop){ startLoop();}}else{isMove = true;if(!isHaveLoop){ startLoop();}}return super.onTouchEvent(arg0);}4.测试。
我们放入布局文件
activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" > <aimin.myviewpager.CusViewpage android:id="@+id/cusviewpage" android:layout_width="match_parent" android:layout_height="300dp" > </aimin.myviewpager.CusViewpage> <LinearLayout android:id="@+id/dots" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_marginTop="280dp" android:layout_marginRight="30dp" android:gravity="right" android:orientation="horizontal" > </LinearLayout></RelativeLayout>
在主activity中初始化
import java.util.ArrayList;import java.util.List;import aimin.myviewpager.CusViewpage;import android.app.Activity;import android.os.Bundle;import android.widget.ImageView;import android.widget.LinearLayout;public class MainActivity extends Activity {private CusViewpage imageSwitchertitle;private LinearLayout dotLayout;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);imageSwitchertitle = (CusViewpage) findViewById(R.id.cusviewpage);dotLayout = (LinearLayout) findViewById(R.id.dots);imageSwitchertitle.init(getTestImageView(),dotLayout);}/** * * @return测试用的List<ImageView> */public List<ImageView> getTestImageView(){List<ImageView> imageview = new ArrayList<ImageView>();ImageView imageviewfourq = new ImageView(this);imageviewfourq.setImageResource(R.drawable.title_four);ImageView imageviewone = new ImageView(this);imageviewone.setImageResource(R.drawable.title_one);ImageView imageviewtwo = new ImageView(this);imageviewtwo.setImageResource(R.drawable.title_two);ImageView imageviewthree = new ImageView(this);imageviewthree.setImageResource(R.drawable.title_three);ImageView imageviewfour = new ImageView(this);imageviewfour.setImageResource(R.drawable.title_four);ImageView imageviewoneh = new ImageView(this);imageviewoneh.setImageResource(R.drawable.title_one);imageview.add(imageviewfourq);imageview.add(imageviewone);imageview.add(imageviewtwo);imageview.add(imageviewthree);imageview.add(imageviewfour);imageview.add(imageviewoneh);return imageview;}/** * 初始化CusViewpage */}
运行截图:
缺陷:
1.但是依然有不足之处,init方法初始化List<ImageView> viewPagerImage时,需要传入一定顺序的Imageview(即在最前和最后加入最后和最前的脱)。但这并不是我们想要的,我尝试过在init()中,将List<ImageView> viewPagerImage添加上首尾图片,但只能添加引用,在VIewpager换图时报错,ImageView又不能被复制对象(其实也可以做到复制,需要重写ImagerVIew的copy()方法吧,我觉得太麻烦了,有兴趣的同学可以试试),我只好在传入时先构造了一定顺序的list。
2.不能动态添加图片.
- ViewPager实现无限循环切换和手势滑动效果
- 封装自定义ViewPager实现左右自动切换和手势滑动效果
- Android ViewPager 实现无限循环滑动
- ViewPager实现左右无限循环滑动
- Android ViewPager实现无限循环滑动
- 实现viewpager的无限滑动效果
- ViewPager实现自动无限循环切换
- ViewPager实现多页面滑动切换和动画效果
- android viewpager 无限循环实现gallery 效果
- ViewPager实现左右无限循环效果
- ViewPager实现左右无限循环效果
- 用最简单的方法实现ViewPager无限循环滑动(跑马灯)效果
- 使用ViewPager和Fragment同时实现点击底部Tab切换和手势滑动切换Fragment
- viewpager实现循环滑动(左右无限循环)
- viewpager+Fragment实现简单滑动切换效果
- ViewPager 实现无限滑动
- ViewPager自动无限循环滑动
- Android之ViewPager+Fragment实现页面点击切换和手势滑动
- MySQL 面试题目
- Spring MVC学习-------------访问到静态的文件
- ubuntu 搭建 erlang 环境
- java 值传递 引用传递的理解 言简意赅 一字千金
- HDU 2818 Building Block (并查集)
- ViewPager实现无限循环切换和手势滑动效果
- QWidget: must construct a QApplication before a QPaintDevice问题解决方法
- 基础问答
- 网络请求之GET、POST请求
- leetcode 061 —— Rotate List
- Android之——自定义复合控件的实现
- 安装tomcat服务
- JSVM使用简介
- 自定义PUSH POP跳转动画