您的位置:首页 > 移动开发 > Android开发

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行。

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工程的下载了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: