Android setSelection不更改ListView位置

Android setSelection不更改ListView位置,android,listview,orientation,Android,Listview,Orientation,我在ListView setSelection方法方面遇到了一些问题。在横向和纵向之间切换时,我试图使列表视图保持在相同的索引。但是,每次我旋转并重新创建活动时,listview都从顶部开始。我使用的代码如下: @Override public void onSaveInstanceState(Bundle savedInstanceState) { ArrayList<Integer> indices = new ArrayList<Integer>();

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

@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);
}
@覆盖
SaveInstanceState上的公共无效(Bundle savedInstanceState){
ArrayList索引=新的ArrayList();
for(整数i:f_checkedMessages){
增加(i);
}
savedInstanceState.putIntegerArrayList(“已检查消息条件”,索引);
savedInstanceState.putInt(“ListIndex”,f_listView.getFirstVisiblePosition());
}
@凌驾
RestoreInstanceState上的公共无效(Bundle savedInstanceState){
ArrayList index=savedInstanceState.getIntegerArrayList(“CheckedMessageIndicates”);
for(整数i:索引){
f_checkedMessages.添加(i);
}
int listIndex=savedInstanceState.getInt(“listIndex”);
f_listView.setSelection(listIndex);
}
我已使用调试器验证listIndex是正确的值。还应该提到的是,在更改方向时,选中的listview项会保持不变。我知道setSelected仅在触摸模式下选择listview项,但文档中说,无论是否在触摸模式下,此方法都将对齐listview

有人知道为什么这样做不起作用,或者有没有更好的方法


谢谢,非常感谢你的帮助

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

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

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

如果需要进一步帮助,在几个小时后,我用a-IV的相同示例解决了这个问题,但做了一些修改

首先,在执行runnable之前调用方法clearFocus()是非常重要的

当调用方法setSelection(index)时,具有触摸模式控制器的设备没有视觉效果,但通常会选择该项。因此,有必要调用requestFocusFromTouch()以启用由方法setSelection(index)引起的可视更改

在调用setSelection(index)之后,调用requestFocus(),以便为视图提供焦点

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


我希望我能帮忙

如果您的ListView位于ListFragment中,只需调用。

您可以使用下面的代码来解决此问题

@Override
protected void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    listView = getListView();
    listView.setAdapter(adapter);

    listView.post(new Runnable()
    {
        public void run()
        {
            listView.setSelection(position);
        }
    });
} 

或请参阅以下连结:


我希望你能找到解决办法。谢谢你

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

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

看起来很糟糕,但这种方式在触摸和非触摸模式下都能工作。

我的问题是我打电话了 adapter.notifyDataSetChanged(); 打完电话 mListView.setSelection(0)

现在我按顺序打电话:

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

它正在工作。

我想我找到了最好的解决方案,而不使用post a Runnable:

list.setAdapter(adapter);
list.setSelection(list.getCount() - 1);
使用此代码

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

下面是相关的线程:我认为,要关注
run()
最后一行的视图可能是其他视图,不一定与您选择的
ListView
相同。不管怎样,这就是我需要做的,而且似乎很有效。非常感谢。不过,要让列表滚动到某个特定元素,必须直接调整焦点,这听起来还是很奇怪的。我认为这是安卓系统中另一个不幸的设计决定,但这可能只是因为处理它而产生的挫败感。这对我来说是有效的。谢谢但让我恼火的是,像list.setSelection(x)这样的调用应该是直截了当的,根本不能像预期的那样工作,而且没有很好的文档证明在调用它之前必须采取一些步骤。啊。。。制作这样一个功能的目的是什么?为什么不在其中包含requestFocus…这对我来说很有用,但ListView项目会高亮显示,就好像用户用手指按住指定的ListView项目一样,只要我触摸屏幕,该项目就不再被选中(高亮显示)。是否有任何解决方案可以通过手指轻触而不是按住来设置选择?这与这个问题如何相关?
sp2.setAdapter(sp2.getAdapter());
        sp2.getAdapter().notifyDataSetChanged();
        sp2.setSelection(0, false);