Android ListView setSelection()似乎不起作用

时间:2009-09-18 19:12:51

标签: android listview

我有ListActivity实现onListItemClick()并调用该类的doSomething()函数。后者包含l.setSelection(position),其中lListView对象。

现在有一个onClickListener()听取按钮点击,它会执行某些操作并且也会调用doSomething()

在第一种情况下,所选项目的位置恰当,但在后一种情况下,没有任何反应。

有关这种奇怪行为以及如何使其发挥作用的任何线索?

16 个答案:

答案 0 :(得分:103)

也许你需要使用功能:

ListView.setItemChecked(int position, boolean checked);

答案 1 :(得分:65)

在调用requestFocusFromTouch()方法

之前使用setSelection()

答案 2 :(得分:31)

我知道这是一个老问题,但我遇到了类似的问题,我以这种方式解决了这个问题:

mListView.clearFocus();
mListView.post(new Runnable() {
    @Override
    public void run() {
        mListView.setSelection(index);
    }
});

答案 3 :(得分:15)

您可能需要将setSelection()包裹在post Runnable {{1}}(reference)中。

答案 4 :(得分:13)

setSelection()不一定有视觉冲击力。仅当您使用D-pad /轨迹球导航列表时,才会显示选择栏。如果您点击屏幕上点击某些内容,选择栏会短暂显示并消失。

因此,setSelection()只会在活动未处于触摸模式时产生视觉影响(即,用户做的最后一件事是使用D-pad /轨迹球)。

根据您提供的描述,我不是100%肯定这会解释您的现象,但我认为值得一试......

答案 5 :(得分:6)

如果您为ListView使用适配器,请将此代码添加到适配器:

public class MyAdapter extends
        ArrayAdapter<MyClass> {


    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        if (convertView == null) {
            LayoutInflater inflator = (LayoutInflater) getContext()
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            rowView = inflator.inflate(R.layout.my_adapter, null);
        } else {
            rowView = (View) convertView;
        }

        //...

        // set selected item
        LinearLayout ActiveItem = (LinearLayout) rowView;
        if (position == selectedItem)
        {
            ActiveItem
                    .setBackgroundResource(R.drawable.background_dark_blue);

            // for focus on it
            int top = (ActiveItem == null) ? 0 : ActiveItem.getTop();
            ((ListView) parent).setSelectionFromTop(position, top);
        }
        else
        {
            ActiveItem
                    .setBackgroundResource(R.drawable.border02);
        }

    }

    private int selectedItem;

    public void setSelectedItem(int position) {
        selectedItem = position;
    }

}

在您的活动中:

myAdapter.setSelectedItem(1);

答案 6 :(得分:4)

我有一个非常大的WebContent请求。当我在onCreateView中使用代码时,Listview甚至没有完成加载。 我把它放在我的AsyncTask的onPostExecute中。

            //Get last position in listview
        if (listView != null && scrollPosition != 0) {
            listView.clearFocus();
            listView.requestFocusFromTouch();
            listView.post(new Runnable() {
                @Override
                public void run() {
                    listView.setItemChecked(scrollPosition, true);
                    listView.setSelection(scrollPosition);
                }
            });
        }

别忘了在Click上设置检查项目;)

答案 7 :(得分:3)

我来电话

listView.notifyDataSetChanged();
listView.requestFocusFromTouch();

然后

 listView.setSelection(position);

解决了这个问题。

如果你在runnable中这样做,它可以在不调用requestFocusFromTouch()的情况下工作,但是ListView的旧位置会显示为sekound。

答案 8 :(得分:2)

也许你应该使用ListView的smoothScrollToPosition(int position)方法

答案 9 :(得分:0)

在我的情况下,smoothScrollToPosition(int position)工作,你还可以告诉我如何将滚动位置设置到列表的中心。它出现在可见项目的底部。

答案 10 :(得分:0)

对我而言,它有助于设置 ListView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);ListView.CHOICE_MODE_MULTIPLE
然后
ListView.setSelection(position)ListView.setItemChecked(position, true);
工作正常

答案 11 :(得分:0)

在我的案例中找到了一个解决方案。我没有使用Runnable,因为我的类正在扩展ListFragment。我必须做的是让我的索引成为最终的; 最终指数= 5; mListView.setSelection(索引);

答案 12 :(得分:0)

我发现有时setSelection不起作用,因为我将listView的属性“android:height”设置为“wrap_content”。

我的应用程序不起作用的时间是当listView变得可滚动时不可滚动。

例如,如果我的应用是“文件浏览器应用”。当我的列表小于时,让我们说6,那么它是不可滚动的。现在我返回到父目录,它有11个对象,我想将选择设置到某个位置,它在这里不起作用。

to\from    |    Scrollable  | non-Scrollable

可滚动| O | O(当然)

不可滚动| X | O(当然)

我不想使用post(Runnable),因为会有延迟。

==================================

答案:

您可以尝试将“android:height”设置为“match_parent”

上帝,它花了三天时间。

答案 13 :(得分:0)

当使用发布到setSelection()时,ListView会首先看到,然后滚动到该位置,感谢&#34; 魏经轩&#34;,然后布局实际上会影响setSelection(),因为setSelection()会调用setSelectionFromTop(int position, int y),还有另一种解决方法。

listView.setAdapter(listView.getAdapter());
listView.setSelection(123);

答案 14 :(得分:0)

只需尝试此代码

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

答案 15 :(得分:0)

您可以尝试以下两种方法:
解决方案A:

    mListView.post(new Runnable() {
        @Override
        public void run() {
            if (null != mListView) {
                mListView.clearFocus();
                mListView.requestFocusFromTouch();
                mListView.setSelection(0);
            }
        }
    });

在某些复杂情况下,此解决方案将在Android 8.x中带来一些新问题。
此外,它可能会导致意外的onFocusChange()。

解决方案B: 定义自定义视图扩展了ListView。覆盖方法handleDataChanged()。然后setSelection(0)。在CustomListView中:

@Override
protected void handleDataChanged() {
    super.handleDataChanged();
    if (null != mHandleDataChangedListener){
        mHandleDataChangedListener.onChanged();
    }
}
HandleDataChangedListener mHandleDataChangedListener;

public void setHandleDataChangedListener(HandleDataChangedListener handleDataChangedListener) {
    this.mHandleDataChangedListener = handleDataChangedListener;
}

public interface HandleDataChangedListener{
    void onChanged();
}

活动中:

    mListView.setHandleDataChangedListener(new CustomListView.HandleDataChangedListener() {
        @Override
        public void onChanged() {
            mListView.setHandleDataChangedListener(null);
            mListView.setSelection(0);
        }
    });
    mAdapter.notifyDataSetChanged();

好,就是这样。