【问题标题】:Determining the entry shown is listview确定显示的条目是列表视图
【发布时间】:2013-07-09 07:56:16
【问题描述】:

单击按钮时,我试图在列表视图中发送数据。

但是,我的列表视图一次显示 2 行,一个完整行和一个部分行。有没有办法我可以确定哪一行显示部分显示,哪一行显示完全。

我能够获得仅显示的索引。还有其他方法吗?

@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()+ "");
        }

    }
}
});

【问题讨论】:

  • 你试过 getChildVisibleRect() 吗?
  • @sandrstar 我已经用stackoverflow.com/questions/15338509/… 中显示的示例更新了我的代码。这会导致我的列表视图不再可滚动。
  • 是否调用了 onScroll()?我认为您需要使用 onScrollStateChanged(),检测 SCROLL_STATE_IDLE,然后执行您的逻辑。
  • @sandrstar 是的 onscrolled 被解雇了。但是,r.height 始终为零。

标签: android listview scroll


【解决方案1】:

看来您对getChildVisibleRect() 的文档理解有误。

它提到:

r 输入矩形,在子坐标系中定义。将要 被覆盖以包含生成的可见矩形,表示 在全局(根)坐标中

所以,如果您在子坐标中提供空矩形,那么它只能转换为空的可见矩形,对吧?

对我来说,这段代码似乎有效:

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
    }
});

关于确定哪个视图完全可见,哪个不可见的初始问题,我建议使用以下代码:

@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 ");
        }
    }
}

【讨论】:

  • 嗨,sandstar,我尝试了上面的解决方案。当我从项目 1 滚动到 2 时,从项目 0 滚动到 1 工作正常。列表开始从 1 - 2 - 1 - 2 ... 不确定地移动。 07-10 02:49:46.930: D/Visible1(2772): 1 190.0 190 2 07-10 02:49:46.930: D/Visible1 Location(2772): 1 07-10 02:49:46.980: D/Visible1(2772): 1 190.0 52 2 07-10 02:49:46.980: D/Visible1 Location(2772): 2 07-10 02:49:47.040: D/Visible1(2772): 1 190.0 190 2 07-10 02:49:47.070: D/Visible1 Location(2772): 1 07-10 02:49:47.113: D/Visible1(2772): 1 190.0 52 2
  • 你想达到什么目的?实际上,您的问题是“确定哪一行显示部分显示”-您能够实现吗?
  • 是的,没错。我正在尝试确定显示哪一行,然后滚动到显示最大区域的行。我只是好奇为什么它适用于项目 0 到 1 的滚动而不适用于后续滚动。
  • 我提供了代码来确定哪个视图可见,哪个视图不可见(或部分可见)。我认为 2 items 是一个极端情况,可能 Math.abs (r.height ())
  • 嗨,sandrstar,感谢您的代码。我现在正在尝试它们。你能分享分配给变量 mListItemsOnScreen 的内容吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-14
  • 1970-01-01
  • 2015-12-22
  • 2013-10-26
  • 2015-12-24
  • 2016-06-09
相关资源
最近更新 更多