2012-08-02 8 views
21

Ich habe ein Problem mit dem Erstellen eines GridView-basierten Kalenders. Hier ist die Grid:OnClickListener funktioniert nicht für das erste Element in GridView

GridView Calendar

Dies sollte ein Kalender mit Ereignissen gefüllt werden, so dass ich meinen Adapter OnClickListener implementieren und ich festgelegt, dass die Zuhörer für jede Taste im Kalender. Es funktioniert perfekt für jeden einzelnen Knopf AUSSER der erste (in diesem Fall Nummer 30). Wenn ich es anklicke, funktioniert es nicht, aber wenn ich auf eine andere Schaltfläche klicke, nachdem ich versucht habe, auf die erste Schaltfläche zu klicken, führt es den Klick für die erste aus, kurz bevor der Klick für die andere Schaltfläche ausgeführt wird.

Ich habe etwa 10 Seiten mit relevanten Fragen gescannt und habe niemanden gefunden, der dieses Problem hat. Hilfe bitte!

Als gefragt, hier ist die getView Funktion meines Codes:

public View getView(int position, View convertView, ViewGroup parent) 
    { 
     View row = convertView; 
     ViewHolder holder; 
     if (row == null) 
     { 
      holder = new ViewHolder(); 
      LayoutInflater inflater = (LayoutInflater) _context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
      row = inflater.inflate(R.layout.calendar_day_gridcell, parent, false); 
      holder.gridCell = (Button) row.findViewById(R.id.calendar_day_gridcell); 
      holder.multiDayEvent = (EventLengthView)row.findViewById(R.id.eventLengthView); 
     } 
     else{ 
      holder = (ViewHolder)row.getTag(); 
     } 

     int calendarGridHeight = (calendarView.getHeight()-5)/(getCount()/7); 
     AbsListView.LayoutParams params = new AbsListView.LayoutParams(
       android.view.ViewGroup.LayoutParams.FILL_PARENT, 
       calendarGridHeight); 
     row.setLayoutParams(params); 

     //Change the background drawable depending on the position in the calendar 
     if ((position+1) % 7 == 0){ 
      holder.gridCell.setBackgroundDrawable(getResources().getDrawable(R.drawable.calendar_button_selector_end_row)); 
     } 
     if (getCount() - position < 8){ 
      holder.gridCell.setBackgroundDrawable(getResources().getDrawable(R.drawable.calendar_button_selector_end_column)); 
     } 
     if (position == getCount()-1){ 
      holder.gridCell.setBackgroundDrawable(getResources().getDrawable(R.drawable.calendar_button_selector_end)); 
     } 
     holder.gridCell.setOnClickListener(this); 

     holder.gridCell.setTag(null);//clear tags 

     // ACCOUNT FOR SPACING 
     String[] day_color = list.get(position).split("-"); 
     int theday = Integer.parseInt(day_color[0]); 
     int themonth = Integer.parseInt(day_color[2]); 
     int theyear = Integer.parseInt(day_color[3]); 
     String date = DateFormat.format("dd/M/yy", new Date(theyear,themonth,theday)).toString(); 
     if ((!eventsMap.isEmpty()) && (eventsMap != null)) 
     { 
      if (eventsMap.containsKey(date)) 
      { 
       holder.multiDayEvent.SetMeasure(calendarView.getWidth()/7, calendarGridHeight); 

       holder.multiDayEvent.setVisibility(View.VISIBLE); 
       //holder.singleDayEvent.setVisibility(View.VISIBLE); 
       Event event = (Event) eventsMap.get(date); 
       holder.multiDayEvent.AddEvent(event); 
       holder.gridCell.setTag(event); 
      } 
      else{ 
       //holder.singleDayEvent.setVisibility(View.GONE); 
       holder.multiDayEvent.setVisibility(View.GONE); 
      } 
     } 

     // Set the Day GridCell 
     holder.gridCell.setText(Integer.toString(theday)); 

     if (day_color[1].equals("GREY")) 
     { 
      holder.gridCell.setTextColor(Color.GRAY); 
     } 
     if (day_color[1].equals("WHITE")) 
     { 
      holder.gridCell.setTextColor(Color.WHITE); 
     } 
     if (day_color[1].equals("BLUE")) 
     { 
      holder.gridCell.setTextColor(Color.BLUE); 
     } 

     row.setTag(holder); 
     return row; 
    } 

    public class ViewHolder{ 
     Button gridCell; 
     ImageView singleDayEvent; 
     EventLengthView multiDayEvent; 
    } 

    public void onClick(View view) 
    { 
     if (view.getTag() != null){ 
      Event event = (Event)view.getTag(); 

      eventListView.setAdapter(new EventListAdapter(CalendarScreen.this, event)); 
      eventListViewLayout.setVisibility(View.VISIBLE); 
      eventListViewLayout.startAnimation(fadeIn); 
     } 
     else if (eventListViewLayout.getVisibility() == View.VISIBLE){ 
      onBackPressed(); 
     } 
    } 

Die onClick für jede Gridcell außer dem ersten in der linken oberen Ecke

+0

Bitte setzen Sie den Code, den Sie verwendet haben .. –

+0

[Warum haben Sie dieses Beispiel nicht versuchen] (http://w2davids.wordpress.com/android-simple-calendar/) – Praveenkumar

+0

mein Code basiert auf diesem Beispiel – Valentin

Antwort

8

Ok, ich habe die Lösung gefunden. Das Problem war, diese Zeilen:

ViewHolder holder; 
if (convertView == null) 
{ 
    holder = new ViewHolder(); 
    LayoutInflater inflater = (LayoutInflater) _context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
    convertView = inflater.inflate(R.layout.calendar_day_gridcell, parent, false); 
    holder.gridCell = (Button) convertView.findViewById(R.id.calendar_day_gridcell_button); 
    holder.multiDayEvent = (EventLengthView) convertView.findViewById(R.id.eventLengthView); 
    convertView.setTag(holder); 
} 
else { 
    holder = (ViewHolder) convertView.getTag(); 
} 

Wenn instatiating die Gridcell-Taste setzen, irgendwie, es mischt den Klick Hörer der ersten Position in dem Adapter auf. Ich reparierte es, indem ich einfach den Halter in jedem Durchgang einsetzte, anstatt ihn per Etikett zu bekommen (was für die Leistung besser ist, aber naja). Danke allen für die Hilfe.

+0

können Sie etwas mehr Code setzen –

+0

Wirklich nicht Wiederverwendung der convertView machte dies funktioniert –

0

Sets onItemClickListener auf dem Gridview-Objekt aufgerufen wird, statt onClickListeners für jede Schaltfläche festlegen.

Und ich fand eine andere Frage mit Ihrem Problem here. Bounty vielleicht?

+0

funktioniert nicht. Ich versuchte es. – Valentin

+0

Ich habe auch versucht, die Schaltflächen mit ImageViews zu ersetzen (wie ich weiß, die Schaltflächen blockieren die onItemClickListeners der GridView), aber es hat immer noch nicht funktioniert. – Valentin

+0

Bitte Code hinzufügen – png

0

Bitte beziehen Sie sich auf link, es hat die Hintergrundfarbe gridview auf TRANSPARENT gesetzt. Es kann dir helfen.

1

Für was es wert ist, hatte ich auch dieses Problem (erste Zelle in der Gridview verzögert onclick).

In meinem Fall benutzte ich eine (leicht angepasste) Rasteransicht mit dynamischen Bildaufrufen, die ich sichtbar machen würde und die Gitteransicht neu zeichnen würde. Alle Bildansichten wurden zuvor vorbereitet und im Adapter gespeichert.

Anfangs verwendete ich notifyDataSetChanged() auf dem Adapter, aber dies führte zu dem verzögerten Klick-Problem für die erste Zelle, wann immer der Satz aktualisiert wurde. Ich änderte nur die Gitteransicht und jetzt ist alles in Ordnung. Denken Sie daran, dass alle meine Ansichten bereits erstellt und im Adapter gespeichert sind, es ist nur die getview-Methode, die überprüft, welche wirklich sichtbar sind.

8

Verwenden Sie Ihre OnClickListener() in Ihrer Aktivität nach .setAdapter() Verfahren, nicht in Ihrer Adapterklasse.

gridView.setAdapter(adapter); 
gridView.setOnItemClickListener(new OnItemClickListener() { 
public void onItemClick(AdapterView parent, View v, int position, long id) { 
    Toast.makeText(GridViewActivity.this, "" + position, 
      Toast.LENGTH_SHORT).show(); 
    } 
}); 
+1

danke. Mein Problem wurde durch Ihre Lösung gelöst. –

+1

Diese Lösung ist am besten – Miguel

+0

Lassen Sie mich sagen, würden Sie mich heiraten? Funktioniert wie ein Charme ... –

1

Ich hatte das gleiche Problem. Das Klickereignis für den ersten Artikel wurde erheblich verzögert. Ich habe bereits notifyDataSetInvalidated() verwendet.Die Verwendung von onItemClickListener() löste das Problem, obwohl ich immer noch nicht verstehe, warum der onClick-Listener für die einzelnen Elemente dieses Verhalten hat.

13

Ich hatte das gleiche Problem. Keeping die setLayoutParams innerhalb der If (view == null) -Klausel ausgearbeitet. Sie müssen View Recycling auf diese Weise nicht opfern.

mag:

if(row == null){ 
    // inflate row 
    row.setLayoutParams(params); 
    //remaining code 
}else{ 
    holder = (ViewHolder)row.getTag(); 
} 
// everything else 

Ich weiß nicht, warum es funktioniert, aber es funktionierte für mich. Ich habe auch bemerkt, dass alle Codes, die dasselbe Problem in Stackoverflow betreffen, auch setLayoutParams außerhalb der if-Klausel benutzt haben. Dies ist mein erstes Mal, also weiß ich nicht, ob ich das überall posten kann. Hoffe es hat geholfen.

Quelle: Viel Trail und Fehler.

+2

Arbeitete für mich und sparte mir eine Menge Zeit – 365SplendidSuns

+0

Vielen Dank! Es hilft. – Zikkoua

+0

Danke, dass du mir sehr geholfen hast :) – Radwa

Verwandte Themen