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.