2014-09-08 11 views
8

Ho un problema seguente. Ho un GridView all'interno di LinearLayout come immagine qui sotto. Voglio rilevare l'evento click quando l'utente fa clic allo spazio vuoto di GridView, nell'immagine, la posizione che desidero è l'area rossa e anche all'interno dell'area verde.Android: rileva l'evento click allo spazio vuoto di gridview all'interno linearlayout

Ma ho problemi seguenti.

  1. Se aggiungo onClickListener per GridView: errore perché l'adattatore non può aggiungere evento click.
  2. Se aggiungo onItemClickListener per GridView: Ho appena in grado di rilevare dove esistono elementi (nell'immagine è la scatola bianca)
  3. Se aggiungo onClickListener per LinearLayout riesco proprio a rilevare evento click su un'area verde, non è zona rossa.

Quindi, come posso risolvere il problema precedente.

@EDIT: mio layout assomiglia:

<LinearLayout> 
    <GridView 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent"/> 
</LinearLayout> 

Grazie :)

enter image description here

+0

Possibile duplicato di: http://stackoverflow.com/questions/4415528/how-to-pass-the-onclick-event-to-its-parent-on-android – selbie

risposta

10

Poiché al controllore LinearLayout può essere assegnato il proprio OnClickListener, il problema è solo come rilevare un clic all'interno di GridView che si verifica al di fuori delle sue Visualizzazioni secondarie. È possibile eseguire la sottoclasse di GridView e sovrascrivere il metodo dispatchTouchEvent() per ottenere ciò. Usando il metodo pointToPosition(), possiamo determinare se un evento tattile si verifica al di fuori delle viste secondarie e utilizzare un'interfaccia per notificare un listener, se lo è. Nell'esempio seguente, l'interfaccia OnNoItemClickListener fornisce tale funzionalità.

public class TouchyGridView extends GridView 
{ 
    // Depending on how you're creating this View, 
    // you might need to specify additional constructors. 
    public TouchyGridView(Context context, AttributeSet attrs) 
    { 
     super(context, attrs); 
    } 

    private OnNoItemClickListener listener; 
    public interface OnNoItemClickListener 
    { 
     public void onNoItemClick(); 
    } 

    public void setOnNoItemClickListener(OnNoItemClickListener listener) 
    { 
     this.listener = listener; 
    } 

    @Override 
    public boolean dispatchTouchEvent(MotionEvent event) 
    { 
     // The pointToPosition() method returns -1 if the touch event 
     // occurs outside of a child View. 
     // Change the MotionEvent action as needed. Here we use ACTION_DOWN 
     // as a simple, naive indication of a click. 
     if (pointToPosition((int) event.getX(), (int) event.getY()) == -1 
      && event.getAction() == MotionEvent.ACTION_DOWN) 
     { 
      if (listener != null) 
      { 
       listener.onNoItemClick(); 
      } 
     } 
     return super.dispatchTouchEvent(event); 
    } 
} 
+2

grazie per il tuo post :) questa soluzione funziona davvero per me :) – hqt

+0

Qualunque modo di implementarlo senza creare classi separate? –

0

sembra che si mette onClickListener il layout errato (si è messo solo su interno/verde il layout dell'area e non il RelativeLayout globale che può catturare i clic dalla griglia e dai layout lineari entrambi).

+0

infatti. la disposizione lineare è un contenitore di gridview. ma forse perché la vista della griglia è sopra, quindi nell'area rossa, facendo clic su evento non può entrare nel layout lineare. :( – hqt

+0

Non penso che questo sia un motivo, ma puoi creare un singolo onClickListener e aggiungerlo entrambi ai layout Linear e Grid. –

+0

come tre test sopra, nessun test case può rilevare la sezione area rossa. click listener per entrambi i layout non funzionerà – hqt

0

Dichiarare il vostro GridView non cliccabile/attivabile utilizzando

android: cliccabile = "false" e Android: attivabile = "false"

o

v.setClickable(false) and v.setFocusable(false) 

Gli eventi click devono essere inviati al genitore di GridView ora.

Nota: Al fine di raggiungere questo obiettivo, è necessario aggiungere cliccare alla sua controllante diretta. o impostare android: clickable = "false" e android: focusable = "false" al suo genitore diretto per passare listener a genitore ulteriore.

thnx per la risposta di SIYB https://stackoverflow.com/a/18959830/3818437

+0

questo è un buon modo per una soluzione quindi per favore non inviare spam a meno che questa risposta NON sia UTILE. – mhdjazmati

1

U può solo impostare sia OnItemClickListener e OnTouchListener e
Maniglia griglia Visualizza i click un'area vuota all'interno OnTouchListener.

gridViewVar.setOnItemClickListener(new AdapterView.OnItemClickListener() 
    { 
     public void onItemClick(AdapterView<?> parent, View VyuIdxPsgVar, 
       int IdxPsgVal, long id) 
     { 
      // Code Something todo on item clicked 
     } 
    }); 
    gridViewVar.setOnTouchListener(new View.OnTouchListener() 
    { 
     @Override 
     public boolean onTouch(View v, MotionEvent event) 
     { 
      if (gridViewVar.pointToPosition((int) event.getX(), (int) event.getY()) == -1 
        && event.getAction() == MotionEvent.ACTION_DOWN) 
      { 
       // Code Something todo on empty space 
      } 
      return false; 
     } 
    }); 
+0

questo funziona per me. e più semplice dell'utilizzo di una GridView personalizzata. – mingfai

Problemi correlati