Android 获取listview中Item的可视百分比
2016-04-01 18:01
127 查看
需求: 做新闻埋点上报的时候有种上报叫展现上报。服务端要求当新闻展现超过50%后才算展现,手指做了抛的动作(手指离开屏幕前,用力滑了一下)这种在listview中显示的不算展现。
猛的一看,实现太难了,后来发现函数
获取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)个点
所以计算显示百分比的函数
listview的滑动事件有三个
SCROLL_STATE_IDLE = 0; 停止滚动
SCROLL_STATE_TOUCH_SCROLL = 1; 正在滚动
SCROLL_STATE_FLING = 2; 惯性滑动
惯性滑动的时候展现的新闻不算展现,也就是说,在SCROLL_STATE_IDLE的时候计算整个屏幕的itemView的展现百分比,在SCROLL_STATE_TOUCH_SCROLL的时候,只计算最下面itemView的百分比就好。
关键代码:
猛的一看,实现太难了,后来发现函数
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+"%"); } } });
相关文章推荐
- Android的性能优化
- Android开发中经常会用到的功能代码
- 【Dialer】自定义暗码进入测试模式
- Android移动应用开发中常见的经验技巧总结
- Android快速毛玻璃虚化效果实现
- Android Asynctask与Handler的比较,优缺点区别,Asynctask源码
- Android 获取控件宽高的3种方法
- android shape的使用
- 通过包名,直接精确启动一个三方Activity
- Android 5.0 CardView+ListView 卡片布局应用
- 【Dialer】android6.0拨号界面分析<一>
- Android fragment 重叠问题的解决方法
- 在Android Studio中有六种依赖
- 【Android 2D 游戏开发(4)】——俄罗斯方块(手势操作)
- Android NestedScrolling与分发机制 二
- Android 添加页面切换动画, 避免冷启动
- Android 使用DrawerLayout快速实现侧滑菜单
- android开源的酷炫的交互动画和视觉效果:Interactive-animation
- 安卓开发——androidstudio自动导包(导入全部包)
- Android 看IntentService源码延伸