ViewPager加载页面,底部圆点指示器,圆点拖动效果,支持手势拖动

来源:互联网 发布:php培训 编辑:程序博客网 时间:2024/04/30 19:44

效果概述:

  • 随着viewpager中页面的滑动,底部的圆点也有拖动效果,支持手势拖动

效果图如下:

这里写图片描述

实现原理:

  • ViewPager 无限轮播,设置了Integer.MAX_VALUE ; 其实也可以设置为前一张后一张,不过麻烦点儿
  • 根据ViewPager中图片个数不同,底部显示不同个数的圆点
  • 动态加载圆点的同时,记录下圆点的位置,放于集合中
  • ViewPager 的setOnPageChangeListener监听,用于设置ViewPager的页面切换时,圆点的动画效果
  • 支持手势拖动

遇到的问题

  1. 装载圆点的layout在onCreate()中未立即装载,需要动态获取圆点位置的方法失败

    解决办法: 网上有说其他的方法;我是直接开了子线程,睡了500ms

  2. 手势拖动,使用handler,但会触发setOnPageChangeListener监听,导致立即切换到下一个图片,特别不友好

    解决办法:onPageScrollStateChanged方法中判断,状态为1(开始滑动)的时候,hanlder移除掉所有的消息,然后5s后重发消息

    3 . 手势拖动,右滑的时候,圆点的移动效果和左滑不同

    解决办法:根据当前position判断左滑/右滑(我使用的是Integer.MAX_VALUE),设置不同的动画

核心代码

/*
暴漏出去的item点击事件接口:OnPagerItemClickListnener
需要传递的参数:
item 个数
List
Circle 形状,颜色【包括normal和select】
轮播时间间隔

    viewpager加载前图片,加载失败图片

*/

public class MainActivity extends AppCompatActivity {

private ViewPager pager;private LinearLayout layout;private List<String> urlList=new ArrayList<>();private List<Integer> posList=new ArrayList<>();private boolean once=true;private TextView circle;private PagerAdapter adapter;private RelativeLayout main_layout;private int preItemPos=0;private boolean right;@Overrideprotected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_main);    pager = (ViewPager) findViewById(R.id.viewPager);    layout = (LinearLayout) findViewById(R.id.circleLayout);    main_layout = (RelativeLayout) findViewById(R.id.activity_main);    //传入参数为5;传入的url集合为urlList;间隔时间为500ms;传入默认颜色为白,移动颜色为红    final LinearLayout.LayoutParams params=new LinearLayout.LayoutParams(5,5,1);    params.setMargins(5,0,5,0);    for (int i = 0; i < 5; i++) {        TextView circle=(TextView) LayoutInflater.from(this).inflate(R.layout.circle, null);        circle.setLayoutParams(params);        layout.addView(circle);    }    circle = (TextView) LayoutInflater.from(this).inflate(R.layout.circle, null);    RelativeLayout.LayoutParams params1=new RelativeLayout.LayoutParams(5,5);    circle.setLayoutParams(params1);    circle.setBackgroundDrawable(getResources().getDrawable(R.drawable.circle_rotate));    main_layout.addView(circle);    urlList.add("http://img0.imgtn.bdimg.com/it/u=3508535310,2065429756&fm=21&gp=0.jpg");    urlList.add("http://img5.imgtn.bdimg.com/it/u=646811362,1303793773&fm=21&gp=0.jpg");    urlList.add("http://imgsrc.baidu.com/baike/pic/item/0d72994497e8a063510ffee5.jpg");    urlList.add("http://img0.imgtn.bdimg.com/it/u=1342487761,3658569123&fm=21&gp=0.jpg");    urlList.add("http://img1.imgtn.bdimg.com/it/u=2656478986,1405599153&fm=21&gp=0.jpg");    new Thread(new Runnable() {        @Override        public void run() {            try {                Thread.sleep(500);                for (int i = 0; i < layout.getChildCount(); i++) {                    if (once){                        posList.add(layout.getTop());                        posList.add(layout.getLeft());                        once=false;                    }                    posList.add(layout.getChildAt(i).getLeft());                }                runOnUiThread(new Runnable() {                    @Override                    public void run() {                        adapter = new PagerAdapter(MainActivity.this, new tmpListener(), urlList);                        pager.setCurrentItem(Integer.MAX_VALUE/2-Integer.MAX_VALUE/2%urlList.size());                        pager.setAdapter(adapter);                        circle.setTop(posList.get(0));                        circle.setLeft(posList.get(1)+posList.get(2));                        myHandler.sendEmptyMessageDelayed(100,1000);                        pager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {                            @Override                            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {                            }                            @Override                            public void onPageSelected(int position) {                                myHandler.sendEmptyMessageDelayed(100,2000);                                right=position>preItemPos?true:false;                                preItemPos=position;                                position%=urlList.size();                                //圆点的移动                                AnimationSet animationSet=new AnimationSet(true);                                Animation animation;                                if (position==0){                                    if (right)animation=setAnim(posList.get(2)-5,posList.get(2));                                    else animation=setAnim(posList.get(position+3),posList.get(position+2));                                }                                else {                                    if (right)animation=setAnim(posList.get(position+1),posList.get(position+2));                                    else{                                        if (position==urlList.size()-1)animation=setAnim(posList.get(posList.size()-1)+5,posList.get(posList.size()-1));                                        else animation=setAnim(posList.get(position+3),posList.get(position+2));                                    }                                }                                animation.setDuration(1000);                                animationSet.addAnimation(animation);                                animationSet.setFillEnabled(true);                                animationSet.setFillAfter(true);                                circle.startAnimation(animationSet);                            }                            @Override                            public void onPageScrollStateChanged(int state) {                                switch (state){                                    case 1:                                        myHandler.removeMessages(100);                                        myHandler.sendEmptyMessageDelayed(100,5000);                                        Log.e("自定义标签", "类名==MainActivity" + "方法名==onPageScrollStateChanged=====:" + "");                                        break;                                }                            }                        });                    }                });            } catch (InterruptedException e) {                e.printStackTrace();            }        }    }).start();}Handler myHandler=new Handler(){    @Override    public void handleMessage(Message msg) {        switch (msg.what){            case 100:                myHandler.removeMessages(100);                pager.setCurrentItem(pager.getCurrentItem()+1);                break;        }    }};private Animation setAnim(int from,int to){    return new TranslateAnimation(posList.get(1)+from,posList.get(1)+to,posList.get(0),posList.get(0));}

}
//暴露出去的接口;在此处实现Viewpager的item的监听
class tmpListener implements OnPagerItemClickListnener{

@Overridepublic void onClick(int pos) {    Log.e("自定义标签", "类名==tmpListener" + "方法名==onClick=====:" + pos);}

}

实现源码

欢迎访问我的github,有帮助的话就star/fork一个吧,^3^
https://github.com/liuda555/MyViewFlow

0 0