Come sapere quale vista all'interno di un object ListView specifico che è stato cliccato

Sto avendo un ListView con il mio personalizzato adattatore derivato da un BaseAdapter . Ogni elemento del ListView ha sotto elementi come ImageView e TextView .

Come faccio a sapere quale di questi sottotitoli l'utente ha fatto clic? Ad esempio, è ansible colbind un ascoltatore nella function getView , o potrebbe essere un problema?

  • onUpdate () variabile intilizzata sono null in onReceive della class widget
  • onCreateView () non viene chiamato immediatamente dopo FragmentTransaction.commit ()
  • Come posso aspettare per 10 secondi senza bloccare l'applicazione UI in Android
  • Impostare TextSize su un text in filatore in android in modo programmato
  • Trovare un file di driver del touchscreen Android
  • Come convertire un TextView in EditText in android?
  • / Henrik

    Modifica: Attualmente ho un onItemClick nell'attività che contiene il ListView . C'è un buon modo per sapere quale voce secondaria in un elemento specifico di ListView che è stato premuto controllando i params nel onItemClick .

     @Override public void onItemClick(AdapterView<?> a, View v, int pos, long id) { . . } 

  • FilterView ListView con l'adattatore personalizzato (object)
  • Testo e image di ArrayAdapter
  • Android, CustomAddAdapter ottiene TextView-Text
  • Filtro per android ListView - carattere spaziale
  • Deseleziona tutte le caselle di controllo in un ListView personalizzato
  • Come gli elementi GridLayout vengono dall'adattatore (elenco / image) in App Android
  • 5 Solutions collect form web for “Come sapere quale vista all'interno di un object ListView specifico che è stato cliccato”

    Puoi farlo. È necessario modificare il metodo getView:

     @Override public View getView(final int position, View row, final ViewGroup parent) { ... YourWrapper wrapper = null; if (row == null) { row = getLayoutInflater().inflate(R.layout.your_row, parent, false); wrapper = new YourWrapper(row); row.setTag(wrapper); } else { wrapper = (YourWrapper) row.getTag(); } wrapper.yourSubView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // do something } ... } 

    Ho usato un'idea dalla Hobby Programming di Miga .

    La chiave chiama performItemClick () dal nuovo ascoltatore onClick. Questo passa il clic su attraverso l'onItemClick () che viene già utilizzato per la visualizzazione di liste. È così veloce e facile, mi sento come se sto imbrogliando.

    Ecco il getView (), dalla scheda di elenco:

     @Override public View getView(final int position, View convertView, final ViewGroup parent) { // Check if an existing view is being reused, otherwise inflate the view if (convertView == null) { convertView = LayoutInflater.from(getContext()).inflate(R.layout.one_line, parent, false); } // This chunk added to get textview click to register in Fragment's onItemClick() // Had to make position and parent 'final' in method definition convertView.findViewById(R.id.someName).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { ((ListView) parent).performItemClick(v, position, 0); } }); // do stuff... } 

    E l'onItemClick ():

     @Override public void onItemClick(AdapterView adapterView, View view, int position, long id) { long viewId = view.getId(); if (viewId == R.id.someName) { Toast.makeText(getActivity(), "someName item clicked", Toast.LENGTH_SHORT).show(); } else { Toast.makeText(getActivity(), "ListView clicked: " + id, Toast.LENGTH_SHORT).show(); } } 

    ListView ricicla gli oggetti di row visualizzazione e assegna loro dati freschi quando viene chiamato "getView", quindi l'approccio da utilizzare è quello di aggiungere un listener nella function getView. Ecco un esempio di codice da un'applicazione che mostra come è fatto:

     private class DeletePlayerAdapter extends ArrayAdapter<Player> { Context context; int layoutResourceId; ArrayList<Player> data; public DeletePlayerAdapter(Context context, int layout, ArrayList<Player> list) { super(context, layout, list); this.layoutResourceId = layout; this.context = context; this.data = list; } @Override public View getView(final int position, View convertView, ViewGroup parent) { View row = convertView; PlayerHolder holder = null; if (row == null) { LayoutInflater inflater = ((Activity) context) .getLayoutInflater(); row = inflater.inflate(layoutResourceId, parent, false); holder = new PlayerHolder(); holder.player_name = (TextView) row .findViewById(R.id.player_name); holder.player_number = (TextView) row .findViewById(R.id.player_number); holder.seeded_button = (ImageButton) row .findViewById(R.id.delete_toggle); holder.player_name.setTypeface(tf); holder.player_number.setTypeface(tf); row.setTag(holder); players_arrays.get(position).marked_for_delete = false; } else { Log.d("PLAYER_ADAPTER", "NOT_NULL ROW"); holder = (PlayerHolder) row.getTag(); } holder.seeded_button.setOnClickListener(new OnClickListener() { // // Here is the magic sauce that makes it work. // private int pos = position; public void onClick(View v) { ImageButton b = (ImageButton) v; if (b.isSelected()) { b.setSelected(false); players_arrays.get(pos).marked_for_delete = false; } else { b.setSelected(true); players_arrays.get(pos).marked_for_delete = true; } } }); Player p = data.get(position); holder.player_name.setText(p.name); holder.player_number.setText(String.valueOf(position+1)); holder.seeded_button .setSelected(players_arrays.get(position).marked_for_delete); return row; } } static class PlayerHolder { TextView player_number; TextView player_name; ImageButton seeded_button; } 

    Poiché si dispone solo di un ImageView e di un TextView, è ansible modificare il tuo ImageView in ImageButton. È quindi ansible aggiungere un listener sull'AppleButton che verrà chiamato se l'utente fa clic sull'image. Se scatta in un altro punto all'interno dell'elemento (incluso il TextView), verrà richiamato l'onItemclicklistener. Questo è molto più semplice penso.

    Ho trovato una soluzione generica e riutilizzabile. Invece di estendere un adattatore di elenco di calcestruzzo e di modificare il metodo getView() , ho creato una nuova class che implementa l'interface di ListAdapter che inoltra quasi each cosa ad un altro ListAdapter exception di getView() . Sembra così:

     public class SubClickableListAdapter implements ListAdapter { public static interface OnSubItemClickListener { public void onSubItemClick(View subView, int position); } private ListAdapter other; private SparseArray<OnSubItemClickListener> onClickListeners; public SubClickableListAdapter(ListAdapter other) { this.other = other; onClickListeners = new SparseArray<OnSubItemClickListener>(); } public void setOnClickListener(int id, OnSubItemClickListener listener) { onClickListeners.put(id, listener); } public void removeOnClickListener(int id) { onClickListeners.remove(id); } @Override public View getView(final int position, View convertView, ViewGroup parent) { View view = other.getView(position, convertView, parent); for(int i = 0; i < onClickListeners.size(); i++) { View subView = view.findViewById(onClickListeners.keyAt(i)); if (subView != null) { final OnSubItemClickListener listener = onClickListeners.valueAt(i); if (listener != null) { subView.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { listener.onSubItemClick(v, position); } }); } } } return view; } // other implemented methods } 

    Gli altri methods implementati sembrano semplicemente il seguente:

     @Override public Object getItem(int position) { return other.getItem(position); } 

    Per usarlo, semplicemente istanziarlo fornendo qualsiasi altro ListAdapter (ad esempio ArrayAdapter o SimpleCursorAdapter o qualsiasi altra cosa). Quindi call setOnClickListener() per each vista in cui si desidera ascoltare i clic, dando il suo id nel parametro id e il tuo ascoltatore nel parametro listener . Per get l'ID di row per la row cliccata, call il getItemIdAtPosition(position) del tuo ListView (che devi avere in qualche modo, perché non viene dato come parametro alla tua richiamata, ma non dovrebbe essere un grande problema nella maggior parte dei casi).

    Il vantaggio di questa soluzione è che può essere utilizzato con qualsiasi ListAdapter . Quindi, se la tua applicazione ha parecchi ListView , ognuno che utilizza diverse viste sottostanti, o addirittura adattatori diversi, non è necessario creare una nuova class di adattatori per ciascuna di esse.

    Il problema con questo è lo stesso di tutte le altre soluzioni: l' OnItemClick() del ListView non verrà chiamato se si fa clic su una vista che hai registrato un listener. Per le visualizzazioni che non hai registrato un listener, questo callback verrà chiamato però. Così, per esempio, hai un'attività per la tua voce di elenco che contiene due campi di text e un button e registri un listener per il button, quindi cliccando sul button non chiamerai l' OnItemClick() del ListView ma il tuo invece di ricall. Facendo clic su un altro posto, chiama OnItemClick() .

    L'Android è un fan Android di Google, tutto su telefoni Android, Android Wear, Android Dev e applicazioni Android Games e così via.