好久没有写文章了,慢慢的自己工作中遇到的问题不做积累,下次遇到还会忘。哎。。。。周日无聊的单身程序员-唯有程序你懂的…
写着程序听着歌也是极好的!!最近工作中要实现类似 今日头条等新闻类APP顶部导航条的效果 ,不过我们这效果切换时要加上文字颜色的渐变和缩放我不会弄动态图片啊,求各位会的教俺下:
一:分析
今天我们要实现这种特效。
用到的开源项目有:master-nineoldandroids-library.jar这个jar包,这个是向下兼容的jar包,包括android一系列的动画。
首先我们说一下这种日头条等新闻类APP 的基本实现是ViewPage+Fragment+HorizontalScrollView
我们今天说的就是这个HorizontalScrollView的特效。
实现原理图:
相信大家已经明白了大概
就是:最初时我们 初始化textview 并把选中的和正常的textview 初始化。就是上图中的framelayout中的2个textview 放到集合HashMap<String, View>()中。用于保持所有textview的状态。
至于代码怎么写呢?!
android系统给我们提供了一个叫PagerSlidingTabStrip的类,在v4包中。我们把java中考出来放到我们的小明中,修改其中的代码就可以。
我们通过viewpage来控制导航条。把viewpage传到PagerSlidingTabStrip中,并设置监听器,代码如下:
public void setViewPager(ViewPager pager) {this.pager = pager;if (pager.getAdapter() == null) {throw new IllegalStateException("ViewPager does not have adapter instance.");}pager.setOnPageChangeListener(pageListener);notifyDataSetChanged();}二、获取用户切换时当前View和切换至的目的View。
ViewPager也需要监听用户的手势,所以肯定提供了某个方法。于是纵观ViewPager的方法,发现了一个叫做onPageScrolled(int position, float positionOffset,int positionOffsetPixels)的方法~~
没错就是这个方法:在页面滚动时调用~
下面仔细研究下这几个参数:
直接说测试结果:
在非第一页与最后一页时,滑动到下一页,position为当前页位置;滑动到上一页:position为当前页-1
positionOffset滑动到下一页,[0,1)区间上变化;滑动到上一页:(1,0]区间上变化
positionOffsetPixels这个和positionOffset很像:滑动到下一页,[0,宽度)区间上变化;滑动到上一页:(宽度,0]区间上变化
第一页时:滑动到上一页position=0 ,其他基本为0 ;最后一页滑动到下一页position为当前页位置,其他两个参数为0
豁然发现,我们需要的步骤的第二步解决了,positionOffset很适合作为,,渐变,缩放的控制参数;positionOffsetPixels则可以作为平移等的控制参数。
那么如何获得当前View和目的View呢:
分享几个我的歧途:
1、【错误】我通过getChildAt(position),getChildAt(position+1),getChildAt(position-1)获得滑动时,左右的两个View;乍一看,还真觉得不错~~~在代码写出来,再乍效果也出不来~~错误原因:我们忽略一个特别大的东西,ViewPager的机制,滑动时动态加载和删除View,ViewPager其实只会维持2到3个View,而position的范围基本属于无限~~
2、【错误】我通过getCurrentItem获得当前的位置,然后+1,-1获得后一个或者前一个~~正在窃喜,赶快代码改过来,效果怎么也不对,乱七八糟的~~仔细观察日志,这个getCurrentItem当用户手指离开的屏幕,Page还在动画执行时,就改变了~~难怪~整个滑动过程并不是固定的~~唉,心都碎了~
3、【错误】position在整个滑动的过程中是不变化的,而且ViewPager会保存2个或3个View;那么我考虑,如果是第一页、或者最后一页那么我取getChildAt(0)和getChildAt(1),如果在其他页面则为getChildAt(0),getChildAt(2),然后经过一系列的变化~我想这会总该对了吧,于是我遇到第一问题,第一页的时候,不管左右position都为0,尼玛,这哪个为左View,哪个为右View~~
说了这么多错误,大家可以绕过这些弯路,也能从这些弯路里面看出点什么~
下面说正确的,其实ViewPager在添加一个View或者销毁一个View时,是我们自己的PageAdapter中控制的,于是我们可以在ViewPager里面维系一个HashMap<Position,View>,然后滑动的时候,通过get(position)取出,比如上述效果,始终是右边的View变化,要么从小到大,要么从大到小
那么滑倒下一页:左边的View:map.get(position) ,右边的View : map.get(position+1) .
那么滑倒上一页:左边的View : map.get(position) , 右边的View : map.get(position+1) , 一样的,因为滑到上一页,position为当前页-1
知已知彼,百战百胜。