本文出自博客Vander丶CSDN博客,如需转载请标明出处,尊重原创谢谢
博客地址:http://blog.csdn.net/l540675759/article/details/78112989
前言
如果读者没有阅读过该系列博客,建议先阅读下博文说明,这样会对后续的阅读博客思路上会有一个清晰的认识。
Android 中LayoutInflater(布局加载器)系列博文说明
导航
Android 中LayoutInflater(布局加载器)系列博文说明
Android 中LayoutInflater(布局加载器)系列之介绍篇
Android 中LayoutInflater(布局加载器)系列之源码篇
Android 中LayoutInflater(布局加载器)源码篇之createViewFromTag方法
Android 中LayoutInflater(布局加载器)源码篇之rInflate方法
Android 中LayoutInflater(布局加载器)源码篇之parseInclude方法
Android 中LayoutInflater(布局加载器)之实战篇
效果
概述
(1)主要目的是通过这个Demo,理解自定义LayoutInflater.Factory的过程。
(2)理解小红书的第一版引导页是如何制作出来的。
分析
这个效果属于视觉差的效果,原理是根据ViewPager的滑动方向,页面内物理做同向偏移,只要偏移距离大于页面的偏移,就会产生速度差,那么就会实现该效果。
实现速度差,我们需要一个滑动的比例系数:
在页面进入时:
页面物体的移动距离 = (页面长度 - 滑动距离) * 滑动系数
在页面滑出时:
页面物体的移动距离 = (0 - 滑动距离 ) * 滑动系数
同时考虑第二张Gif上,发现物体Y轴也存在移动,所以也得需要考虑Y轴方向的滑动,整理下:
//进入时:
view.setTranslateX((vpWidth - positionOffsetPixels) * xIn);
view.setTranslateY((vpWidth - positionOffsetPixels) * yIn);
//退出时
view.setTranslateX((0 - positionOffsetPixels) * xOut);
view.setTranslateY((0 - positionOffsetPixels) * yOut);
这样就可以实现出:
(1)进入该界面时,界面上的物品快速飞进来。
(2)退出该界面时,界面上的物理快速飞出去。
实现思路
对于上述的分析,这里的实现思路存在两种:
-
自定义View,自定义xIn、yIn、xOut、yOut四个属性的系数,所有界面上的物体继承这个自定义View。
-
自定义LayoutInflater.Factory在解析时,将这些自定义属性提取,以Tag方式储存起来。
优缺点分析
自定义View:
优点:可以对物体做更多层面的扩展,这个自定义LayoutInflater.Factory是不具备的。
缺点:由于界面的物体数量过多,在findViewById时需要处理的View元素过多,极大的增加代码量。
自定义LayoutInflater.Factory :
优点:可以在解析过程中对View做统一操作,当出现大量的View时,能够缩减大量代码。
缺点:在解析时预处理View,但是就不能动态的改变View的属性,要对View进行扩展性操作,自定义LayoutInflater.Factory不具备这样的功能。
自定义LayoutInflater.Factory
上述的两种方案的优缺点已经分析完毕,但是本文作为实战篇,所以只会介绍自定义LayoutInflater.Factory这种方式。
在实际场景中,需要结合自身情况,以及上述的优缺点,进行合理选择。
在介绍之前,先看一段代码:
View view;
//如果Factory2存在,就会调用其onCreateView方法
if (mFactory2 != null) {
view = mFactory2.onCreateView(parent, name, context, attrs);
//如果Factory存在,就会调用其onCreateView方法,和Factory2不同的时,这里的参数没有父View
} else if (mFactory != null) {
view = mFactory.onCreateView(name, context, attrs);
} else {
view = null;
}
//如果没有Factory或者Factory2,就会寻找mPrivateFactory(本质上也是Factory2)
if (view == null && mPrivateFactory != null) {
view = mPrivateFactory.onCreateView(parent, name, context, attrs);
}
这段代码出自LayoutInflater中createViewFromTag()方法,作用是根据View的名称(name参数)来创建View,这里在源码篇已经详细分析过,如果没有看过,可以点击这里。