ViewPager加载页面,底部圆点指示器,圆点拖动效果,支持手势拖动
来源:互联网 发布:php培训 编辑:程序博客网 时间:2024/04/30 19:44
效果概述:
- 随着viewpager中页面的滑动,底部的圆点也有拖动效果,支持手势拖动
效果图如下:
实现原理:
- ViewPager 无限轮播,设置了Integer.MAX_VALUE ; 其实也可以设置为前一张后一张,不过麻烦点儿
- 根据ViewPager中图片个数不同,底部显示不同个数的圆点
- 动态加载圆点的同时,记录下圆点的位置,放于集合中
- ViewPager 的setOnPageChangeListener监听,用于设置ViewPager的页面切换时,圆点的动画效果
- 支持手势拖动
遇到的问题
装载圆点的layout在onCreate()中未立即装载,需要动态获取圆点位置的方法失败
解决办法: 网上有说其他的方法;我是直接开了子线程,睡了500ms
手势拖动,使用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
- ViewPager加载页面,底部圆点指示器,圆点拖动效果,支持手势拖动
- ViewPager底部圆点指示器
- viewpager的圆点指示器
- Android 利用ViewPager实现底部圆点导航左右滑动效果以及Fragment页面切换
- 模仿QQ消息红点拖动效果
- 跟随滑动ViewPager指示器(小圆点跟随滑动效果)
- 打造最简单ViewPager指示器,实现小圆点效果
- Android ViewPager 小圆点指示器
- Tab页滑动导航效果圆点指示器
- ViewPager 实现循环拖动效果
- GDI 编程画折线&winform拖动圆点
- 自定义Android圆点指示器
- 自定义QQ消息红点拖动的效果
- Android 自定义View 实现QQ红点拖动删除效果
- 自己动手搞一个拖动滑块,点击水波纹效果
- Android中ViewPager的简单使用(底部圆点)
- Android中ViewPager使用FragmentPagerAdapter(底部圆点)
- Android中ViewPager使用FragmentPagerAdapter(底部圆点)
- Lambda 表达式(一)-码住
- 蓝桥杯 16进制转换8进制
- spring注解完整版
- jvm系列
- php 贪婪算法(摘记)
- ViewPager加载页面,底部圆点指示器,圆点拖动效果,支持手势拖动
- R语言案例分析:多元数据的基本统计分析
- 动态规划算法
- PAT甲级1005
- codevs 1688 逆序对
- (shell)判断文件个数是否为一,是的话判断是否在文件内
- Java过滤器与SpringMVC拦截器
- 算法导论——2.1-4
- spark 操作hive相关文档以及技术操作网址链接