ViewPager笔记
来源:互联网 发布:java 按位异或 编辑:程序博客网 时间:2024/05/19 23:57
1.FragmentStatePageAdapter和FragmentPageAdapter的异同点
同:
(1)对于超出缓存范围的Fragment:
FragmentStateAdapter执行Fragment的onDetach,即超出缓存的范围,Fragment将才从Activity中脱离(detach),当然此时Fragment的视图也会被销毁。
FragmentAdapter执行onDestroyView ,超出缓存的范围,Fragment将销毁视图,但是不会从Activity中脱离(detach)
(2)使用FragmentStatePageAdapter,当Fragment销毁时,会将其onSaveInstanceState(Bundle outState)中的bundle信息保存下来,当用户切换回来,可以通过该bundle恢复生成新的fragment,也就是说,你可以在onSaveInstanceState(Bundle outState)方法中保存一些数据,在onCreate中进行恢复创建。
(3)注意:
1)onDestroyView可以理解为切断了Fragment到View的引用,如果此时View没有被其他东西引用,那么这个View将等待GC回收,表现在你下次回来这个Fragment的时候,将执行onCreateView来重建View(如EditText,ImageView都是要重新创建的)。
反之这个View中的某些子View将不会被回收。比如下面的代码:
private ImageView imageView; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // Inflate the layout for this fragment super.onCreateView( inflater, container, savedInstanceState); View view= inflater.inflate(R.layout.fragment_fragment_one, container, false); imageView= (ImageView) view.findViewById(R.id.image_one); return view; }
如上面代码所示,因为成员变量imageView还保持对View中ImageView的引用,所以ImageView占用的内存并不会被回收。要是的ImageView被回收,采用如下代码
@Override public void onDestroyView() { super.onDestroyView(); imageView=null; }
2)onDetach意思是Fragment从Activity脱离,此时若在Fragment中调用getActivity()将得到null。
3)不管使用哪种adapter,都只是销毁了视图而已,Fragment并不会被回收,因为adapter中的list 引用着Fragment。
(2)都是默认缓存3个,setOffscreenPageLimit(int num)设置缓存的个数。
(3)各个重要方法的作用和执行顺序。(从上到下按顺序)
左右滑动时:
onPageScrollStateChanged DRAGGING
onPageScrollStateChanged SETTLING
onPageSelected
onPageScrollStateChanged IDLE
setPrimaryItem (会执行多次)
初始化时:
getCount
getItem
setPrimaryItem(会先setPrimaryItem,再预加载,所以当第一次加载的时候,会先setPrimaryItem,再加载当前的Fragment)
Fragment的生命周期一定在getItem之后,但是多个Fragment的生命周期有可能是交替执行的。
2.给ViewPager设置切换动画:
public class BasePagerTransFarmer implements ViewPager.PageTransformer { private static float MIN_SCALE = 0.75f; @SuppressLint("NewApi") @Override public void transformPage(View view, float position) { int pageWidth = view.getWidth(); if (position < -1) { // [-Infinity,-1) // This page is way off-screen to the left. view.setAlpha(0); } else if (position <= 0) { // [-1,0] // Use the default slide transition when // moving to the left page view.setAlpha(1); view.setTranslationX(0); view.setScaleX(1); view.setScaleY(1); } else if (position <= 1) { // (0,1] // Fade the page out. view.setAlpha(1 ); // Counteract the default slide transition view.setTranslationX(pageWidth * -position); // Scale the page down (between MIN_SCALE and 1) float scaleFactor = MIN_SCALE + (1 - MIN_SCALE) * (1 - Math.abs(position)); view.setScaleX(scaleFactor); view.setScaleY(scaleFactor); } else { // (1,+Infinity] // This page is way off-screen to the right. view.setAlpha(0); } } }
//设置动画viewPager.setPageTransformer(true, new BasePagerTransFarmer());
更多切换动画内容请点
http://blog.csdn.net/angcyo/article/details/49796759
3.使用PagerAdapter需实现一下四个方法:
getCount
isViewFromObject
instantiateItem
destroyItem
而FragmentStatePageAdapter和FragmentPageAdapter只需实现
getCount和getItem,其他方法已经帮我们实现好了。
4.
设置页卡间距: viewPager.setPageMargin(30);(或者用 viewPager.setPageMargin(-30),这样可以在一个pager里看到到两个pager放在一起的效果。)
5.
ViewPager无限轮播
方法1:
特殊说明:只有两条(a,b),一条数据(a)时,往list中添加相同的数据即可(a,b,a,b),(a,a,a)
@Override public Object instantiateItem(ViewGroup container, int position) { container.addView(viewList.get(position%viewList.size())); return viewList.get(position%viewList.size()); } @Override public void destroyItem(ViewGroup container, int position, Object object) { container.removeView(viewList.get(position%viewList.size())); } @Override public int getCount() { return Integer.MAX_VALUE; }
方法2:
特殊说明:只有一条数据时(a),往list中再添加两条相同数据即可(a,a,a)
boolean mIsChanged;//标识是否需要在onPageScrollStateChanged中重新setCurrentItem int pageIndex; @Override public void onPageScrollStateChanged(int pState) { if (ViewPager.SCROLL_STATE_IDLE == pState) {//viewpager已经停止滑动 if (mIsChanged) { mIsChanged = false; mViewPager.setCurrentItem(pageIndex, false); } } } @Override public void onPageSelected(int position) { if (position == 0) { // 当视图在第一个时,将页面号设置为图片的最后一张。 mIsChanged=true; pageIndex = mViewPagerList.size() - 2; } else if (position == mViewPagerList.size() - 1) { // 当视图在最后一个时,将页面号设置为图片的第一张。 mIsChanged=true; pageIndex = 1; } /** * 不要在此处 mViewPager.setCurrentItem(pageIndex, false); 因为此时viewpager还没有停止滑动,会造成界面闪跳 */ }
6.自定义ViewPager的滑动速度。
(1)自定义一个Scroller类
public class FixedScroller extends Scroller { private int mDuration = 500; public FixedScroller(Context context) { super(context); } public FixedScroller(Context context, Interpolator interpolator) { super(context, interpolator); } @Override public void startScroll(int startX, int startY, int dx, int dy, int duration) { //用mDuration去代替系统默认的Duration super.startScroll(startX, startY, dx, dy, mDuration); } @Override public void startScroll(int startX, int startY, int dx, int dy) { //用mDuration去代替系统默认的Duration super.startScroll(startX, startY, dx, dy, mDuration); }}
try { //使用反射重新设置ViewPager的Scroller Field mScroller; mScroller = ViewPager.class.getDeclaredField("mScroller"); mScroller.setAccessible(true); Interpolator sInterpolator = new LinearInterpolator(); FixedScroller scroller = new FixedScroller(viewPager.getContext(), sInterpolator); mScroller.set(viewPager, scroller); } catch (NoSuchFieldException | IllegalArgumentException | IllegalAccessException e) { }
7.关于adapter的 notifyDataSetChanged()
(1)当adapter中的数据源发生变化的时候(list的size变化了,list里面的内容变化了),就需要调用notifyDataSetChanged()去更新数,否则应用会崩溃。要注意两点:
a.如果只是list的size变化了,就不用重写adapter的getItemPosition()。
b.如果是list里面的内容变化了,就需要重写adapter的getItemPosition()
public int getItemPosition(Object object) { // 对应position的pager不需要更新,这是默认值 //return POSITION_UNCHANGED; //需要更新 return POSITION_NONE; }
8.destroyItem和instantiateItem 源码解析
如果destroyItem没有删除viewpager,那么instantiateItem就不会去调用getItem来获取新的fragment,而是复用之前的fragment。
如果如果destroyItem删除了viewpager,那么instantiateItem就会去调用getItem来获取新的fragment。
- ViewPager 笔记
- Viewpager笔记
- ViewPager笔记
- viewpager笔记
- android笔记11-ViewPager
- ViewPager学习笔记
- viewpager+fragment学习笔记
- ViewPager相关笔记
- FragmentPagerAdapter+ViewPager 笔记
- viewpager 左右滑动笔记
- 学习笔记之ViewPager
- viewpager学习笔记
- 温故知新-ViewPager学习笔记
- Viewpager 滑动动画笔记
- Android的 ViewPager 学习笔记
- 笔记44--viewpager用法二
- 笔记60--ViewPager循环滑动
- Android的 ViewPager 学习笔记
- 安卓XML和java文件中定义基本动画
- 第一天、我的CSDN博客开山篇
- Openvswitch原理与代码分析(2): ovs-vswitchd的启动
- redis 集群
- Openvswitch原理与代码分析(3): openvswitch内核模块的加载
- ViewPager笔记
- how to get UILable text width
- 制作Pascal VOC数据集并在YOLO和Faster RCNN上测试(码字ing)
- Openvswitch原理与代码分析(4):网络包的处理过程
- Java线程总结(十):并发包------两个线程交换数据Exchanger
- 神奇的 37% 的概率
- MD5加密算法的使用 (及加盐操作)
- 一张图解释什么是clearfix
- spring+struts2+mybatis整合