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

Android 获取listview中Item的可视百分比

2016-04-01 18:01 127 查看
需求: 做新闻埋点上报的时候有种上报叫展现上报。服务端要求当新闻展现超过50%后才算展现,手指做了抛的动作(手指离开屏幕前,用力滑了一下)这种在listview中显示的不算展现。
猛的一看,实现太难了,后来发现函数
public final boolean getLocalVisibleRect(Rect r)

获取View的可视区域,比如listView 最顶层的ItemView显示一半,通过函数的到Rect(0, 60 - 1080, 120)
0 和 1080 是itemView的left right
60 和 120 是itemView的top bottom
如果显示全 itemView的top就是0。
如果是最低层的itemView显示一点,通过函数得到的Rect(0, 0 - 1080, 21)
top为0,说明上面没有覆盖,
bottom为21,说明下面覆盖了(120-21)个点
所以计算显示百分比的函数
public int getVisibilityPercents(View view){
View tv =  view;
tv.getLocalVisibleRect(rect);
int height = tv.getHeight();
int  percents = 100;
if(rect.top==0 && rect.bottom == height){
percents = 100;
}else if(rect.top > 0){
percents =  (height - rect.top) * 100 / height;
}else if(rect.bottom > 0 && rect.bottom <height) {
percents =rect.bottom * 100 / height;
}
return percents;
}


listview的滑动事件有三个
SCROLL_STATE_IDLE = 0; 停止滚动
SCROLL_STATE_TOUCH_SCROLL = 1; 正在滚动
SCROLL_STATE_FLING = 2; 惯性滑动
惯性滑动的时候展现的新闻不算展现,也就是说,在SCROLL_STATE_IDLE的时候计算整个屏幕的itemView的展现百分比,在SCROLL_STATE_TOUCH_SCROLL的时候,只计算最下面itemView的百分比就好。
关键代码:
public class DataListItem extends Object{

public String mTitle;
public Rect rect = new Rect();
public DataListItem(String title){
mTitle = title;
}

public int getVisibilityPercents(View view){
View tv =  view;
tv.getLocalVisibleRect(rect);
int height = tv.getHeight();
int  percents = 100;
if(rect.top==0 && rect.bottom == height){
percents = 100;
}else if(rect.top > 0){
percents =  (height - rect.top) * 100 / height;
}else if(rect.bottom > 0 && rect.bottom <height) {
percents =rect.bottom * 100 / height;
}
return percents;
}
}


for (int i = 0; i < 50; i++) {
mArrayList.add(new DataListItem("" + i));
}

mMyAdapter = new MyAdapter(getBaseContext().getApplicationContext(), mArrayList);
mListView.setAdapter(mMyAdapter);
mListView.setOnScrollListener(new AbsListView.OnScrollListener() {
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {

//正在滚动时回调,回调2-3次,手指没抛则回调2次。scrollState = 2的这次不回调
//回调顺序如下
//第1次:scrollState = SCROLL_STATE_TOUCH_SCROLL(1) 正在滚动
//第2次:scrollState = SCROLL_STATE_FLING(2) 手指做了抛的动作(手指离开屏幕前,用力滑了一下)
//第3次:scrollState = SCROLL_STATE_IDLE(0) 停止滚动
//当屏幕停止滚动时为0;当屏幕滚动且用户使用的触碰或手指还在屏幕上时为1;
//由于用户的操作,屏幕产生惯性滑动时为2
mScrollState = scrollState;
Log.d("onScrollStateChanged","scrollState = " +scrollState );
Log.d("onScrollStateChanged", "view.getFirstVisiblePosition() = " +view.getFirstVisiblePosition() +"view.getLastVisiblePosition() = "+view.getLastVisiblePosition() );

if(mScrollState == 0){
for (int i = view.getFirstVisiblePosition(),j=0;i<=view.getLastVisiblePosition();i++,j++){
View v = view.getChildAt(j);
if(v==null)return;
DataListItem d =  mArrayList.get(i);
int percents = d.getVisibilityPercents(v);
Log.d(TAG ,d.mTitle +"  "+percents+"%");
}
}
}

@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
//滚动时一直回调,直到停止滚动时才停止回调。单击时回调一次。
//firstVisibleItem:当前能看见的第一个列表项ID(从0开始)
//visibleItemCount:当前能看见的列表项个数(小半个也算)
//totalItemCount:列表项共数

Log.d("onScroll", "firstVisibleItem = " + firstVisibleItem + " visibleItemCount = " + visibleItemCount + " totalItemCount = " + totalItemCount);
if(mScrollState == 0){
for (int i = firstVisibleItem ,j=0;i<visibleItemCount;i++,j++){
View v = view.getChildAt(j);
DataListItem d =  mArrayList.get(i);
int percents = d.getVisibilityPercents(v);
Log.d(TAG ,d.mTitle +"  "+percents+"%");
}
}else if(mScrollState == 1){
DataListItem d =  mArrayList.get(firstVisibleItem);
View v = view.getChildAt(0);
int percents = d.getVisibilityPercents(v);
Log.d(TAG ,d.mTitle +"  "+percents+"%");

d =  mArrayList.get(firstVisibleItem +visibleItemCount-1);
v = view.getChildAt(visibleItemCount-1);
percents = d.getVisibilityPercents(v);
Log.d(TAG ,d.mTitle +"  "+percents+"%");
}
}
});
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: