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

需求: 做新闻埋点上报的时候有种上报叫展现上报。服务端要求当新闻展现超过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+"%");
                }
            }
        });






猜你喜欢

转载自blog.csdn.net/langzxz/article/details/51038684