【问题标题】:ensure visible on android listview?确保在 android listview 上可见?
【发布时间】:2010-01-01 15:54:12
【问题描述】:

有没有一种方法可以确保 android listview 中的给定项目完全可见?

我希望能够以编程方式滚动到特定项目,例如当我按下按钮时。

【问题讨论】:

    标签: android listview listactivity


    【解决方案1】:

    ListView.setSelection() 将滚动列表,以便所需的项目位于视口内。

    【讨论】:

    • Setselection 将其滚动到视图顶部。我只需要它尽可能少地移动
    • 正如 CodeFusionMobile 指出的那样,这个答案并不准确。因此我不会真的接受它...... :-(
    【解决方案2】:

    试试看:

    public static void ensureVisible(ListView listView, int pos)
    {
        if (listView == null)
        {
            return;
        }
    
        if(pos < 0 || pos >= listView.getCount())
        {
            return;
        }
    
        int first = listView.getFirstVisiblePosition();
        int last = listView.getLastVisiblePosition();
    
        if (pos < first)
        {
            listView.setSelection(pos);
            return;
        }
    
        if (pos >= last)
        {
            listView.setSelection(1 + pos - (last - first));
            return;
        }
    }
    

    【讨论】:

    • listView.smoothScrollToPosition(pos);如果需要,而不是 setSelection(...)。谢谢 jauseg。
    • 嗯。这里至少有一个陷阱:如果您在布局完成之前设置选择 - 将没有最后一个可见位置 (=-1) 并且一切都会中断。您需要确保在布局完成后运行它。否则,它不会按预期工作,而是将选择设置完全错误。
    • 在自定义对话框中的 Listview 的情况下不起作用。请提出建议。
    【解决方案3】:

    我相信你要找的是ListView.setSelectionFromTop()(虽然我参加聚会有点晚了)。

    【讨论】:

      【解决方案4】:

      最近我遇到了同样的问题,将我的解决方案粘贴在这里以防有人需要它(我试图使整个最后一个可见项目可见):

          if (mListView != null) {
              int firstVisible = mListView.getFirstVisiblePosition()
                      - mListView.getHeaderViewsCount();
              int lastVisible = mListView.getLastVisiblePosition()
                      - mListView.getHeaderViewsCount();
      
              View child = mListView.getChildAt(lastVisible
                      - firstVisible);
              int offset = child.getTop() + child.getMeasuredHeight()
                      - mListView.getMeasuredHeight();
              if (offset > 0) {
                  mListView.smoothScrollBy(offset, 200);
              }
          }
      

      【讨论】:

      • 效果很好!尽管我应该提到一个需要更改代码的极端情况:您必须调用 mListView.post( new Runnable() { public void run() { (上面的代码); } ) } );这可以处理您正在修改最后一个孩子的高度的情况(从而使 ListView 的内容更高)。在您尝试滚动到列表的新底部之前,发布一个可运行对象可以让 ListView 有机会自行更新。
      • 不幸的是,ListView.smoothScrollBy 将滚动的数量有一个内部上限。那是因为它在内部模拟了用户投掷。使用这种方法滚动 10 个屏幕的项目只会滚动几个屏幕。
      【解决方案5】:

      我有一个更短且在我看来更好的解决方案:ListView requestChildRectangleOnScreen 方法就是为此而设计的。

      上面的答案确保了该项目将被显示,但有时它会部分显示(即当它位于屏幕底部时)。下面的代码确保显示整个项目并且视图将仅滚动必要的区域:

          private void ensureVisible(ListView parent, View view) {
          Rect rect = new Rect(view.getLeft(), view.getTop(), view.getRight(), view.getBottom());
          parent.requestChildRectangleOnScreen(view, rect, false);
      }
      

      【讨论】:

      • 如果您使用 API 8 或更高版本,ListView smoothScrollToPosition() 方法是更智能的解决方案。
      • Yves 的回答的问题是这个View 不一定存在......如果它不可见,ListView 很可能会丢弃它。确实,smoothScrollToPosition 是一个很好的答案。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多