¿Dónde debo colocar onClickListener en un ListView personalizado?
Estoy haciendo un ListView
personalizado de las filas que contienen un CheckBox
y un TextView
. Antes de usar ListViews
personalizado con SimpleCursorAdapter, mi onListItemClick()
funcionó bien.
He leído que tengo que añadir un onClickListener
a mis TextViews
pero ¿DÓNDE? ¿Y por qué?
- No se puede iniciar la actividad, setOnClickListener
- OnItemClickListener en un ListView dentro de un fragmento no funciona
- Establecer onClickListener a LinearLayout llenado por adaptador personalizado
- ¿Cómo puedo tener EditText con Clickable Spannables y todavía seleccionable por longClick?
- Cómo obtener clics en RecyclerView (NO los niños)
Todavía estoy extendiendo ListActivity
y pasando un Adapter
a setListAdapter(listedPuzzleAdapter);
, ¿No lo soy?
public class PuzzleListActivity extends ListActivity { private PuzzlesDbAdapter mDbHelper; private Cursor puzzlesCursor; private ArrayList<ListedPuzzle> listedPuzzles = null; private ListedPuzzleAdapter listedPuzzleAdapter; private class ListedPuzzleAdapter extends ArrayAdapter<ListedPuzzle> { private ArrayList<ListedPuzzle> items; public ListedPuzzleAdapter(Context context, int textViewResourceId, ArrayList<ListedPuzzle> items) { super(context, textViewResourceId, items); this.items = items; } @Override public View getView(int position, View convertView, ViewGroup parent) { View v = convertView; if (v == null) { LayoutInflater vi = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE); v = vi.inflate(R.layout.puzzles_row, null); } ListedPuzzle lp = items.get(position); if (lp != null) { TextView title = (TextView) v.findViewById(R.id.listTitles); title.setText(lp.getTitle()); CheckBox star = (CheckBox) v.findViewById(R.id.star_listed); star.setChecked(lp.isStarred()); } return v; } } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.puzzles_list); // Create database helper to open connection mDbHelper = new PuzzlesDbAdapter(this); mDbHelper.open(); fetchData(); } private void fetchData() { puzzlesCursor = mDbHelper.fetchAllPuzzles(); startManagingCursor(puzzlesCursor); listedPuzzles = new ArrayList<ListedPuzzle>(); ListedPuzzle lp; puzzlesCursor.moveToFirst(); while (!puzzlesCursor.isAfterLast()) { lp = new ListedPuzzle(); lp.setTitle(puzzlesCursor.getString(puzzlesCursor .getColumnIndex(PuzzlesDbAdapter.KEY_TITLE))); lp.setStarred(puzzlesCursor.getInt(puzzlesCursor .getColumnIndex(PuzzlesDbAdapter.KEY_STARRED)) > 0); listedPuzzles.add(lp); puzzlesCursor.moveToNext(); } listedPuzzleAdapter = new ListedPuzzleAdapter(this, R.layout.puzzles_row, listedPuzzles); setListAdapter(listedPuzzleAdapter); } @Override protected void onListItemClick(ListView l, View v, int position, long id) { super.onListItemClick(l, v, position, id); Intent i = new Intent(this, PuzzleQuestionActivity.class); i.putExtra(PuzzlesDbAdapter.KEY_ROWID, id); startActivity(i); }
EDIT: Mi pregunta era hacer que todo el elemento de un ListView
personalizado haga clic, así que encontré la mejor respuesta fue la dada por @Luksprog. El onListItemClick
de mi ListActivity
era suficiente. Sólo necesitaba configurar el android:focusable='false'
para que funcione.
Ahora, el CheckBox
en cada elemento del ListView
debe "star" ese elemento, lo que significa, accesing el DB.
public View getView(int position, View convertView, ViewGroup parent) { View v = convertView; if (v == null) { LayoutInflater vi = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE); v = vi.inflate(R.layout.puzzles_row, null); } ListedPuzzle lp = items.get(position); if (lp != null) { TextView title = (TextView) v.findViewById(R.id.listTitles); title.setText(lp.getTitle()); CheckBox star = (CheckBox) v.findViewById(R.id.star_listed); star.setChecked(lp.isStarred()); star.setOnCheckedChangeListener(new OnCheckedChangeListener() { public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { Integer realPosition = (Integer) v.getTag(); ListedPuzzle obj = items.get(realPosition); obj.getId(); } }); } return v; }
Pero v.getTag()
refiere a una variable no final y si la cambio no se puede asignar el v = vi.inflate(R.layout.puzzles_row, null)
. ¿Cuál es la mejor manera de resolver esto? Realmente nunca entendí todo el trato final.
- Botón de forma personalizada de Android
- Invocar una llamada de escucha programáticamente en android
- ¿Cómo agregar tiempo al temporizador de cuenta atrás?
- Cómo utilizar el método onClickListener de Button en un ListView
- Parámetro de vista de Android para el método OnClickListener
- Cómo quitar un elemento seleccionado de ListView utilizando CursorAdapter
- ¿Cómo funciona finish () en el evento OnClick?
- Widget de la aplicación de Android listview onclick listener
Si desea agregar una acción especial para cuando haga clic en el TextView
o CheckBox
de cualquiera de las filas de su ListView
continuación, agregue un OnCLickListener
para esas Views
en el método getView
de su Adapter
personalizado:
@Override public View getView(int position, View convertView, ViewGroup parent) { View v = convertView; if (v == null) { LayoutInflater vi = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE); v = vi.inflate(R.layout.puzzles_row, null); } ListedPuzzle lp = items.get(position); if (lp != null) { TextView title = (TextView) v.findViewById(R.id.listTitles); //set as the tag the position parameter title.setTag(new Integer(position)); title.setOnclickListener(new OnCLickListener(){ @Override public void onClick(View v) { // Do the stuff you want for the case when the row TextView is clicked // you may want to set as the tag for the TextView the position paremeter of the `getView` method and then retrieve it here Integer realPosition = (Integer) v.getTag(); // using realPosition , now you know the row where this TextView was clicked } }); title.setText(lp.getTitle()); CheckBox star = (CheckBox) v.findViewById(R.id.star_listed); star.setChecked(lp.isStarred()); } return v; }
Si desea hacer una acción cuando se hace clic en una fila (no importa qué View
de esa fila se haya hecho clic (si se ha hecho clic en él)), simplemente use OnItemClickListener
en su ListView
(o la devolución de llamada onListItemClick
en el caso de ListActivity
).
También, espero que usted fije android:focusable="false"
para el CheckBox
(en R.layout.puzzles_row
) porque no pienso que onListItemClick
trabajará de otra manera.
Editar:
onListItemClick
la nueva Activity
en la devolución de llamada onListItemClick
(en el caso de ListActivity
) si desea iniciar la nueva actividad sin importar dónde el usuario haga clic en una fila :
@Override protected void onListItemClick(ListView l, View v, int position, long id) { Intent i = new Intent(this, PuzzleQuestionActivity.class); i.putExtra(PuzzlesDbAdapter.KEY_ROWID, id); startActivity(i); }
Si, por alguna razón, desea iniciar la nueva Activity
cuando el usuario hace clic solo (por ejemplo) en el TextView
en una fila ListView
, a continuación, inicie la nueva actividad en el método onClick
desde mi código anterior:
//... title.setOnclickListener(new OnCLickListener(){ @Override public void onClick(View v) { Integer realPosition = (Integer) v.getTag(); ListedPuzzle obj = items.get(realPosition); Intent i = new Intent(this, PuzzleQuestionActivity.class); i.putExtra(PuzzlesDbAdapter.KEY_ROWID, obj.getTheId());//see below startActivity(i); } //...
Para que esto funcione tendrás que modificar ListedPuzzle
para añadir también la columna puzzlesCursor
cursor puzzlesCursor
en el método fetchData()
:
//... while (!puzzlesCursor.isAfterLast()) { lp = new ListedPuzzle(); lp.setTitle(puzzlesCursor.getString(puzzlesCursor .getColumnIndex(PuzzlesDbAdapter.KEY_TITLE))); lp.setStarred(puzzlesCursor.getInt(puzzlesCursor .getColumnIndex(PuzzlesDbAdapter.KEY_STARRED)) > 0); lp.setTheId(puzzlesCursor.getLong(puzzlesCursor .getColumnIndex(PuzzlesDbAdapter.KEY_ROWID))); listedPuzzles.add(lp); //...
Puede asignar un onClickListener
en el adaptador, pero es una mala práctica.
Lo que debe hacer es implementar onItemClick
siguiente manera:
@Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { TextView text = parent.getItemAtPosition(position); // DO SOMETHING or in your case //startActivity(new Intent(<the correct intent>); }
Debe implementar onItemClickListener en su ListView.
ListView lv = getListView(); lv.setOnItemClickListener(new OnItemClickListener() { });
Utilice onClick Listner sólo en su adaptador. En su adaptador usted está volviendo v que es kiond de la visión del objeto. Ponga allí su onclickListener.
EgvsetOnCLickListener.
Tengo en cuenta que desea abrir una actividad en un clic de vista. Y sí, si su clase ListedPuzzle es serializable o parcelable puede reenviar todo el objeto usando el método putextra de intención de la misma.
Si usted no está claro con la respuesta dígame que le proporcionará el fragmento de código de samll
lstviewemojis.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> arg0, View arg1, int position, long arg3) { }
- Android cómo guardar la imagen capturada en la galería de teléfonos
- Cómo reemplazar / desinstalar la aplicación de correo electrónico del emulador de Android