3

Ich erstelle eine Liste mit einem RecyclerView. Jedes Listenelement ist ein Beitrag von einem Benutzer (gerade hart codiert). Der Hintergrund für jeden Beitrag wird aus einer layer-list XML-Datei im Zeichenordner geladen.Android RecyclerView ändert nicht Hintergrundfarbe beim ersten Element programmgesteuert

Alles funktioniert wie beabsichtigt mit den Texten usw., aber ich versuche, die Hintergrundfarbe programmgesteuert zu ändern. Es ändert die Hintergrundfarbe für jeden Artikel, außer für den ersten Artikel, und ich kann nicht herausfinden, warum.

Der erste Punkt wird immer die Hintergrundfarbe von der Innenseite der itemsolid Farbe der shape angegeben shape_background in der XML-Datei mit dem Namen, so wird es nicht geändert, aber die folgenden Elemente erhalten die Farbe #ff22ff.

Dies ist die Implementierung des Adapters:

class PostListAdapter extends RecyclerView.Adapter<PostListAdapter.PostViewHolder>{ 

    private LayoutInflater inflater; 
    private List<PostRow> data = Collections.emptyList(); 

    PostListAdapter(Context context, List<PostRow> data) { 
     inflater = LayoutInflater.from(context); 
     this.data = data; 
    } 

    @Override 
    public void onBindViewHolder(PostViewHolder holder, int position) { 

     PostRow current = data.get(position); 
     holder.text.setText(current.text.toUpperCase()); 
     holder.time.setText(current.time.toUpperCase()); 
     holder.answers.setText(current.answers.toUpperCase()); 

     try { 
      // "#ff22ff" will be changed to current.color, unique color for every post 
      // That string is parsed from a JSON request, hence the try-catch. 
      int color = Color.parseColor("#ff22ff"); 
      holder.shape.setColor(color); 
     } catch (Exception e){ 
      e.printStackTrace(); 
     } 

    } 

    @Override 
    public PostViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
     View view = inflater.inflate(R.layout.post_row, parent, false); 
     return new PostViewHolder(view); 
    } 

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

    class PostViewHolder extends RecyclerView.ViewHolder { 

     TextView text; 
     TextView time; 
     TextView answers; 
     GradientDrawable shape; 

     PostViewHolder(View itemView) { 
      super(itemView); 
      text = (TextView) itemView.findViewById(R.id.text); 
      time = (TextView) itemView.findViewById(R.id.time); 
      answers = (TextView) itemView.findViewById(R.id.answers); 
      LayerDrawable layers = (LayerDrawable) ContextCompat.getDrawable(itemView.getContext(), R.drawable.bubble); 

      shape = (GradientDrawable) (layers.findDrawableByLayerId(R.id.shape_background)); 
     } 

    } 

} 

Warum ist der Hintergrund des ersten Elements nicht geändert, aber die Texte?

Vielen Dank im Voraus!

+3

Haben Sie eine Ausnahme? Warum versuchen fangen? – natario

+0

Ich verstehe, dass der Kommentar nicht klar genug war. Die hartcodierte Zeichenkette "# ff22ff" wird später in die Zeichenkette current.color geändert. Diese Zeichenfolge wird von einer JSON-Antwort analysiert. Für den Fall, dass in diesem Prozess etwas durcheinander gerät, sollte man das mit dem Versuch fangen. Ich werde den Kommentar aktualisieren, danke. – Misklahr

Antwort

3

Auf Ihrem onBindViewHolder, erhalten Sie Ihre Ansicht (von Halter) für die Sie benötigen, Hintergrundfarbe ändern & seinen aktuellen Hintergrund zu erhalten (ziehbar Blase, dass Sie bereits in XML-Attribut gesetzt) ​​

LayerDrawable layerDrawable = (LayerDrawable) yourView.getBackground().getCurrent(); 
GradientDrawable gradientDrawable = (GradientDrawable) layerDrawable.findDrawableByLayerId(R.id. shape_background).getCurrent(); 
// set you color based on position 
gradientDrawable.setColor(Color.parseColor("#ff22ff")); 
+0

Danke, das hat mein Problem so gelöst, wie ich es wollte. Mit API 15 und höher, also konnte das setBackground in liubaoyuas Antwort in meinem Fall nicht verwendet werden, aber es ist auch korrekt. – Misklahr

3

Sie angerufen haben holder.shape.setColor(color);

aber die holderView wurde nicht aktualisiert.

vielleicht sollten Sie

holder.itemView.setBackgroundDrawable( ContextCompat.getDrawable(itemView.getContext(), R.drawable.bubble))

rufen Sie die holderView

+0

Dies ist korrekt, beachten Sie, dass setBackgroundDrawable veraltet ist. Man sollte setBackground für die API-Stufe 16 und höher verwenden, obwohl setBackground die Methode setBackgroundDrawable aufruft. – Misklahr

0

Sie haben zwei verschiedene Dinge hier zu aktualisieren.

Zuerst - Sie ändern selbst zeichnend, aber nicht Hintergrund anzeigen. Es ist gelöst von liubaoyua und Vignesh Sundar Antworten.

Zweitens - Sie ändern R.drawable.bubble statisch. Android kann es auch nach einer Mutation zwischenspeichern und wiederverwenden. Es kann zu anderen Problemen führen, wenn Sie verschiedene Farben für verschiedene Elemente verwenden.

Um das zweite Problem zu lösen, müssen Sie immer zuerst android.graphics.drawable.Drawable#mutate aufrufen, bevor Sie es mutieren.

Standardmäßig haben alle Zeichenauszugsinstanzen, die von derselben Ressource geladen werden, einen gemeinsamen Status. Wenn Sie den Status einer Instanz ändern, erhalten alle anderen Instanzen die gleiche Änderung.

So sollte es in etwa so aussieht:

class PostViewHolder extends RecyclerView.ViewHolder { 

    TextView text; 
    TextView time; 
    TextView answers; 
    LayerDrawable layers; 
    GradientDrawable shape; 

    PostViewHolder(View itemView) { 
     super(itemView); 

     text = (TextView) itemView.findViewById(R.id.text); 
     time = (TextView) itemView.findViewById(R.id.time); 
     answers = (TextView) itemView.findViewById(R.id.answers); 

     layers = (LayerDrawable) ContextCompat 
       .getDrawable(itemView.getContext(), R.drawable.bubble) 
       .mutate(); 

     shape = (GradientDrawable) layers.findDrawableByLayerId(R.id.shape_background); 
     itemView.setBackground(layers); 
    } 

    void setColor(Color color) { 
     shape.setColor(color); 
     itemView.setBackgroundDrawable(layers); 
    } 
} 

sein kann wenig .mutate() von Schicht kann vereinfacht werden, indem zu gestalten.

Verwandte Themen