Android基础———ViewPager
来源:互联网 发布:人工智能会毁灭人类 编辑:程序博客网 时间:2024/05/20 13:08
ViewPager
可以用来做轮播,或者做fragment的滑动框架
一、简单的一个轮播
1.在布局文件layout里面写下viewpager控件 `<android.support.v4.view.ViewPager android:id="@+id/viewpager" android:layout_width="match_parent" android:layout_height="match_parent"> </android.support.v4.view.ViewPager>`注意:viewpager是v4包里面的2.ViewPager也和listview这些控件类似,需要适配器来加载view,写一个适配器 public class MyAdapter extends PagerAdapter { private List<ImageView> imageViewList; public MyAdapter(List<ImageView> imageViewList) { this.imageViewList = imageViewList; } /** * 获取viewpager的数目 * @return */ @Override public int getCount() { return imageViewList==null?0:imageViewList.size(); } /** *判断 返回的view和填充到viewpager的view是否一致 一致的才返回true * @param view instantiateItem里面加入containerde的view * @param object instantiateItem里面返回的值 */ @Override public boolean isViewFromObject(View view, Object object) { return view==object; } /** * 加载item ,要显示的内容加载出来 * @param container viewpager * @param position 要加载的位置 * @return */ @Override public Object instantiateItem(ViewGroup container, int position) { //获取当前要加载的图片 ImageView imageView=imageViewList.get(position); container.addView(imageView); return imageView; } /** * 销毁view * @param container viewpager对象 * @param position 当前位置 * @param object 将要销毁的对象view */ @Override public void destroyItem(ViewGroup container, int position, Object object) { //从viewpager中移除view container.removeView((View)object); } }3.在activity里面加代码,和listview类似,获取数据源,传到适配器,设置适配器,下面代码,数据源为三张图片,已经加在资源文件中了,资源文件也可以是从网上获取public class MainActivity extends AppCompatActivity { //图片id数组 private int[] ids={R.mipmap.pic1,R.mipmap.pic2,R.mipmap.pic3,R.mipmap.pic4}; private ViewPager viewPager; private List<ImageView> imageViewList; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //获取viewpager控件 viewPager = (ViewPager)findViewById(R.id.viewpager); //获取图片,把图片装入集合中 imageViewList = new ArrayList<>(); //给viewpager添加图片 for(int i=0;i<ids.length;i++){ //将图片加载到图片控件,然后加到图片集合中 ImageView imageView=new ImageView(this); imageView.setImageResource(ids[i]); imageViewList.add(imageView); } //加载适配器 viewPager.setAdapter(new MyAdapter(imageViewList)); }}
无限轮播
无限轮播需要注意的地方:会容易在移动view时崩溃, 崩溃的原因,是从右往左滑的时候是先移除后加载,而往回滑的时候是先加载后移除。解决崩溃主要思路: 在适配器里面设置getcount时,将返回的值设置为Integer.MAX_VALUE; public int getCount() { return Integer.MAX_VALUE; } 因为这个count代表的viewpager一共有多少页view,如果填实际的数据源,在循环无限的轮播的时候容易出问题, 所以设置一个很大的数来,来充当数目。 在加载view时要注意,判断当前获取的imageview是否有父容器,如果有,则需要移除父容器,没有则添加到viewpager, public Object instantiateItem(ViewGroup container, int position) { int rightPosition = position % imageViewList.size();//实际应该加入viewpager里面的第几个条目 ImageView imageView = imageViewList.get(rightPosition); if (imageView.getParent() == null) {//如果获取到的imageView没有父容器就不添加到viewPager container.addView(imageView); } else {//如果有父容器,就改变标记 isBack = true; } return imageView; } 在销毁view时也要进行判断,判断是否为往左滑动,如果是,则不需要销毁view //销毁view @Override public void destroyItem(ViewGroup container, int position, Object object) { if (!isBack) {//不是往左边滑的,才移除 container.removeView((View) object); } isBack=false; } 以上操作的原因: ViewPager在滑动时,每次加载时除了当前显示的视图,还会加载两个视图,前一个和后一个, 第一次加载时,前一个没有,只加载后一个,也只有这一次是例外。 但是每次加载前后两个图片的方式又根据滑动方式分为两种: 1、当你向右边滑动时,加载顺序是:先销毁上一个,再去加载下一个的下一个 2、当你向左边滑动时,加载顺序是:先加载上一个的上一个,在去销毁下一个 因为以上两种加载方式,就会导致在只有3张图的时候,出现程序崩溃。 比如有0 1 2 三张图,当前显示的是2,上一个是1和下一个0已经加载好了。 此时向左滑动,显示1,先加载0,会发现0已经有父容器了,加载失败,程序崩溃.... 在代码里面,当只有三张图的时候,可以再添加三张一样的图,这样就不会出现以上情况了、 代码如下:(包括了handler实现自动轮播,以及小白点) public class Main2Activity extends AppCompatActivity { private ViewPager viewPager2; private List<ImageView> imageViewList; private int[] ids = {R.mipmap.pic1, R.mipmap.pic2, R.mipmap.pic3}; private int lastPoint=0;//记录上一个小白点的位置 //实现自动轮播 private Handler handler = new Handler() { @Override public void handleMessage(Message msg) { switch (msg.what) { case 111://定时轮播 viewPager2.setCurrentItem(viewPager2.getCurrentItem() + 1);//设置轮播为下一页 sendEmptyMessageDelayed(111, 2000); //延迟两秒轮播 break; } } }; private LinearLayout pointLinearLayout; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main2); viewPager2 = (ViewPager) findViewById(R.id.viewpager2); imageViewList = new ArrayList<>(); //用来放白点 pointLinearLayout=(LinearLayout)findViewById(R.id.pointLinearLayout); //给list加imageview createImageview(false); //3张图以下,会因为viewpager不同方向滑动,加载方式不同而出现一些问题,所以此处可以判断一下, // 如果只有三张或一下的图,则多加三张一样的图 if (imageViewList.size() <= 3) { createImageview(true); } viewPager2.setAdapter(new MyAdapterInfinite(imageViewList)); //初始将viewpager设置在中间,这样才可以往左边滑动 //Integer.MAX_VALUE/2-Integer.MAX_VALUE/2%imageViewList.size() 这个不仅取到了中间,而且取到了第一张图 //Integer.MAX_VALUE/2%imageViewList.size() 表示 中间那个位置的图片是实际的第几张图片,然后减去数,就是第0张图片也就是第一张图片 viewPager2.setCurrentItem(Integer.MAX_VALUE / 2 - Integer.MAX_VALUE / 2 % imageViewList.size()); handler.sendEmptyMessage(111); //viewpager的页面监听 viewPager2.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { /** * 当页面滑动的时候 * * @param position 当前正在滑动的那一页下标 * @param positionOffset 滑动的偏移量 百分比 已经滑动了多少了 * @param positionOffsetPixels 滑动的偏移量(像素),当前总共滑动了多少像素 */ @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { } /** * 页面被选择时 * @param position 当前页面的位置 */ @Override public void onPageSelected(int position) { //用当前位置去求模得到小白点的位置,这里取余应该用ids,不能用imageviewlist, //因为图片有可能会有复制的 int pointPosition=position%ids.length; //获取小白点,并设置值 pointLinearLayout.getChildAt(pointPosition).setEnabled(false); //改变上一个小白点的状体 pointLinearLayout.getChildAt(lastPoint).setEnabled(true); //设置lastpoint的值为当前页面小白点 lastPoint=pointPosition; } /** * 页面滑动的状态发生变化的时候 * * @param state 包含拖动1 SCROLL_STATE_DRAGGING, * 惯性滚动2 SCROLL_STATE_SETTLING, * 停止0SCROLL_STATE_IDLE */ @Override public void onPageScrollStateChanged(int state) { } }); //viewpager的触摸监听 viewPager2.setOnTouchListener(new View.OnTouchListener() { /** * 当触摸的时候停止轮播 * @param view 当前的view页面 * @param motionEvent 事件类型,按下,松开 * @return */ @Override public boolean onTouch(View view, MotionEvent motionEvent) { if(motionEvent.getAction()== MotionEvent.ACTION_DOWN){//按下 handler.removeMessages(111);//移除handler }else if(motionEvent.getAction()==MotionEvent.ACTION_UP){ handler.sendEmptyMessageDelayed(111,2000); } return false; } }); } //用来把图片加载到list //使用isCopy来判断是否是复制的数据,即图片数量小于等于3的时候 private void createImageview(boolean isCopy) { for (int i = 0; i < ids.length; i++) { ImageView imageView = new ImageView(this); imageView.setImageResource(ids[i]); imageViewList.add(imageView); if (!isCopy) {//图片资源不是复制的,就生产小白点 View view = new View(this); view.setBackgroundResource(R.drawable.selector);//设置背景色 if (i == 0) {//如果是第一个则设置为红色 view.setEnabled(false); } //将当前位置加入到tag,下次点击事件可以使用 view.setTag(i); //加入小白点到线性布局 view.setOnClickListener(new View.OnClickListener() { /** * 小白点的点击监听 * @param view */ @Override public void onClick(View view) { //获取点击的小白点的位置 int pointposition=(int)view.getTag(); //获取当前点击小白点位置和上个小白点的位置差 int sub=pointposition-lastPoint; //viewpager当前页面去加上差值,就是点击了小白点后要显示的页面 viewPager2.setCurrentItem(viewPager2.getCurrentItem()+sub); } }); LinearLayout.LayoutParams layoutParams=new LinearLayout.LayoutParams(44,44); layoutParams.rightMargin=10; pointLinearLayout.addView(view,layoutParams); } } } } 除了上面的一种方法:还可以在适配器里面,每次加载图片都new一个出来,而不是去源数据中获取已经存好了的imageview。 代码如下: @Override public Object instantiateItem(ViewGroup container, int position) { ImageView imageView = new ImageView(container.getContext()); imageView.setScaleType(ImageView.ScaleType.FIT_XY); imageView.setImageResource(ids[position%ids.length]); container.addView(imageView); return imageView; } 但是这样特别浪费内存.建议用上面的一种
TabLayout
一种可以与viewpager结合使用,很暴力的控件,需要添加一个依赖,因为是另外一个包里面的1.在xml布局文件里面写 <android.support.design.widget.TabLayout android:id="@+id/tabLayout" android:layout_width="match_parent" android:layout_height="wrap_content" app:tabIndicatorHeight="10dp" app:tabSelectedTextColor="#fff" app:tabMode="scrollable" android:background="@drawable/shape" app:tabIndicatorColor="#0f0" app:tabTextColor="#00f" ></android.support.design.widget.TabLayout> 属性: tabIndicatorColor 下标指示器的颜色 tabIndicatorHeight 下标指示器的高度 tabTextColor tab 上面的文件的颜色 tabSelectedTextColor 被选中的 tab的上面的字的颜色2.在代码里面,viewpager的加载如上面一致,tablayout控件的设置,需要将获取到的TabLayout控件与viewpager联动, //将tablayout与viewpager设置联动 tabLayout.setupWithViewPager(viewPager);但是有一个问题,设置联动之后,如果给tablayout的tab设置了tag,与哪个 viewpager 保持联动, 这行代码会导致所有的 tab被删除然后重新添加,所以上面的属性都会被回收。所以想要tag生效,必须在最后再添加一次tag。3.想要tablayout的文字显示出来,需要在viewpager的adapter里面重写一个方法 @Override public CharSequence getPageTitle(int position) { return ss.get(position); } 这个方法会把文字添加进去。
viewpager结合fragment
1.只是适配器不同了,viewpager里面放fragment时,适配器不是pageadapter,而是用FragmentStatePagerAdapter和FragmentPageAdapter里面重写的方法也很简单,只有两个。2.在代码里面的实现很简单, public class MainActivity extends AppCompatActivity { private ViewPager viewPager; private List<Fragment> fragmentList; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //获取viewpager viewPager = (ViewPager)findViewById(R.id.viewpager); //创建fragment fragmentList = new ArrayList<>(); MyFragment myFragment = new MyFragment(); MyFragment2 myFragment2 = new MyFragment2(); MyFragment3 myFragment3 = new MyFragment3(); MyFragment4 myFragment4 = new MyFragment4(); //添加数据源 fragmentList.add(myFragment); fragmentList.add(myFragment2); fragmentList.add(myFragment3); fragmentList.add(myFragment4); //给viewpager设置适配器 /* FragmentManager fm=getSupportFragmentManager(); viewPager.setAdapter(new MyAdapter(fm,fragmentList)); */ //另外一种适配器 viewPager.setAdapter(new MyAdapterFragmentState(getSupportFragmentManager(),fragmentList)); viewPager.setOffscreenPageLimit(2);//前后各加载2个 }}3.viewpager 里面可以设置前后加载图片的数量,setOffscreenPageLimit viewPager.setOffscreenPageLimit(2);//前后各加载2个好像最多可以设置为3,即前后加载3张,每次加载7张图
0 0
- Android基础———ViewPager
- Android UI基础——ViewPager+Fragment
- Android开发笔记—ViewPager的基础使用
- Android——ViewPager
- Android——ViewPager滑动
- Android为ViewPager增加切换动画——自定义ViewPager
- Android为ViewPager增加切换动画——自定义ViewPager
- Android基础入门教程——2.4.14 ViewPager的简单使用
- Android基础控件——ViewPager实现带有动画的引导页
- android 基础 ---> ViewPager
- Android开发——ViewPager、项目相关
- Android——ViewPager+RadioGroup+Fragment
- Android——ViewPager+Fragment+ListView之间
- Android自定义View——自定义ViewPager
- Android课堂笔记——ViewPager
- Android——ViewPager及适配器PagerAdapter...
- android——ViewPager的使用
- Android——自定义ViewPager指示器
- ulua里如何将C#创建的UnityEngine对象返回给lua
- python整型
- RxJava的使用,教你四步搞定RxBus.
- 自定义present动画的屏幕变黑的一个坑
- Remove Duplicates from Sorted List II
- Android基础———ViewPager
- java解题公共汽车
- 运维日记011 - Ubuntu下更改初始用户名的方法
- Github 使用方法
- HTML基础样式(二)
- Vector与ArrayList区别
- leetcode---Water and Jug Problem
- JavaScript调试之console命令的各函数用法
- 对于rpc遇到的疑问以及个人理解