Android自定义ListView实现第一可见项和最后可见项的淡入淡出效果
2016-04-08 16:33
615 查看
先上效果图:(demo背景颜色太白了,所以效果不是很好)
本来想实现这个效果的,但是在网上简单搜了一下,都没人讲解一下这个怎么实现,因此本人也花了一些功夫来搞。
首先思考实现思路:
1、得到第一项和最后一项的View
2、算出此View的本身绘制的高度
3、算出此View在屏幕可见的高度
4、通过可见高度与本身高度的比值,设置View的alpha值。
首先,第一步很简单,总所周知,在ListView的onScrollListener监听器中的onScroll方法,第三个参数visiableItemCount,表示屏幕一共可见的Item数,也就是该ListView实际拥有的View的数量(不懂的请百度【ListView的缓存原理】),那么visiableItemCount-1,就等于最后可见项的View在ListView的实际索引,通过getChildAt方法可得到这个View。
然后第二步,因为上一步已经得到了对应的View,因此只需要调用getHeight方法就可以得到这个高度,这种方式虽然简单,但是就这一句代码,就可以适配Item高度不相同的情况,因为在onScroll方法是跟着手势滚动实时调用的,还有就是此时ListView已经measure成功,不必担心getHeight返回值为0的情况。
最重要的第三步,算出最后一个View的可见的高度。这个方法折腾了我好久一段时间。期初我打算用getScrollY得到偏移值,来动态进行计算,后来发现getScrollY返回值恒等于0,无语。然后打算在onTouchEvent中用滑动距离进行计算,但是发现逻辑会非常复杂,就此打住。然后与好朋友一起讨论发现,根本不需要那么复杂,view.getTop和view.getBottom方法直接返回这个view的起点和终点在ListView中的坐标,然后通过onMeasure方法得到ListView的高度值,瞬间就能解决问题。哎,有时候灵感非常重要啊,闭门造车还不如找朋友谈谈找找灵感。废话不多说,直接上源码,关键部分的代码不超过20行。
用法就如普通的ListView完全一样。就不提供demo工程的下载了。
本来想实现这个效果的,但是在网上简单搜了一下,都没人讲解一下这个怎么实现,因此本人也花了一些功夫来搞。
首先思考实现思路:
1、得到第一项和最后一项的View
2、算出此View的本身绘制的高度
3、算出此View在屏幕可见的高度
4、通过可见高度与本身高度的比值,设置View的alpha值。
首先,第一步很简单,总所周知,在ListView的onScrollListener监听器中的onScroll方法,第三个参数visiableItemCount,表示屏幕一共可见的Item数,也就是该ListView实际拥有的View的数量(不懂的请百度【ListView的缓存原理】),那么visiableItemCount-1,就等于最后可见项的View在ListView的实际索引,通过getChildAt方法可得到这个View。
然后第二步,因为上一步已经得到了对应的View,因此只需要调用getHeight方法就可以得到这个高度,这种方式虽然简单,但是就这一句代码,就可以适配Item高度不相同的情况,因为在onScroll方法是跟着手势滚动实时调用的,还有就是此时ListView已经measure成功,不必担心getHeight返回值为0的情况。
最重要的第三步,算出最后一个View的可见的高度。这个方法折腾了我好久一段时间。期初我打算用getScrollY得到偏移值,来动态进行计算,后来发现getScrollY返回值恒等于0,无语。然后打算在onTouchEvent中用滑动距离进行计算,但是发现逻辑会非常复杂,就此打住。然后与好朋友一起讨论发现,根本不需要那么复杂,view.getTop和view.getBottom方法直接返回这个view的起点和终点在ListView中的坐标,然后通过onMeasure方法得到ListView的高度值,瞬间就能解决问题。哎,有时候灵感非常重要啊,闭门造车还不如找朋友谈谈找找灵感。废话不多说,直接上源码,关键部分的代码不超过20行。
package cc.wxf.view.alpha; import android.content.Context; import android.util.AttributeSet; import android.view.View; import android.widget.AbsListView; import android.widget.ListView; /** * Created by ccwxf on 2016/4/7. */ public class AlphaListView extends ListView implements AbsListView.OnScrollListener { private int height; private int itemHeight; public AlphaListView(Context context) { super(context); init(); } public AlphaListView(Context context, AttributeSet attrs) { super(context, attrs); init(); } public AlphaListView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(); } private void init() { setOnScrollListener(this); } @Override public void onScrollStateChanged(AbsListView view, int scrollState) { } @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { //将所有View的透明度设置为1 for(int i = 0; i < getChildCount(); i++){ getChildAt(i).setAlpha(1); } //得到第一个可见的View View v = getChildAt(0); if(v != null){ //得到这个v的高度 itemHeight = v.getHeight(); //得到可见部分 int visiableLength = v.getBottom(); //得到可见不分部分比例 float ratio = visiableLength * 1.0f / itemHeight; v.setAlpha(ratio); } //得到最后一个可见的View v = getChildAt(visibleItemCount - 1); if(v != null){ //得到这个v的高度 itemHeight = v.getHeight(); //得到可见部分 int visiableLength = height - v.getTop(); //得到可见不分部分比例 float ratio = visiableLength * 1.0f / itemHeight; v.setAlpha(ratio); } } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { height = MeasureSpec.getSize(heightMeasureSpec); super.onMeasure(widthMeasureSpec, heightMeasureSpec); } }
用法就如普通的ListView完全一样。就不提供demo工程的下载了。
相关文章推荐
- Android:应用前后台切换判断
- Android Fragment详解(一):概述
- Android Studio 小技巧合集
- android的工程和代码的命名规范(第一篇文章,勿喷)
- 基于DLNA实现iOS、Android投屏:基本概念
- Android .mk文件中需要注意的一些宏
- 把Android源码中的密码对转换为keystore的方法
- Android 6.0运行时权限
- android 沉浸式状态栏
- Android图片加载Glide框架使用详解
- android短信监听
- android工具2——MD5加密
- android back键监听
- Android系统关机或重启的几种实现方式
- Android动态布局方法总结
- Android Studio中配置AndroidAnnotations,遇到的问题及解决方法
- Service详解(一):什么是Service
- android 什么是"有权查看使用情况的应用程序"
- Android实现一个记住密码的登陆界面
- android性能调优