finding pixel location of Listview item seems to return wrong value

夙愿已清 提交于 2019-12-07 06:44:49

问题


I have a ListView with a number of items (animals), of diverse heights. Using OnScrollListener I am trying to track which item intersects a specific location on the screen. Say the location in question is creatureMarkerBottom = 140. The code below seems to be returning faulty data when I run the code: I keep getting false positives and false negatives. Here is the code. The code is supposed to make the marker go solid or transparent depending if a chicken is intersecting it. However, the fading does not really obey whether the chicken is touching the slab/bar or not. My guess is the way I am getting the ListView pixel location is wrong.

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:


The solution to the problem is explained understanding ListView childAt method and what limits the index for listview.getChildAt(index). The problem was that I misunderstood the relationship between listView.getChildCount() and adapter.getCount().

In brief:

per my experiment, here is how it works. The ListView is a slice of the adapter. So if an adapter has 500 items and the ListView has ten (10). The ten in the ListView represent a dynamic view. So if the firstVisibleItem were item 217 in the adapter, then the ListView range of indices would be (217,…,226) whereas the listView.getChildCount() would still return 10.

Hence the answer is:

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


来源:https://stackoverflow.com/questions/19041222/finding-pixel-location-of-listview-item-seems-to-return-wrong-value

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!