web-dev-qa-db-ja.com

Android ListView setSelection()は動作しないようです

onListItemClick()を実装し、クラスのdoSomething()関数を呼び出すListActivityがあります。後者にはl.setSelection(position)が含まれます。lListViewオブジェクトです。

現在、いくつかのアクションを実行し、onClickListener()を呼び出すボタンクリックをリッスンするdoSomething()があります。

前者の場合、選択したアイテムは適切に配置されますが、後者の場合は何も起こりません。

この奇妙な動作についての手がかりと、それをどのように機能させることができますか?

65
alkar

多分あなたは関数を使用する必要があります:

ListView.setItemChecked(int position, boolean checked);
104
meizilp

requestFocusFromTouch()メソッドを呼び出す前にsetSelection()を使用する

65
AlexD

私はこれが古い質問であることを知っていますが、この方法で解決した同様の問題がありました:

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

posted Runnablereference )でsetSelection()をラップする必要がある場合があります。

15
kostmo

setSelection()は必ずしも視覚的な影響を与えません。選択バーは、Dパッド/トラックボールを使用してリスト内を移動する場合にのみ表示されます。画面をタップして何かをクリックすると、選択バーが短時間表示されて消えます。

したがって、setSelection()は、アクティビティがタッチモードでない場合(つまり、ユーザーが最後にD-pad/trackballを使用した場合)にのみ視覚的な影響があります。

私はこれがあなたの説明を与えられたあなたの現象を説明することを100%確信していませんが、私はそれが一撃の価値があると思いました...

13
CommonsWare

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
Bobs

Webcontentで非常に大きなリクエストがあります。 onCreateViewでコードを使用したとき、リストビューはロードを完了しませんでした。 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);
                }
            });
        }

クリック時にチェックインしたアイテムを設定することを忘れないでください;)

4
Nick

私のために

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

その後

 listView.setSelection(position);

問題を解決しました。

runnableでこれを行うと、requestFocusFromTouch()を呼び出さなくても機能しますが、ListViewの古い位置は、sekoundに対して表示されます。

3
MaInStReAm

たぶん、ListViewのsmoothScrollToPosition(int position)メソッドを使用する必要があります

2
TaoZang

PostをsetSelection()に使用すると、ListViewが最初に表示され、次に位置までスクロールし、「魏經軒」に感謝します。レイアウトは実際にsetSelection()setSelection()setSelectionFromTop(int position, int y)を呼び出すため、別の解決方法があります。

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

このコードを試してください

  listView.setAdapter(adapter);
  listView.setSelection(position);
  adapter.notifyDataSetChanged(); 
0
Cecil Paul

ListViewの属性「Android:height」を「wrap_content」に設定しているため、setSelectionが機能しない場合があります。

そして、私のアプリが動作しないのは、listViewがスクロール不可からスクロール可能になったときです。

たとえば、私のアプリが「File Browser App」の場合。リストが6よりも小さい場合、6とすると、スクロール不可になります。ここで、親ディレクトリに戻り、11個のオブジェクトがあり、選択をある位置に設定したいのですが、ここでは機能しません。

to\from    |    Scrollable  | non-Scrollable

スクロール可能| O | O(もちろん)

スクロール不可| X | O(もちろん)

Post(Runnable)を使用したくないのは、遅延があるためです。

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

回答:

「Android:height」を「match_parent」に設定してみてください

神様、それは3日を費やします。

0
魏經軒

私の場合、smoothScrollToPosition(int position)は機能しましたが、そのスクロール位置をリストの中央に設定する方法を教えてもらえますか。目に見えるアイテムの下部に表示されました。

0
Bhaumik

私にとっては、それが設定するのに役立ちました
ListView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);または_ListView.CHOICE_MODE_MULTIPLE_
それから
ListView.setSelection(position)またはListView.setItemChecked(position, true);
正常に動作します

0
Lemberg

次のような2つの方法を試すことができます。
ソリューション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();

OK、それだけです。

0
Courysky

私の場合、解決策を見つけました。クラスがListFragmentを拡張しているため、Runnableを使用していません。私がしなければならなかったことは、インデックスを最終的なものにすることです。最終インデックス= 5; mListView.setSelection(index);

0
DevfoMobile