找到Listview项目的像素位置似乎返回错误的值

时间:2013-09-27 01:14:41

标签: android android-layout android-listview scroll coordinates

我有一个ListView,其中包含许多不同高度的物品(动物)。使用OnScrollListener我试图跟踪哪个项目与屏幕上的特定位置相交。假设有问题的地点是creatureMarkerBottom = 140。当我运行代码时,下面的代码似乎返回了错误的数据:我不断得到误报和漏报。这是代码。该代码应该使标记变为实心或透明,这取决于鸡是否与它交叉。然而,褪色并不能真正服从鸡是否接触到板/棒。我的猜测是我获取ListView像素位置的方式是错误的。

OnScrollListener listviewScrollListener = new OnScrollListener() {
        int creatureLocationPixel[] = { 0, 0 };
        int creatureMarkerBottom;
        int creatureTop, creatureBottom;
        int[] creatureLocationPixel = { 0, 0 };
        View creatureView;
        boolean creatureMarkerIsFaded = false;

        @Override
        public void onScrollStateChanged(AbsListView view, int scrollState) {

        }

        @Override
        public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
            try {
                scrollBackgroundToFindCreature(visibleItemCount, firstVisibleItem);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        private void scrollBackgroundToFindCreature(int visibleItemCount, int index) {
            creatureMarkerSlabView.getLocationOnScreen(creatureLocationPixel);
            creatureMarkerBottom = creatureLocationPixel[1] + creatureMarkerSlabView.getHeight();
            Animal creature;
            boolean found = false;
            do {
                creature = mAdapter.getItem(index);
                creatureView = getViewForPosition(index);
                creatureView.getLocationOnScreen(creatureLocationPixel);
                creatureTop = creatureLocationPixel[1];
                creatureBottom = creatureTop + creatureView.getHeight();
                if (creatureTop < creatureMarkerBottom  && creatureMarkerBottom  < creatureBottom) {
                    found = true;
                } else {
                    index++;
                }
            } while (!found && index < visibleItemCount);

            if (creatureType.CHICKEN != creature.getType()) {
                if (!creatureMarkerIsFaded) {
                    creatureMarkerIsFaded = true;
                    for (int x = 0; x < creatureMarkerSlabView.getChildCount(); x++)
                        creatureMarkerSlabView.getChildAt(x).setAlpha(TRANSPARENCY_ALPHA);
                    creatureMarkerSlabView.setAlpha(TRANSPARENCY_ALPHA);
                }

            } else {
                if (creatureMarkerIsFaded) {
                    creatureMarkerIsFaded = false;
                    for (int x = 0; x < creatureMarkerSlabView.getChildCount(); x++)
                        creatureMarkerSlabView.getChildAt(x).setAlpha(255);
                    creatureMarkerSlabView.setAlpha(255);
                }
            }
        }

    };

public View getViewForPosition(int position) {
        int firstPosition = animalListview.getFirstVisiblePosition() - animalListview.getHeaderViewsCount();
        int wantedChild = position - firstPosition;
        // Say, first visible position is 8, you want position 10, wantedChild will now be 2
        // So that means your view is child #2 in the ViewGroup:
        if (wantedChild < 0 || wantedChild >= animalListview.getChildCount()) {
            return null;
        }
        return animalListview.getChildAt(wantedChild);
    }

1 个答案:

答案 0 :(得分:1)

解释了问题的解决方案understanding ListView childAt methodwhat limits the index for listview.getChildAt(index)。问题在于我误解了listView.getChildCount()adapter.getCount()之间的关系。

简而言之:

根据我的实验,这是它的工作原理。 ListView是适配器的一部分。因此,如果适配器有500个项目,ListView有10个(10)。 ListView中的十个表示动态视图。因此,如果firstVisibleItem是适配器中的项目217,那么ListView的索引范围将是(217,...,226),而listView.getChildCount()仍将返回10.。

因此答案是:

getChildAt(x) | x : [0+firstVisibleItem, listview.getChildCount()+firstVisibleItem)