2010-04-01 1 views
14

Sto provando a fare (a scopo di apprendimento) la mia implementazione di un semplice AdapterView in cui gli elementi provengono da un adattatore di base (ImageAdapter da campioni sdk).Extending AdapterView

codice effettivo è come questo:

public class MyAdapterView extends AdapterView<ImageAdapter> implements AdapterView.OnItemClickListener{ 
    private ImageAdapter mAdapter; 
    public MyAdapterView(Context context, AttributeSet attrs, int defStyle) { 
     super(context, attrs, defStyle); 
     initThings(); 
    } 
    private void initThings(){ 
     setOnItemClickListener(this); 
    } 
    @Override 
    public ImageAdapter getAdapter() { 
     // TODO Auto-generated method stub 
     return mAdapter; 
    } 
    @Override 
    public void setAdapter(ImageAdapter adapter) { 
     // TODO Auto-generated method stub 
     mAdapter=adapter; 
     requestLayout(); 
    } 
    View obtainView(int position) { 
     View child = mAdapter.getView(position, null, this); 
     return child; 
    } 
    @Override 
    protected void onLayout(boolean changed, int l, int t, int r, int b) { 
    super.onLayout(changed, l, t, r, b); 
     for(int i=0;i<mAdapter.getCount();i++){ 
      View child = obtainView(i); 
      child.layout(10, 70*i, 70, 70); 
      addViewInLayout(child, i, null, true); 
     } 
     this.invalidate(); 
    } 
    @Override 
    public void onItemClick(AdapterView<?> parent, View v, int position, long id) { 
     Log.d("MYEXAMPLES","Clicked an item!"); 
    } 
} 

Questo non è un capolavoro di codifica, mostra solo una pseudo-listview con le immagini. So che avrei potuto usare ListView, GridView, Spinner, ecc., Ma sono relativamente nuovo per Android e sto cercando di capire alcune cose su di esso.

Bene, la domanda è: Perché il mio onItemClick non viene attivato?

Utilizzando lo stesso ImageAdapter con GridView, tutto funziona correttamente, ma quando uso con la classe precedente, non ottengo nulla. All'interno di AdapterView.java c'è un codice per quegli eventi click, longclick, ecc ... quindi perché non posso semplicemente licenziarli? Forse sto fraintendendo le cose basilari su come funziona AdapterView? Dovrei estendere altre classi base invece? E perché?

Sperando di trovare una guida più esperta qui, grazie in anticipo.

+0

hai una soluzione ?? – Riser

risposta

0

Invece di estendere AdapterView, perché non provare con baseAdapter. Quando si personalizza l'adattatore, è disponibile un metodo fornito di seguito.

getView(int position, View convertView,ViewGroup group) 

nel metodo di cui sopra è possibile accedere al layout per ogni elemento della lista del listview e qui è possibile impostare gli eventi tutti supportati per ogni controllo.

+1

Sapevo di mettere i miei ascoltatori onClick per ogni vista sull'adattatore, ma è accettabile? Ho anche potuto farlo all'interno della mia classe aggiungendo onClickListeners a ogni bambino dopo "addViewInLayout" ... Ma pensavo che l'adattatore dovrebbe gestire solo "elementi" e la vista (AdapterView) dovrebbe gestire la posizione, gli eventi e così via. .. È lo stesso ListView/GridView do ... la loro gerarchia va da AdapterView-> AbsListView-> ListView, quindi ho pensato di poter fare qualcosa di simile ma non funziona ... –

0

Sto giocando con qualcosa di simile e sto usando onItem * Selezionato * Listener che potrebbe essere più quello che stai cercando.

3

Se si dà un'occhiata in fonti s' AdapterView, vedrai che il OnItemClickListener viene invocata in un metodo, chiamato performItemClick:

public boolean performItemClick(View view, int position, long id) { 
    if (mOnItemClickListener != null) { 
     // ... 
     mOnItemClickListener.onItemClick(this, view, position, id); 
     return true; 
    } 
    return false; 
} 

Tuttavia, se si cerca l'origine AdapterView per cui questo metodo è usato, vedrai che non è chiamato da nessuna parte!

In effetti, se si seleziona la fonte del Gallery per esempio, vedrete che il performItemClick si chiama all'interno della gestione dei onSingleTapUp o onKeyUp eventi.

Se si desidera utilizzarlo, è necessario rilevare quando un utente fa clic da qualche parte e chiama performItemClick da solo.