onListItemClick()
を実装し、クラスのdoSomething()
関数を呼び出すListActivity
があります。後者にはl.setSelection(position)
が含まれます。l
はListView
オブジェクトです。
現在、いくつかのアクションを実行し、onClickListener()
を呼び出すボタンクリックをリッスンするdoSomething()
があります。
前者の場合、選択したアイテムは適切に配置されますが、後者の場合は何も起こりません。
この奇妙な動作についての手がかりと、それをどのように機能させることができますか?
多分あなたは関数を使用する必要があります:
ListView.setItemChecked(int position, boolean checked);
requestFocusFromTouch()
メソッドを呼び出す前にsetSelection()
を使用する
私はこれが古い質問であることを知っていますが、この方法で解決した同様の問題がありました:
mListView.clearFocus();
mListView.post(new Runnable() {
@Override
public void run() {
mListView.setSelection(index);
}
});
post
ed Runnable
( reference )でsetSelection()
をラップする必要がある場合があります。
setSelection()
は必ずしも視覚的な影響を与えません。選択バーは、Dパッド/トラックボールを使用してリスト内を移動する場合にのみ表示されます。画面をタップして何かをクリックすると、選択バーが短時間表示されて消えます。
したがって、setSelection()
は、アクティビティがタッチモードでない場合(つまり、ユーザーが最後にD-pad/trackballを使用した場合)にのみ視覚的な影響があります。
私はこれがあなたの説明を与えられたあなたの現象を説明することを100%確信していませんが、私はそれが一撃の価値があると思いました...
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);
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);
}
});
}
クリック時にチェックインしたアイテムを設定することを忘れないでください;)
私のために
listView.notifyDataSetChanged();
listView.requestFocusFromTouch();
その後
listView.setSelection(position);
問題を解決しました。
runnableでこれを行うと、requestFocusFromTouch()を呼び出さなくても機能しますが、ListViewの古い位置は、sekoundに対して表示されます。
たぶん、ListViewのsmoothScrollToPosition(int position)メソッドを使用する必要があります
PostをsetSelection()
に使用すると、ListView
が最初に表示され、次に位置までスクロールし、「魏經軒」に感謝します。レイアウトは実際にsetSelection()
、setSelection()
はsetSelectionFromTop(int position, int y)
を呼び出すため、別の解決方法があります。
listView.setAdapter(listView.getAdapter());
listView.setSelection(123);
このコードを試してください
listView.setAdapter(adapter);
listView.setSelection(position);
adapter.notifyDataSetChanged();
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日を費やします。
私の場合、smoothScrollToPosition(int position)は機能しましたが、そのスクロール位置をリストの中央に設定する方法を教えてもらえますか。目に見えるアイテムの下部に表示されました。
私にとっては、それが設定するのに役立ちましたListView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
または_ListView.CHOICE_MODE_MULTIPLE
_
それからListView.setSelection(position)
またはListView.setItemChecked(position, true);
正常に動作します
次のような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、それだけです。
私の場合、解決策を見つけました。クラスがListFragmentを拡張しているため、Runnableを使用していません。私がしなければならなかったことは、インデックスを最終的なものにすることです。最終インデックス= 5; mListView.setSelection(index);