【问题标题】:setSelection not changing ListView positionsetSelection 不改变 ListView 位置
【发布时间】:2011-08-10 22:56:12
【问题描述】:

我在使用 ListView setSelection 方法时遇到了一些问题。在横向和纵向之间切换时,我试图让我的列表视图保持相同的索引。但是,每次我旋转并重新创建活动时,列表视图都会从顶部开始。我使用的代码如下:

@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
    ArrayList<Integer> indices = new ArrayList<Integer>();
    for (Integer i : f_checkedMessages) {
        indices.add(i);
    }
    savedInstanceState.putIntegerArrayList("CheckedMessageIndices", indices);
    savedInstanceState.putInt("ListIndex", f_listView.getFirstVisiblePosition());
}

@Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
    ArrayList<Integer> indices = savedInstanceState.getIntegerArrayList("CheckedMessageIndices");
    for (Integer i : indices) {
        f_checkedMessages.add(i);
    }
    int listIndex = savedInstanceState.getInt("ListIndex");
    f_listView.setSelection(listIndex);
}

我已经使用调试器来验证 listIndex 是正确的值。还应该提到的是,选中的列表视图项目在改变方向时仍然存在。我知道 setSelected 仅在触摸模式下选择列表视图项,但文档说无论是否处于触摸模式,此方法都会对齐列表视图。

有谁知道为什么这不起作用或者是否有更好的方法来解决这个问题?

谢谢,非常感谢您的帮助!

【问题讨论】:

    标签: android listview orientation


    【解决方案1】:

    如果有进一步的帮助,在解决这个问题几个小时后,我设法使用相同的 A-IV 示例解决了它,并进行了一些修改。

    首先,方法 clearFocus() 必须在执行 runnable 之前调用。

    具有触控模式控制器的设备在调用 setSelection(index) 方法时没有视觉效果,但该项目通常会被选中。因此,需要调用 requestFocusFromTouch() 来启用 setSelection(index) 方法引起的视觉变化。

    调用setSelection(index)后,调用requestFocus(),让view获得焦点。

    @Override public void onRestoreInstanceState(Bundle savedInstanceState) {
    ...
    final int listIndex = savedInstanceState.getInt("ListIndex");
    f_listView.clearFocus();
    f_listView.post(new Runnable() {
        @Override
        public void run() {
            listView.requestFocusFromTouch();
            listView.setSelection(listIndex);
            listView.requestFocus();
        }
    });
    

    }

    希望我能帮上忙!

    【讨论】:

    • 关注run() 的最后一行的视图可能是其他视图,我认为不一定与您选择的ListView 相同。无论如何,这就是我需要做的,并且似乎有效。谢谢你。尽管如此,让列表滚动到特定元素必须直接调整焦点,这听起来很奇怪。我会将此归类为 Android 中另一个不幸的设计决定,但这可能只是出于处理它所增加的挫败感。
    • 它对我有用。谢谢。但是让我很恼火的是,应该简单的调用,比如 list.setSelection(x) 根本不能按预期工作,而且在调用它之前你必须采取一些步骤也没有很好的记录。啊……制作一个像这样工作的函数的目的是什么,为什么不在其中包含 requestFocus ……
    • 这对我有用,但 ListView 项目突出显示,就好像用户将手指放在指定的 ListView 项目上一样,一旦我触摸屏幕,该项目就不再被选中(突出显示)。任何解决方案,以便通过手指点击而不是按住来设置选择?
    【解决方案2】:

    你可以使用下面的代码来解决这个问题

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        listView = getListView();
        listView.setAdapter(adapter);
    
        listView.post(new Runnable()
        {
            public void run()
            {
                listView.setSelection(position);
            }
        });
    } 
    

    listView.setAdapter(adapter);
    listView.setSelection(position);
    adapter.notifyDataSetChanged(); 
    

    或者请参考以下链接:

    http://www.codeproject.com/Tips/514527/ListActivity-setSelection-within-onCreate

    我希望你能得到解决方案。谢谢你

    【讨论】:

      【解决方案3】:

      您不能在数据更改后直接设置选择。试试这个:

      @Override public void onRestoreInstanceState(Bundle savedInstanceState) {
          ...
          final int listIndex = savedInstanceState.getInt("ListIndex");
          f_listView.post(new Runnable() {
              @Override
              public void run() {
                  listView.setSelection(listIndex);
              }
          });
      }
      
      【解决方案4】:

      如果您处于 SDK 级别 >= 8,也许您应该使用“smoothScrollToPosition(int position)”。

      【讨论】:

        【解决方案5】:

        对我来说问题是我打电话给 适配器.notifyDataSetChanged(); 打电话后 mListView.setSelection(0);

        现在我按这个顺序打电话:

         adapter.notifyDataSetChanged();
         mListView.setSelection(0);
        

        它正在工作。

        【讨论】:

        • 这与这个问题有什么关系?
        【解决方案6】:

        如果您的 ListView 在 ListFragment 中,只需调用 setSelection()

        【讨论】:

          【解决方案7】:

          对我有用的唯一解决方案是:

              mListView.postDelayed(new Runnable() {
                  @Override
                  public void run() {
                      mListView.setSelection(index);
                  }
              }, 300);
          

          看起来很糟糕,但是这样它在触摸和非触摸模式下都可以工作。

          【讨论】:

            【解决方案8】:

            我认为我找到了最好的解决方案,而不使用发布 Runnable:

            list.setAdapter(adapter);
            list.setSelection(list.getCount() - 1);
            

            【讨论】:

              【解决方案9】:

              使用此代码,

              sp2.setAdapter(sp2.getAdapter());
                      sp2.getAdapter().notifyDataSetChanged();
                      sp2.setSelection(0, false);
              

              【讨论】:

                猜你喜欢
                • 2013-06-11
                • 1970-01-01
                • 1970-01-01
                • 2014-02-07
                • 1970-01-01
                • 2015-12-16
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多