Determining the entry shown is listview

2020-02-16 03:04发布

问题:

i am trying to send data in a listview when a button is clicked.

However my listview show 2 row on at once one full row and one partial row . Is there a way i can determine which row is showing partial and which is showing fully.

I am able to get the index that is showing only. is there another approach ?

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


    if (scrollState == SCROLL_STATE_IDLE){
        Rect r = new Rect ();
        View child = recordListview.getChildAt(view.getFirstVisiblePosition());    // first visible child
        if (child == null)
            return; 
        double height = child.getHeight () * 1.0;

        recordListview.getChildVisibleRect (child, r, null);
        Log.d("Visible1 ", view.getFirstVisiblePosition() + "  "  + height + "  " + r.height()  );

        if (Math.abs (r.height ()) < height / 2.0) {
                    // show next child
            recordListview.smoothScrollToPosition(view.getFirstVisiblePosition()+1);
            Log.d("Visible1 Location", view.getFirstVisiblePosition() +1+ "");
        }

        else {
            recordListview.smoothScrollToPosition(view.getFirstVisiblePosition());
            Log.d("Visible1 Location", view.getFirstVisiblePosition()+ "");
        }

    }
}
});

回答1:

Seems You've understood documentation of getChildVisibleRect() incorrectly.

It mentions:

r The input rectangle, defined in the child coordinate system. Will be overwritten to contain the resulting visible rectangle, expressed in global (root) coordinates

So, if You're providing empty rectangle in the child coordinate then it can be translated only into empty visible rectagle, right?

For me this code seems to work:

recordListview.setOnScrollListener(new AbsListView.OnScrollListener() {
    @Override
    public void onScrollStateChanged(final AbsListView view, final int scrollState) {
        if (scrollState == SCROLL_STATE_IDLE) {
            final View child = recordListview.getChildAt(view.getFirstVisiblePosition());

            if (child == null) {
                return;
            }

            final Rect r = new Rect (0, 0, child.getWidth(), child.getHeight());
            final double height = child.getHeight () * 1.0;

            recordListview.getChildVisibleRect(child, r, null);
            Log.d("Visible1 ", view.getFirstVisiblePosition() + "  "  + height + "  " + r.height());

            if (Math.abs (r.height ()) < height / 2.0) {
                // show next child
                recordListview.smoothScrollToPosition(view.getFirstVisiblePosition()+1);
                Log.d("Visible1 Location", view.getFirstVisiblePosition() +1+ "");
            } else {
                recordListview.smoothScrollToPosition(view.getFirstVisiblePosition());
                Log.d("Visible1 Location", view.getFirstVisiblePosition()+ "");
            }
        }
    }

    @Override
    public void onScroll(final AbsListView view, final int firstVisibleItem, final int visibleItemCount, final int totalItemCount) {
        // nothing to do here
    }
});

Regarding initial question about determining which view is visible fully and which is not, I would suggest to use the following code:

@Override
public void onScrollStateChanged(final AbsListView view, final int scrollState) {
    if (scrollState == SCROLL_STATE_IDLE) {

        final int firstVisiblePosition = view.getFirstVisiblePosition();
        View child = recordListview.getChildAt(firstVisiblePosition);

        if (child == null) {
            return;
        }

        if (mListItemsOnScreen == 0) {
            // number of total visible items, including items which are not fully visible
            mListItemsOnScreen = (int) Math.ceil(((double)recordListview.getHeight()) / (child.getHeight() + recordListview.getDividerHeight()));
        }

        final Rect r = new Rect(0, 0, child.getWidth(), child.getHeight());
        final double height = child.getHeight();

        recordListview.getChildVisibleRect(child, r, null);
        Log.d("Visible1", " items till " + firstVisiblePosition + " are not visible");
        // Check top item
        Log.d("Visible1", firstVisiblePosition + " is visible " + (r.height() >= height ? " fully" : "partially"));
        // check bottom item
        child = recordListview.getChildAt(firstVisiblePosition + mListItemsOnScreen);

        if (child != null) {
            r.set(0, 0, child.getWidth(), child.getHeight());
            recordListview.getChildVisibleRect(child, r, null);

            Log.d("Visible1", " items from " + firstVisiblePosition + " till " + (firstVisiblePosition + mListItemsOnScreen) + " are fully visible");
            Log.d("Visible1", (firstVisiblePosition + mListItemsOnScreen) + " is visible " + (r.height() >= height ? " fully" : "partially"));
        } else {
            Log.d("Visible1", " items from " + firstVisiblePosition + " till " + (firstVisiblePosition + mListItemsOnScreen) + " are fully visible");
            Log.d("Visible1", (firstVisiblePosition + mListItemsOnScreen) + " is invisible ");
        }
    }
}