2016-03-25 10 views
0

Ich habe eine RecyclerView, die aus einer ArrayList füllt. Die Ausgabe ist ein CardView-Layout. In der Cardview gibt es 2 Schaltflächen unter anderen Ansichten. Sie müssen nur den aktuellen Wert einer TextView lesen, die standardmäßig 1 ist, und sie erhöhen oder verringern. Die Arraylist enthält 8 Elemente.ReclyclerView und CardView, onclick Methode führen die Aktion auf mehrere CardViews gleichzeitig

Wenn ich die App ausführen, funktioniert die Benutzeroberfläche gut. Problem ist, wenn ich versuche, den Wert der TextView zu ändern. Der Wert wird in der CardView, an der ich gerade arbeite, korrekt erhöht und verringert, aber auch der Wert wird auf einem anderen CardView geändert. Und in diesem zweiten CardView modifiziert der TextView-Wert auch den ersten.

Also, was mache ich falsch?

Das ist mein Fragment:

public class Fragment_rosas extends Fragment { 


@Override 
public View onCreateView(LayoutInflater inflater,ViewGroup container,Bundle savedInstanceState) { 

    View view = inflater.inflate(R.layout.layout_rosas,container,false); 

    RecyclerView recyclerview_rosas; 
    RecyclerView.Adapter adaptador_rv_rosas; 
    RecyclerView.LayoutManager lm_rosas; 

    List rosas = new ArrayList(); 

    rosas.add(new Tropa(1,R.drawable.minibarbaro, getResources().getString(R.string.barbaro),7,1)); 

    recyclerview_rosas = (RecyclerView) view.findViewById(R.id.recyclerView_tropasRosas); 
    recyclerview_rosas.setHasFixedSize(true); 

    lm_rosas = new LinearLayoutManager(getContext()); 
    recyclerview_rosas.setLayoutManager(lm_rosas); 

    adaptador_rv_rosas = new AdaptadorTropa(rosas); 
    recyclerview_rosas.setAdapter(adaptador_rv_rosas); 

    return view; 
} 

}

Und hier der Teil des Codes auf meinem Adapter:

:

@Override 
public void onBindViewHolder(final TropaViewHolder viewHolder, int i) { 


    viewHolder.imagen.setImageResource(items.get(i).getImagen()); 
    viewHolder.nombre.setText(items.get(i).getNombre()); 
    viewHolder.maxnivel.setText(String.valueOf(items.get(i).getNivelMax())); 
    viewHolder.espacioencamp.setText((String.valueOf(items.get(i).getEspacioEnCamp()))); 


    final String nombre = items.get(i).getNombre(); 
    final int maxnivel = items.get(i).getNivelMax(); 


    viewHolder.nivelmas.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 

      String niveltemp = viewHolder.nivel.getText().toString(); 
      String nivelmaxtemp = viewHolder.maxnivel.getText().toString(); 

      int nivel = Integer.parseInt(niveltemp); 
      int maxxnivel = Integer.parseInt(nivelmaxtemp); 
      int nuevonivel = nivel+1 ; 

      if (nuevonivel<=maxxnivel) { 
       viewHolder.txtv_nivel.setText(String.valueOf(nuevonivel)); 
      } 
     } 
    }); 

Mein OnCreateViewHolder (nichts wirklich hier passiert)

+0

gibt es 2 Probleme mit dieser Lösung. Zuerst müssen Sie sich den Wert merken, der für jede TextView inkrementiert/dekrementiert wird. Andernfalls sehen Sie immer den Standardwert für TextView, wenn Ansichten wiederverwendet werden. Zweitens sollten Sie Click-Listener in onCreateViewHolder einrichten, um sie effizienter zu machen. Es wäre sehr hilfreich, Ihren onCreateViewHolder zu sehen. – dkarmazi

+0

Mit meinem onCreateViewHolder aktualisiert, wie Sie sehen können, ich nur das Layout dort aufblasen. Soll ich die Zuhörer hier schreiben? –

Antwort

0

Hier ist die Lösung, wie im Kommentar oben erwähnt, richtet es zwei Probleme: 1. positiontoValueMap - spart Stromwert für jede Position 2. OnClickListener zum ViewHolder in onCreateViewHolder geben wird

Adapter Class

public class MyAdapter extends RecyclerView.Adapter { 
    private Context context; 
    private List<String> dataList; 
    private Map<Integer, Integer> positionToValueMap = new HashMap<>(); 

    public MyAdapter(Context context, List<String> dataList) { 
     this.context = context; 
     this.dataList = dataList; 
    } 

    @Override 
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
     View view = LayoutInflater.from(context).inflate(R.layout.recycler_view_item, null, false); 

     return new MyViewHolder(view, new OnRecyclerItemClickListener()); 
    } 


    @Override 
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { 
     ((MyViewHolder) holder).onRecyclerItemClickListener.updatePosition(position); 
     ((MyViewHolder) holder).position.setText("" + position); 
     ((MyViewHolder) holder).title.setText(dataList.get(position)); 

     int valueToDisplay = 1; 

     if(positionToValueMap.containsKey(position)) { 
      valueToDisplay = positionToValueMap.get(position); 
     } else { 
      positionToValueMap.put(position, valueToDisplay); 
     } 

     ((MyViewHolder) holder).valueView.setText("value: " + valueToDisplay); 
    } 

    @Override 
    public int getItemCount() { 
     return dataList.size(); 
    } 

    private class MyViewHolder extends RecyclerView.ViewHolder { 
     private OnRecyclerItemClickListener onRecyclerItemClickListener; 
     private TextView position; 
     private TextView title; 
     private TextView valueView; 

     public MyViewHolder(View itemView, OnRecyclerItemClickListener onRecyclerItemClickListener) { 
      super(itemView); 

      itemView.setOnClickListener(onRecyclerItemClickListener); 
      this.onRecyclerItemClickListener = onRecyclerItemClickListener; 
      this.position = (TextView) itemView.findViewById(R.id.position); 
      this.title = (TextView) itemView.findViewById(R.id.title); 
      this.valueView = (TextView) itemView.findViewById(R.id.value_view); 
     } 
    } 


    private class OnRecyclerItemClickListener implements View.OnClickListener { 
     private int position = -1; 

     public void updatePosition(int position) { 
      this.position = position; 
     } 

     @Override 
     public void onClick(View v) { 
      int oldValue = positionToValueMap.get(position); // get current value 
      oldValue++; // increment 
      positionToValueMap.put(position, oldValue); // save current value 
      notifyItemChanged(position); // update clicked view so that it picks up the new saved value from the positionToValueMap in onBindViewHolder 
     } 
    } 
} 

RecyclerView Artikel Layout

<TextView 
     android:id="@+id/position" 
     android:layout_width="30dp" 
     android:layout_height="50dp" 
     android:textColor="@android:color/white" 
     android:gravity="center" 
     android:background="@android:color/holo_green_light" 
     android:layout_alignParentLeft="true"/> 

    <TextView 
     android:id="@+id/title" 
     android:layout_width="50dp" 
     android:layout_height="50dp" 
     android:textColor="@android:color/white" 
     android:gravity="center" 
     android:background="@android:color/holo_green_dark" 
     android:layout_toRightOf="@id/position" /> 

    <TextView 
     android:id="@+id/value_view" 
     android:layout_width="match_parent" 
     android:layout_height="50dp" 
     android:textColor="@android:color/white" 
     android:gravity="center" 
     android:background="@android:color/holo_green_light" 
     android:layout_toRightOf="@id/title" 
     android:layout_alignParentRight="true"/> 
</RelativeLayout> 

Und Aktivität es

zu testen,
public class MainActivity extends AppCompatActivity { 
    private RecyclerView recyclerView; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 

     recyclerView = (RecyclerView) findViewById(R.id.recycler_view); 

     recyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext())); 
     recyclerView.setAdapter(new MyAdapter(getApplicationContext(), getSampleData())); 
    } 

    private static List<String> getSampleData() { 
     List<String> dataList = new ArrayList<>(); 
     dataList.add("zero"); 
     dataList.add("one"); 
     dataList.add("two"); 
     dataList.add("three"); 
     dataList.add("four"); 
     dataList.add("five"); 
     dataList.add("six"); 
     dataList.add("seven"); 
     dataList.add("eight"); 
     dataList.add("nine"); 
     dataList.add("ten"); 
     dataList.add("eleven"); 
     dataList.add("twelve"); 
     dataList.add("thirteen"); 
     dataList.add("fourteen"); 
     dataList.add("fifteen"); 
     dataList.add("sixteen"); 
     dataList.add("seventeen"); 
     dataList.add("eighteen"); 
     dataList.add("nineteen"); 
     dataList.add("twenty"); 

     return dataList; 
    } 
} 

Aktivität Layout

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/root_view" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent"> 

    <android.support.v7.widget.RecyclerView 
     android:id="@+id/recycler_view" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     android:background="@android:color/white"/> 

</RelativeLayout> 
+0

Vielen Dank für Ihre tolle Antwort. Ich versuche herauszufinden, wie Sie meinen Code auf meinem implementieren können. Was passiert, wenn ich das Klickereignis auf einer bestimmten Schaltfläche und nicht nur auf dem gesamten RecyclerView-Element behandeln möchte? –

+0

@RaulLopez, gern geschehen. Alles, was Sie in diesem Fall tun müssen, ist diese Zeile in der privaten Klasse myViewHolder zu ändern. Anstelle von itemView kann dies eine beliebige Ansicht sein, die Sie im Recycler-View-Element haben. – dkarmazi

+0

Vielen Dank, Kumpel! Ich habe bereits eine Lösung entwickelt, ich habe einen allgemeinen onClick-Listener in der OnRecyclerItemClickListener-Klasse implementiert und mit einem Schalter/Fall, der die angeklickte Ansichts-ID erhält, kann ich jetzt 6 Schaltflächen handhaben. –