Indizes (position) von getView stimmen nicht mit size der übergebenen Liste überein

  • 3 Antworten
  • Letztes Antwortdatum
A

Android-Torero

Neues Mitglied
0
Hallo zusammen,

also ich steh gerade völlig auf dem Schlauch und hoffe, jemand von euch hat bei meinem Problem den Durchblick.

Zuerst ne kurze Erklärung:
Ich rufe aus einer Activity einen Dialog auf, der dynamisch (also Zeilenweise) jeweils eine TextView mit zwei Buttons anzeigen soll. Das klappt soweit auch. Allerdings habe ich nun festgestellt, dass die getView-Methode aus dem Adapter für jeden Eintrag der übergebenen ArrayListe mehrmals und in willkürlicher Reihenfolge aufgerufen wird. Keine Ahnung warum??? Noch kurioser ist allerdings, dass, wenn ich eine Liste mit 5 Einträgen übergebe, in der getView-Methode immer nur bestimmte Indizes (position) der Liste verarbeitet werden. Und das kurioseste ist, dass trotzdem alle Einträge der Liste im Dialog genau 1 x angezeigt werden.

Ein bisschen Code dazu ...
1. Die Dialog-Klasse:
Code:
    private void updateEventInfoList(Termin t) {
        if((t != null) && (t.getAuftragsNummern() != null && t.getAuftragsNummern().size() > 0)) {
            listEventInfos = new ArrayList<String>();
            for(int i=0; i<t.getAuftragsNummern().size(); i++) {
                String s = GlobalData.getTerminInfotext(dbHelper2, t.getAuftragsNummer(i));
                listEventInfos.add(s);        
            }
        }
        
        adapter = new EventInfoArrayAdapter(context, R.layout.event_info_item_row, listEventInfos, eventHandlerInfoDialog);
        activity.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                lvEventInfos.setAdapter(adapter);
                adapter.notifyDataSetChanged();
            }
        });
        
    }
2. Die Adapter-Klasse:
Code:
    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {
        this.position = position;
        String s = (String) getItem(position);

        if(convertView == null) {
            eventInfoView = new TableLayout(context);
            LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            inflater.inflate(resourceId, eventInfoView, true); 
        } else {
            eventInfoView = (TableLayout) convertView;
        }

        TableRow trInfo = (TableRow) eventInfoView.findViewById(R.id.event_info_item_row);
        trInfo.setGravity(Gravity.CENTER_VERTICAL);
        trInfo.setBackgroundColor(context.getResources().getColor(R.color.table_row_highlight_color));
        
        TextView tvEventInfo = (TextView) trInfo.findViewById(R.id.event_tvInfo);
        LayoutParams tableRowParamsText = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
        tvEventInfo.setLayoutParams(tableRowParamsText);
        tvEventInfo.setTextSize(16.0f);
        tvEventInfo.setTextColor(context.getResources().getColor(R.color.link_color));
         tvEventInfo.setText(s);
        LinearLayout layoutButtons = (LinearLayout) trInfo.findViewById(R.id.layout_item_buttons);

        Button btnEditEvent = (Button) layoutButtons.findViewById(R.id.btnEditEvent);
        btnEditEvent.setTextSize(18.0f);
        btnEditEvent.setTypeface(btnEditEvent.getTypeface(), Typeface.BOLD);
        btnEditEvent.setOnClickListener(new EventInfoOCL());
        
        Button btnEditOrder = (Button) layoutButtons.findViewById(R.id.btnEditOrder);
        btnEditOrder.setTextSize(18.0f);
        btnEditOrder.setTypeface(btnEditOrder.getTypeface(), Typeface.BOLD);
        btnEditOrder.setOnClickListener(new EventInfoOCL());
        
        
        return eventInfoView;
    }
3. Die Dialog-XML
Code:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/event_info_dialog_layout"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="@color/table_row_highlight_color" >
    
    <View
        android:id="@+id/event_info_separator"
        android:layout_height="1dp"
        android:layout_width="fill_parent"
        android:background="@android:drawable/divider_horizontal_bright"
    />

     <ListView 
         android:id="@+id/listview_event_info"
         android:layout_width="fill_parent"
         android:layout_height="fill_parent"
    />   
</LinearLayout>
4. Die XML für die einzelnen Zeilen des Dialogs
Code:
<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="match_parent"
    android:background="#ffffff" >

      <TableRow
          android:id="@+id/event_info_item_row" 
        android:layout_width="fill_parent" 
           android:layout_height="wrap_content"
           android:layout_marginBottom="1dp">

        <LinearLayout
            xmlns:android="http://schemas.android.com/apk/res/android"
            android:id="@+id/layout_item_row"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:orientation="vertical"
            android:weightSum="1" >

            <TextView
                android:id="@+id/event_tvInfo"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:layout_marginLeft="3dp"
                android:text="TextView"
                android:textColor="@color/link_color"
                android:textSize="16sp" />

            <LinearLayout
                xmlns:android="http://schemas.android.com/apk/res/android"
                android:id="@+id/layout_item_buttons"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center_horizontal"
                android:orientation="horizontal"
                android:weightSum="1" >

                <Button
                    android:id="@+id/btnEditEvent"
                    android:layout_width="150dp"
                    android:layout_height="wrap_content"
                    android:layout_weight="0.5"
                    android:text="Termin" >
                </Button>

                <Button
                    android:id="@+id/btnEditOrder"
                    android:layout_width="150dp"
                    android:layout_height="wrap_content"
                    android:layout_weight="0.5"
                    android:text="Auftrag" >
                </Button>
            </LinearLayout>
        </LinearLayout>  
      </TableRow>
</TableLayout>
Ich habe mittels LogCat-Ausgabe überprüft, was in der Liste drinsteht und was in der getView-Methode verarbeitet wird, und das differiert gewaltig. Das Ergebnis ist allerdings, so wie ich es wünsche. Nur weiß ich nicht, ob es nicht im Weiterverlauf zu ungewollten Nebeneffekten kommt.

Wäre gut, wenn mir einer sagen könnte, was bei meinem Code passiert.

Thorero
 
getView wird sehr oft aufgerufen.

es wird aber nur für jene einträge aufgerufen, die auch gerade für den user sichtbar sind.

wenn du jetzt 5 einträge hast. 3 davon sind sichtbar, dann wird die getview für die 3 sichtbaren aufgerufen. gut möglich, dass es mehrmals passiert. android weiß schon was es tut.

wenn du weiterscrollst, wird zb item5 sichtbar, item2 unsichtbar. dann wird getview für item 5 aufgerufen.

achtung die views der zellen werden wiederverwendet. stichwort convertview
 
Ja danke ;-),
das erkärt natürlich, warum er immer nur die Einträge mit den Indizes 0 - 2 verarbeitet. Auf das Display passen tatsächlich nur die ersten drei Einträge der Liste drauf. Für die anderen muss gescrollt werden.

Das eröffnet mit aber ein anderes Problem. Da ich einen der Buttons unter gewissen Umständen auf enabled = false bzw. View.Gone setzen muss.
Mit der derzeitigen Lösung schmeisst er mir beim Scrollen die Buttons durcheinander.
Will sagen, dass Buttons auf unsichtbar gesetzt werden, die es eigentlich nicht sein dürften.
 
du musst die buttons immer explizit setzen

das heißt es reicht nicht
if(diesdas)
button.enabled = false;

du brauchst auch noch ein
else
button.enabled = true

weil er die views reused
 
Zurück
Oben Unten