tutorial recyclerview developer custom arrayadapter android listview

recyclerview - listview android eclipse



Android ListView child View setEnabled() y setClickable() no hacen nada (4)

Estoy haciendo un trabajo AsyncTask después de que el usuario hace clic en un elemento en mi ListView . Me gustaría desactivar el artículo para que no se pueda hacer clic dos veces. He simplificado el oyente clic para contener solo este método, pero todavía no hace nada por mí, la vista se ve igual y se deja felizmente clic otra vez, para mi enojo.

public void onItemClick(AdapterView<?> parent, View clickedView, int position, long id) { item = (Episode) parent.getItemAtPosition(position); clickedView.setClickable(false); clickedView.setEnabled(false); clickedView.invalidate(); }

Mi vista para cada fila es LinearLayout personalizado con dos TextView s.


Hay varias razones por las que su enfoque no funcionará.

1) onItemClick solo se llama debido a eventos de teclado. Específicamente KeyKevent.KEYCODE_ENTER . No se llama a través de ninguna otra ruta de código. Por lo tanto, manejar eso incluso solo es útil si está intentando proporcionar compatibilidad con teclado / trackball.

Código fuente de Android para los métodos relevantes de AbsListView:

public boolean onKeyUp(int keyCode, KeyEvent event) { switch (keyCode) { case KeyEvent.KEYCODE_DPAD_CENTER: case KeyEvent.KEYCODE_ENTER: if (!isEnabled()) { return true; } if (isClickable() && isPressed() && mSelectedPosition >= 0 && mAdapter != null && mSelectedPosition < mAdapter.getCount()) { final View view = getChildAt(mSelectedPosition - mFirstPosition); if (view != null) { performItemClick(view, mSelectedPosition, mSelectedRowId); view.setPressed(false); } setPressed(false); return true; } break; } return super.onKeyUp(keyCode, event); } public boolean performItemClick(View view, int position, long id) { if (mOnItemClickListener != null) { playSoundEffect(SoundEffectConstants.CLICK); mOnItemClickListener.onItemClick(this, view, position, id); return true; } return false; }

2) Está configurando la información clicable directamente en la vista. Las vistas que se muestran a través de cualquier AdapterView son etéreas. Se crean a petición de AdapterView y solo existen mientras AdapterView necesite. No debe establecer ningún dato sobre ellos que desee conservar. Puede llamar a setEnabled y setClickable para obtener un efecto inmediato, pero si desea que la información persista, debe almacenarla en alguna parte a la que el Adapter tenga acceso para que pueda recrearse cuando AdapterView crear la View para esa posición.

3) onClick manejar el evento onClick para que se onClick clic en la View real. Donde manejas esto depende de ti. El mejor lugar es probablemente su Adapter que luego puede o no pasarlo a su Activity dependiendo de cuáles sean sus requisitos de diseño. Ahí es donde necesitas manejar tus eventos táctiles.

Vea este código para una Actividad simple:

public class PhoneTesting extends Activity { private static final String TAG = "PhoneTesting"; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); Log.d(TAG, "onCreate()"); List<String> strings = new ArrayList<String>(); for(int i = 0 ; i < 20 ; i++) { strings.add(Integer.toString(i)); } ListView list = (ListView) this.findViewById(R.id.list); list.setAdapter(new SimpleAdapter(this, 0, 0, strings)); list.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { Log.d(TAG, "onItemClick: " + id); } }); } class SimpleAdapter extends ArrayAdapter<String> implements OnClickListener { SimpleAdapter(Context context, int resource, int textViewResourceId, List<String> objects) { super(context, resource, textViewResourceId, objects); } SimpleAdapter(Context context, int resource, int textViewResourceId, String[] objects) { super(context, resource, textViewResourceId, objects); } SimpleAdapter(Context context, int resource, int textViewResourceId) { super(context, resource, textViewResourceId); } SimpleAdapter(Context context, int textViewResourceId, List<String> objects) { super(context, textViewResourceId, objects); } SimpleAdapter(Context context, int textViewResourceId, String[] objects) { super(context, textViewResourceId, objects); } SimpleAdapter(Context context, int textViewResourceId) { super(context, textViewResourceId); } @Override public View getView(int position, View convertView, ViewGroup parent) { TextView b = position % 2 == 0 ? new Button(this.getContext()) : new TextView(this.getContext()); b.setText(this.getItem(position)); b.setOnClickListener(this); return b; } @Override public void onClick(View v) { TextView t = (TextView) v; Log.d(TAG, "onClick: " + t.getText()); } @Override public boolean isEnabled(int position) { return position % 2 == 0 ? false : true; } } }

Si ejecuta este código y hace clic en cualquiera de las View en ListView , verá en la salida de logcat que solo se está llamando a onClick . onItemClick nunca se llama.

También tenga en cuenta que isEnabled en el adaptador no parece tener efecto si se puede hacer clic en la View o no. No estoy seguro de cómo interpretar eso. Sin embargo, lo que eso significa es que si desea controlar esa propiedad de la View el Adapter necesita establecerla cuando se crea la View y mantener de alguna manera esa información.


Por lo tanto, también puede estar usando un adaptador personalizado. Si lo hace, anule estos métodos:

public boolean areAllItemsEnabled() { return false; } public boolean isEnabled(int position) { // return false if position == position you want to disable }

Luego, cuando reciba un clic, dígale al adaptador en qué se hizo clic en el último elemento y devuelve falso en isEnabled para esa posición. Por ejemplo, puede tener un método como este en su adaptador:

private int mLastClicked; public void setLastClicked(int lastClicked){ mLastClicked = lastClicked; }


Si desea desactivar el elemento, haga clic en vista de lista use clickedView.setClickable(true);


Tu problema no está completamente claro. Estoy interpretando su pregunta como que espera que onItemClick() no se llame en función de sus setEnabled() y setClickable() .

No me sorprende que no funcione, ya que onItemClick() es algo que hace ListView , no la vista secundaria. Intente anular areAllItemsEnabled() y isEnabled() en su ListAdapter en su lugar.