2017-08-04 3 views
0

So habe ich eine Basiszeile, die grundlegende Vorlage, die beim Start angezeigt wird, wenn die Zeilen der Listenansicht erstellt wird, aber jede Zeile hat eine Schaltfläche, die ein in der Listenansicht neue Elemente in der Zeile geklickt fügt zum Beispiel das Hinzufügen EditText Das Problem ist, dass jedes Mal, wenn ich nach unten scrolle und dann zu der Zeile zurückkomme, die ich hinzugefügt habe, sie erneut erstellt wird und die Elemente, die ich hinzugefügt habe, gelöscht werden. Ich weiß, dass dies geschieht, weil meine Anwendung getView() jedes Mal, wenn die Zeile die Methode ruft gezeigt wird, und es wird die Ansicht wieder mit dem R.layout.listview_row Instanziieren das ist, wo ich die grundlegende Zeilenvorlage habe. Ich möchte wissen, wie ich sicherstellen kann, dass die Elemente in der Zeile gespeichert werden.Wie fügt man Zeilen der ListView programmatisch hinzu?

Das ist mein Adapter:

public class ListAdapter extends BaseAdapter { 

    private final Activity context; 

    ArrayList<String> mDataSet; 


    public ListAdapter(Activity context, ArrayList<String> mDataSet){ 
     super(); 
     this.context=context; 
     this.mDataSet = mDataSet; 
    } 

    @Override 
    public int getCount() { 
     return mDataSet.size(); 
    } 

    @Override 
    public Object getItem(int i) { 
     return mDataSet.get(i); 
    } 

    @Override 
    public long getItemId(int i) { 
     return mDataSet.get(i).hashCode(); 
    } 

    @NonNull 
    @Override 
    public View getView(final int position, @Nullable final View convertView, @NonNull ViewGroup parent) { 
     LayoutInflater inflater=context.getLayoutInflater(); 
     final View rowView= inflater.inflate(R.layout.listview_row, null,true);; 

     TextView exercise_text = (TextView) rowView.findViewById(R.id.exercise_text); 
     exercise_text.setText(mDataSet.get(position)); 

     Button btnEliminarRow = (Button) rowView.findViewById(R.id.btnEliminarRow); 
     btnEliminarRow.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View view) { 
       mDataSet.remove(position); 
       notifyDataSetChanged(); 
      } 
     }); 

     Button btnNuevaRow = (Button) rowView.findViewById(R.id.btnNuevaRow); 
     btnNuevaRow.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View view) { 
       addView(rowView); 
      } 
     }); 

     addView(rowView); 

     return rowView; 
    } 

    // Helpers 

    public void addView(View view) { 
     final LinearLayout ll = (LinearLayout) view.findViewById(R.id.layout_sets); 

     LayoutInflater inflater = (LayoutInflater) view.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
     final View v = inflater.inflate(R.layout.exercise_row , null); 
     Button moreOptions = (Button) v.findViewById(R.id.moreOptions); 

     ll.addView(v); 

     moreOptions.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View view) { 
       ll.removeView(v); 
      } 
     }); 
    } 
} 

So wie Sie in getView habe ich einen Listener, der eine Schaltfläche in jedem Klick ich die Methode addView nennen, ist diese Methode eine XML-aufbläst, die enthält einige neue Elemente sehen können das möchte ich zu der erstellten Basiszeile hinzufügen. Das Problem, wie gesagt, ist, dass als getView() wird jedes Mal, wenn ein Nachladen der Ansichten die Elemente genannt I hinzugefügt außer Kraft gesetzt werden, und das Layout der Ansicht wieder als Ausgangszustand aufgeblasen wird. Ich habe versucht, eine if verwenden und prüfen, ob convertview nicht null ist dann nicht die Ansicht, wieder aufblasen, aber das scheint nicht zu funktionieren, denn es ist wie die convertview wiederverwendet wird, und so die addView() für die gleiche Ansicht oft seine dazu aufgerufen, .

Antwort

0

Sie sollen ein neues Element zu dem Datensatz hinzufügen und den Adapter mit notifyDataSetChanged benachrichtigen. Außerdem würde ich das Ansichtshalter-Muster implementieren.

Here some examples.

Nun, zurück zu Ihrem Code, sollten Sie eine Methode namens implementieren: addItem(String item), die ein Element zu mDataSet hinzufügt. Danach benachrichtigen Sie den Adapter. Etwas wie:

public void addItem(String item) { 
    if (mDataSet == null) mDataSet = new ArrayList<>(); 
    mDataSet.add(item); 
    notifyDataSetChanged(); 
} 

Danach, verbessern Sie Ihre getView() Methode, um die ViewHolder Pattern und eine example zu verwenden.

+0

Ja, ich weiß, Sie haben den Adapter zu benachrichtigen, wenn eine neue Zeile in der Listenansicht hinzugefügt wird, und ich habe diese in einer neuen Tätigkeit umgesetztes Verfahren, was Im über in das Problem zu sprechen ist, dass ich Elemente in die bereits hinzugefügt Listenansicht hinzufügen row, um zum Beispiel programmatisch einen Edit-Text zu einem editText hinzuzufügen, siehe addView-Methode. – ravelinx

+0

Sie sollten dies mit Bedingungen in der gleichen getView() implementieren. Vielleicht nur hidding/zeigt sie dort den Trick. Wenn die Ansicht zu kompliziert ist, können Sie möglicherweise sogar zu einer Recycleransicht wechseln. –

+0

Ich glaube nicht, dass es eine gute Idee ist, sie zu verstecken, weil ich nicht weiß, wie oft das Element sich wiederholen wird. Ich habe bereits eine Recycler-Ansicht ausprobiert und hatte ähnliche Probleme. – ravelinx

Verwandte Themen