¿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é?

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.

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) { } 
  • ¿Cómo desactivan otros botones cuando presiono el botón?
  • Establecer OnClick Listener en el botón dentro de la vista de lista en android
  • Forma personalizada real del botón
  • ¿Cómo dejar pasar el evento a container en android?
  • Java - Android - Split Activity / Class en varios archivos para una mejor organización (solución)
  • DialogInterface vs Ver OnClickListeners
  • Android: Configurar onClickListener en una parte del texto de un TextView - Problema
  • Capturar LinearLayout eventos onClick con ImageButton dentro de él
  • Android AlertDialog en onClickListener obtener padre Ver
  • Fragmento implementa OnClickListener
  • Android OnClickListener no disparar para el botón en Layout independiente
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.