通过getChildAt方法取得AdapterView中第n个Item(重新编辑)

以前对于AdapterView(ListView和GridView的父类)以及这个类的getChildAt()方法理解十分粗浅,以为是指传入一个绝对position(就是这个item是AdapterView第几个元素)来直接获得到该item,当然,android SDK中对于该方法也没有很具体的说明。这个理解是错误的。以简单的listview为例先说下listview对于item的复用,一个元素很多的listview,如果页面的可视区域内最多可以看到6个元素,不妨假如它们的index是0-5,那么在内存中只有6个item对象。当第7个item(即index=6)进入到可视区域的时候,那么其实是在复用index=0的item。由于在滑动时getView这个更新控件的方法执行非常频繁,所以肉眼是丝毫看不出这种复用的。
那么,接着上面的例子来说,任何情况下,getChildAt(int position)返回的item都是指的可视区域内的第position个元素。下面是一种巧妙和严谨的方法可以在任何时候(指的是listView滑动在任意状态时)根据position取得可视区域内的item,如果该item不在可视区域,则返回null。

private static class ChildViewInfo {

        private Integer firstVisiblePosition = null;
        private Integer childCount = null;

        private Integer headerViewsCount = null;

        private Integer firstVisiblePositionWithOutHeaderViews = null;
        private Integer childCountWithOutHeaderViews = null;
        private Integer visibleHeaderViewsCount = null;

        public ChildViewInfo(AdapterView adapterView) {
            Adapter adapter = adapterView.getAdapter();
            firstVisiblePosition = adapterView.getFirstVisiblePosition();
            childCount = adapterView.getChildCount();
            if (null != adapter && adapter instanceof HeaderViewListAdapter) {
                headerViewsCount = ((HeaderViewListAdapter) adapter).getHeadersCount();

                firstVisiblePositionWithOutHeaderViews = firstVisiblePosition - headerViewsCount;
                if (firstVisiblePositionWithOutHeaderViews < 0) {
                    firstVisiblePositionWithOutHeaderViews = 0;
                }

                visibleHeaderViewsCount = headerViewsCount - firstVisiblePosition;
                if (visibleHeaderViewsCount > 0) {
                    visibleHeaderViewsCount = Math.min(childCount, visibleHeaderViewsCount);
                    childCountWithOutHeaderViews = childCount - visibleHeaderViewsCount;
                } else {
                    visibleHeaderViewsCount = 0;
                    childCountWithOutHeaderViews = childCount;
                }
            }
        }


        public View getItemView(int position, boolean withOutHeaderViews) { 
            boolean b = withOutHeaderViews && adapterView.getAdapter() instanceof HeaderViewListAdapter;
            ChildViewInfo childViewInfo = new ChildViewInfo(adapterView);
            int firstVisiblePosition = b ? childViewInfo.firstVisiblePositionWithOutHeaderViews : 
                childViewInfo.firstVisiblePosition;
            int childCount = b ? childViewInfo.childCountWithOutHeaderViews : 
                childViewInfo.childCount;
            Integer index = getItemViewIndex(firstVisiblePosition, childCount, position);
            if (null != index) {
                index = b ? index + childViewInfo.visibleHeaderViewsCount : index;
                return adapterView.getChildAt(index);
            }
            return null;
        }

        public static Integer getItemViewIndex(int firstVisiblePosition, int childCount, int position) {
            int index = position - firstVisiblePosition;
            int count = childCount;
            if (index >= 0 && index < count) {
                return index;
            }
            return null;
        }
}

你可能感兴趣的:(android)