Estoy haciendo una costumbre ListView de filas que contienen un CheckBox y un TextView. Antes de utilizar personalizado ListViews con SimpleCursorAdapter, mi onListItemClick() funcionaba bien.

He leído que tengo que añadir un onClickListener a mi TextViews pero, ¿DÓNDE? Y ¿por QUÉ?

Todavía estoy extendiendo ListActivity y pasar un Adapter a setListAdapter(listedPuzzleAdapter);, no soy yo?

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 para hacer de todo elemento de una costumbre ListView clickable entonces, me pareció que la mejor respuesta fue la dada por @Luksprog. El onListItemClick de mi ListActivity fue suficiente. Sólo necesitaba para establecer el android:focusable='false' para hacer que funcione.

Ahora, el CheckBox en cada elemento de la ListView debe «estrella» de ese elemento, lo que significa que, accediendo a la base de datos.

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 la v.getTag() se refiere a un no-final de la variable y si lo puedo cambiar la v = vi.inflate(R.layout.puzzles_row, null) no puede ser asignado.
¿Cuál es la mejor manera de resolver esto? Nunca he entendido realmente el entero acuerdo final.

  • lo que quiere onlistitem haga clic en?
  • ¿quieres TextView ClickLisner?
  • Quiero iniciar otra actividad.
InformationsquelleAutor eskalera | 2012-05-16

5 Comentarios

  1. 3

    Si quieres añadir una acción especial para cuando haga clic en el TextView o/y CheckBox de cualquiera de las filas de la ListView, a continuación, agregue un OnCLickListener para aquellos Views en el getView método de su costumbre Adapter:

     @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 quieres hacer una acción cuando un hacer clic en la fila(no importa lo que View de esa fila se ha hecho clic(si se hizo)) sólo utilice el OnItemClickListener en su ListView(o la devolución de llamada onListItemClick en el caso de un ListActivity).

    También, espero que establece android:focusable="false" para la CheckBox(en R.layout.puzzles_row) porque no creo que onListItemClick va a trabajar de otra manera.

    Edición :

    Comenzar el nuevo Activity en el onListItemClick(en el caso de la ListActivity) devolución de llamada si usted desea que se inicie la nueva actividad no importa si el usuario hace 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 el nuevo Activity cuando el usuario hace clic en sólo(por ejemplo) el TextView en un ListView fila, a continuación, inicie la nueva actividad en el onClick método de 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 agregar también el PuzzlesDbAdapter.KEY_ROWID columna de la puzzlesCursor cursor en la fetchData() método:

    //...
    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);
    //...
    • Excelente @Luksprog! Thx mucho. Se esperaba con la casilla seleccionable a false, lo que yo no podía entender. Aún así, yo no entiendo lo que quieres decir con la configuración de la etiqueta para el TextView. ¿Cómo ¿Dónde puedo lanzamiento de la nueva actividad con mi id de elemento?
    • Ver editado mi respuesta(también mira mi getView código del método). Poner el código para el lanzamiento de la nueva Activity dependiendo de lo que estamos tratando de hacer.
    • Thaaaanks tanto @Luksprog, Cristal claro de este tiempo. Finalmente consiguió trabajo. En mi caso fue el primero pero el segundo fragmento resuelto todas mis dudas. Yo sólo tenía que añadir i.putExtra(PuzzlesDbAdapter.KEY_ROWID, id + 1); desde el ArrayList empieza en el 0 a diferencia del Cursor.
    • He hecho un pequeño cambio se refleja en mi EDICIÓN anterior. Todavía hay un poco de duda con respecto a su solución.
    • Usted no entiende completamente mi respuesta. Se establece la position como una etiqueta para la View en el que también se establece que el oyente, por lo que para su CheckBox: star.setTag(new Integer(position));. En el oyente una referencia a la View que se comprobó, es el buttonView parámetro, de modo que debes hacer:Integer realPosition = (Integer) buttonView.getTag();. Usted no tiene ningún tipo de negocio con el v objeto(el final problema viene porque usted está tratando de acceder a una variable de una clase interna anónima).
    • Ok, thx @Luksprog. Perfecto ahora, y, finalmente, trabajar.

  2. 2

    puede asignar un onClickListener en el adaptador, pero es una mala práctica.

    lo que debe hacer, es poner en práctica onItemClick como este:

    @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>);
    }
    • en el interior del adaptador? en la actividad? Ninguno tiene ese método.
    • hazte un favore e implementar el onItemClick y NO el onCLick. está diseñado para las listas
    • Ouch! Por supuesto! Te refieres a que implemente esa interfaz en mi adaptador. Ok, lo siento.
    • No estoy seguro de si has entendido. onItemClick se asignará a la lista en su actividad principal. onClick es para elementos individuales. y puede ser asignada en el getView pero esto es MALAS PRÁCTICAS y no se debe hacer
    • Puede usted por favor decirme por qué es una mala práctica? En una fila de mi listview, necesito 2 botón. Así que tengo QUE implementar onClick en cada botón en el adaptador. Sé que hay problemas con este enfoque, pero yo no conozco ninguna otra manera de hacerlo
  3. 0

    Debe implementar onItemClickListener en el ListView.

    ListView lv = getListView();
    lv.setOnItemClickListener(new OnItemClickListener() {
    });
    • No, el adaptador debe proporcionar los datos para cada elemento, y eso es todo. Escuchar a los eventos es el trabajo de la listView, así que ponga su elemento, haga clic en la lógica de este objeto. He puesto un ejemplo en mi comentario.
  4. 0

    Uso onClick Listner en su adaptador sólo. En su adaptador vas a devolver v que es vista kiond de objeto. Poner allí su onCLickListener.

    por ejemplo, v. setOnCLickListener.

    Estoy manteniendo en mente que desea abrir una actividad en el clic de vista. Y sí, si su ListedPuzzle clase serializable o parcelable puede reenviar todo el objeto, usando el método putextra de la intención de la misma.

    Si no tienes claro con la respuesta me dicen que me va a proporcionar samll fragmento de código

  5. 0
     lstviewemojis.setOnItemClickListener(new AdapterView.OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> arg0, View arg1, int position, long arg3) {
    }

Dejar respuesta

Please enter your comment!
Please enter your name here