Actionlistener für die Buttons in custom Gridview

  • Antworten:6
  • Bentwortet
Gelöschter Account
  • Forum-Beiträge: 35

08.11.2012, 13:43:02 via Website

Hallo Freunde.
in meiner App verwende ich die Gridview als Liste und für jeden Eintrag habe ich ein Layout mit einem Textview und einem Button erstellt.
In meinem BaseAdapter habe ich alle Layoutkomponenten inflatet so dass ich Zugriff darauf habe.
Die getView des Adapters sieht dann so aus:
1public View getView(int position, View convertView, ViewGroup parent) {
2 view = LayoutInflater.from(context).inflate(R.layout.checklist_entry, null);
3 titelTv = (TextView) view.findViewById(R.id.titel_tv);
4 editButton = (Button) view.findViewById(R.id.add_value_button);
5 editButton.setOnClickListener(this);
6 return view;
7 }
Actionlistener sieht dann so aus:
1public void onClick(View v) {
2 // TODO Auto-generated method stub
3 switch (v.getId()){
4 case R.id.add_value_button:
5 titelTv.setText("HALLO ??????");
6 break;
7 }
Beide Funktionen sind in der selben BaseAdapter klasse.
Doch leder passieren bei der Ausführung total komische Sachen:
HALLO ??? wird auf die falsche Position gesetzt. Wenn man z.b auf den dritten eintrag der liste klickt, dann erscheint der Text erntweder garnicht, oder wird plötzlich auf dem vierten Eintrag gesetzt. Wenn man die Liste scrollt, verschwindet dann das gesetzte Text plötzlich und kommt nicht wieder.
Ich brauche Hilfe !
Mfg.

Antworten
Mac Systems
  • Forum-Beiträge: 1.727

08.11.2012, 13:52:39 via Website

Das liegt sicher daran das die ListView UI elemente wiederverwendet (caching für mehr performance). Wenn du eine Liste mit 10000 einträgen hast,
werden aber dennoch nur ca. 8-9 Element erzeugt, grob Listen höhe Elemente +1 kann man also sagen. Weiterhin solltest du einen ViewHolder verwenden (google mal danach).

In deinem, Adapter musst du dir merken auf welchem! Index welcher Text zu stehen hat, was man z.b über den Positions Index der Liste raus-bekommen könnte.

Windmate HD, See you @ IO 14 , Worked on Wundercar, Glass V3, LG G Watch, Moto 360, Android TV

Antworten
Gelöschter Account
  • Forum-Beiträge: 35

15.11.2012, 15:17:30 via Website

ich habe mal mit viewholder versucht. Es klappt eigentlich auch soweit. Nur habe ich jetzt ein Problem welches ich noch nicht gelöst habe:
ich setze in getView für jedes Button .setTag(contentview).
im actionlistener fange ich den Tag ab, inflate dann wieder die viewholder Buttons und setze text auf Button. (CODE dafür sieht so aus: )
1public void onClick(View v) {
2
3 switch (v.getId()){
4 case R.id.date_now:
5 {
6 View x = (View) v.getTag();
7 viewHolder.date = (Button) x.findViewById(R.id.date);
8 viewHolder.time = (Button) x.findViewById(R.id.time);
9 Calendar c = Calendar.getInstance();
10
11 viewHolder.date.setText(sdf.format(c.getTime()));
12 viewHolder.time.setText(stf.format(c.getTime()));
13 viewHolder.date.setVisibility(View.VISIBLE);
14 viewHolder.time.setVisibility(View.VISIBLE);
15
16 }
17 break;
18 }
Das klappt, nur wenn ich skrolle, verschwinden plötzlich zwei von drei buttons und kommen nicht mehr wieder, so dass man die activity schließen muss. Warum eigentich ?

Antworten
Gelöschter Account
  • Forum-Beiträge: 35

15.11.2012, 16:01:08 via Website

jo das ganze ist ein teil der Custom Adapter welcher von BaseAdapter abgeleitet ist

Antworten
Gelöschter Account
  • Forum-Beiträge: 694

15.11.2012, 16:43:00 via Website

OMG, was machst Du da? Ich sehe das jetzt erst. Du fummelst in einer Activity an den ViewHolder Daten rum.

Normalerweise hast Du doch ein Array/einen Cursor/etc. den Du in den Adapter fütterst. Der Adapter ist dann für die Anzeige und Verwaltung der Views zuständig. Wenn Du etwas an den Daten zu ändern hast dann machst Du das über das Array/den Cursor und teilst das dem Adapter mit notifyDataSetChanged() mit.

Den Weg den Du beschreitest würde ich auf keinen Fall gehen. Der ViewHolder als statische InnerClass des Adapters würde ich außerhalb des Adapters nicht nutzen - der ist nur für die Views und nicht für die Daten.

Antworten