Android ListView setSelection () no parece funcionar

Tengo una ListActivity que implementa onListItemClick() y llama a una función doSomething() de la clase. Este último contiene l.setSelection(position) donde l es el objeto ListView .

Ahora hay un onClickListener() escuchando un clic de botón que ejecuta algunas acciones y que también llama a doSomething() .

En el primer caso, el elemento seleccionado se posiciona adecuadamente, pero en el último, nada sucede.

¿Alguna pista sobre este extraño comportamiento y cómo podría hacerlo funcionar?

tal vez necesites usar la función:

 ListView.setItemChecked(int position, boolean checked); 

utilice requestFocusFromTouch() antes de llamar setSelection() método setSelection()

Sé que esta es una vieja pregunta, pero acabo de tener un problema similar que resolví de esta manera:

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

Es posible que deba ajustar setSelection() en una post ed Runnable ( referencia ).

setSelection() no necesariamente tiene impacto visual. La barra de selección solo aparece si usa el D-pad / trackball para navegar por la lista. Si toca en la pantalla para hacer clic en algo, la barra de selección aparece brevemente y desaparece.

Por lo tanto, setSelection() solo tendrá un impacto visual si la actividad no está en modo táctil (es decir, lo último que hizo el usuario fue usar D-pad / trackball).

No estoy 100% seguro de que esto explique su fenómeno dada la descripción que proporcionó, pero pensé que vale la pena intentarlo …

Si usa un adaptador para su ListView, agregue este código a su adaptador:

 public class MyAdapter extends ArrayAdapter { @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; } } 

En tu actividad:

 myAdapter.setSelectedItem(1); 

Tengo una Solicitud muy grande con contenido web. Cuando utilicé el código en onCreateView, Listview no había terminado de cargarse. Lo puse en PostExecute de mi AsyncTask.

  //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); } }); } 

No te olvides de configurar el elemento registrado al hacer clic;)

Tal vez deberías usar el método smoothScrollToPosition (int position) de ListView

Para mi llamada

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

y entonces

  listView.setSelection(position); 

resuelto el problema

si haces eso en un ejecutable, funciona sin llamar a requestFocusFromTouch (), pero la posición anterior de ListView se muestra para un archivo.

En mi caso, funcionó smoothScrollToPosition (int position), ¿puede decirme también cómo establecer esa posición desplazada en el centro de la lista? Apareció en la parte inferior de los elementos visibles.

Para mí, ayudó a establecer
ListView.setChoiceMode(ListView.CHOICE_MODE_SINGLE); o ListView.CHOICE_MODE_MULTIPLE
entonces
ListView.setSelection(position) o ListView.setItemChecked(position, true);
funciona bien

Encontré una solución en mi caso. No estoy usando Runnable ya que mi clase está extendiendo ListFragment. Lo que tuve que hacer es hacer que mi índice sea definitivo; índice final = 5; mListView.setSelection (índice);

Encontré que a veces setSelection no funcionaría porque establecí el atributo “android: height” de listView en “wrap_content”.

Y los momentos en que mi aplicación no funcionará es cuando listView se puede desplazar desde no desplazable.

Por ejemplo, si mi aplicación es “File Browser App”. Cuando mi lista es inferior a, digamos 6, no es desplazable. Ahora vuelvo al directorio padre, y tiene 11 objetos, y quiero establecer la selección en alguna posición, y no funcionará aquí.

 to\from | Scrollable | non-Scrollable 

Desplazable | O | Por supuesto )

no desplazable | X | Por supuesto )

No quiero usar la publicación (Runnable), porque habrá una demora.

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

Responder:

Puede intentar configurar “android: height” como “match_parent”

Dios, pasa tres días.

Cuando use post para setSelection() , primero se verá ListView , luego se desplazará a la posición, gracias a ” 魏經軒 “, luego el diseño realmente afectará a setSelection() , porque setSelection() llama a setSelectionFromTop(int position, int y) , hay otra manera de resolverlo.

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

Simplemente prueba este código

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

Puedes probar 2 formas como estas:
Solución A:

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

En una situación complicada, esta solución traerá algunos problemas nuevos en Android 8.x.
Además, puede causar inesperado onFocusChange ().

Solución B: definir una vista personalizada extiende ListView. Reemplazar el método handleDataChanged (). Luego setSelection (0). En 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(); } 

En actividad:

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

Vale eso es todo.

Para mí, la solución a este problema fue:

 listView.clearChoices();