2015-10-16 11 views
21

Zuerst, tut mir leid über mein Englisch. Nach RecyclerView Dokumentation über medthod notifyItemChanged(int position, Object payload)Benötigen Sie ein Beispiel über RecyclerView.Adapter.notifyItemChanged (Int-Position, Object Payload)

alle registrierten Beobachter benachrichtigen, dass das Element an der Position mit einem optionalen Nutzlast Objekt geändert wird.

Ich verstehe nicht, wie zweite Parameter payload in dieser Methode zu verwenden. Ich habe viele Dokumente über "Nutzlast" gesucht, aber alles war mehrdeutig.

Also, wenn Sie über diese Methode wissen, zeigen Sie mir bitte ein klares Beispiel darüber. Vielen Dank.

Antwort

19

Überprüfen Sie diesen Beispielcode, der die Funktion veranschaulicht. Es ist eine RecyclerView, die notifyItemChanged(position, payload) aufruft, wenn das Element an Position position geklickt wird. Sie können überprüfen, ob onBindViewHolder(holder, position, payload) aufgerufen wurde, indem Sie nach der logcat-Anweisung suchen.

Vergewissern Sie sich, mindestens Version 23.1.1 der Support-Bibliotheken verwenden, etwa so:

dependencies { 
    compile fileTree(dir: 'libs', include: ['*.jar']) 
    compile 'com.android.support:appcompat-v7:23.1.1' 
    compile 'com.android.support:recyclerview-v7:23.1.1' 
    compile 'com.android.support:cardview-v7:23.1.1' 
} 

HelloActivity.java

package com.formagrid.hellotest; 

import android.app.Activity; 
import android.os.Bundle; 
import android.support.v7.widget.CardView; 
import android.support.v7.widget.DefaultItemAnimator; 
import android.support.v7.widget.LinearLayoutManager; 
import android.support.v7.widget.RecyclerView; 
import android.util.Log; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.TextView; 

import java.util.List; 

public class HelloActivity extends Activity { 

    private RecyclerView mRecyclerView; 

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

     mRecyclerView = (RecyclerView) findViewById(R.id.recycler_view); 
     mRecyclerView.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false)); 
     mRecyclerView.setAdapter(new HelloAdapter()); 
     DefaultItemAnimator animator = new DefaultItemAnimator() { 
      @Override 
      public boolean canReuseUpdatedViewHolder(RecyclerView.ViewHolder viewHolder) { 
       return true; 
      } 
     }; 
     mRecyclerView.setItemAnimator(animator); 
    } 

    private static class HelloAdapter extends RecyclerView.Adapter<HelloAdapter.HelloViewHolder> { 

     public class HelloViewHolder extends RecyclerView.ViewHolder { 

      public TextView textView; 

      public HelloViewHolder(CardView cardView) { 
       super(cardView); 
       textView = (TextView) cardView.findViewById(R.id.text_view); 
      } 

     } 

     @Override 
     public HelloViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
      CardView cardView = (CardView) LayoutInflater.from(parent.getContext()).inflate(
        R.layout.card_item, parent, false); 
      return new HelloViewHolder(cardView); 
     } 

     @Override 
     public void onBindViewHolder(HelloViewHolder holder, int position) { 
      bind(holder); 
     } 

     @Override 
     public void onBindViewHolder(HelloViewHolder holder, int position, List<Object> payload) { 
      Log.d("butt", "payload " + payload.toString()); 
      bind(holder); 
     } 

     @Override 
     public int getItemCount() { 
      return 20; 
     } 

     private void bind(final HelloViewHolder holder) { 
      holder.textView.setText("item " + holder.getAdapterPosition()); 
      holder.itemView.setOnClickListener(new View.OnClickListener() { 
       @Override 
       public void onClick(View v) { 
        final int position = holder.getAdapterPosition(); 
        Log.d("butt", "click " + position); 
        HelloAdapter.this.notifyItemChanged(position, "payload " + position); 
       } 
      }); 
     } 

    } 

} 

activity_main.xml

<RelativeLayout 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:paddingBottom="@dimen/activity_vertical_margin" 
    android:paddingLeft="@dimen/activity_horizontal_margin" 
    android:paddingRight="@dimen/activity_horizontal_margin" 
    android:paddingTop="@dimen/activity_vertical_margin" 
    tools:context=".HelloActivity"> 

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

</RelativeLayout> 

card_item. xml

<?xml version="1.0" encoding="utf-8"?> 
<android.support.v7.widget.CardView 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:card_view="http://schemas.android.com/apk/res-auto" 
    android:layout_width="match_parent" 
    android:layout_height="100dip" 
    android:layout_margin="5dip" 
    card_view:cardElevation="5dip"> 

    <TextView 
     android:id="@+id/text_view" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent"/> 

</android.support.v7.widget.CardView> 
+1

Ich habe gerade Ihren Code getestet. Es gibt etwas nutzloses in meinem Test: das Basic onBind (ohne Payload) wird nie aufgerufen. Hast du jetzt warum? Ich rufe nur notifyItemRangeChanged (index, mArrayList.size()); oder notifyItemInserted (i); – Cocorico

+4

liebe das unreife Log-Tag +1 – styler1972

1

Sie können ein "optionales Nutzlastobjekt" übergeben, wenn Sie nur eine Teilaktualisierung der Daten in ViewHolder durchführen möchten, wenn die Methode onBindViewHolder aufgerufen wird. Es ist jedoch nicht sicher, dass die Nutzlast immer übergeben wird, z. B. wenn die Ansicht nicht angehängt ist, sodass Sie weitere Überprüfungen durchführen sollten.

Wie auch immer, wenn Sie null übergeben wird es ein komplettes Update auf den Artikel durchgeführt werden und Sie müssen sich nicht darum kümmern.

26

Wenn Sie nicht alle Inhaber Ansicht aktualisieren möchten aber nur Teil davon, diese Methode ist das, was Sie brauchen.

Bild, das Sie haben folgende ViewHolder

public class ViewHolder extends RecyclerView.ViewHolder { 
     public final TextView tvName; 
     public final TextView tvScore; 

     public ViewHolder(View view) { 
      super(view); 
      tvName = (TextView) view.findViewById(R.id.tv_name); 
      tvScore = (TextView) view.findViewById(R.id.tv_score); 
     } 

    } 

Und irgendwo in Ihrem Code rufen Sie Adapter einzelneTextview zu aktualisieren - tvScore

mRecyclerViewAdapter.notifyItemChanged(position, new Integer(4533)); 

[...]

onBindViewHolder (ViewHolder-Halter, int-Position, Nutzdatenliste auflisten) fängt Rückruf zuerst ein. Wenn payloads nicht Ihren Anforderungen entspricht, müssen Sie die Superklasse super.onBindViewHolder(holder,position, payloads); aufrufen, die in anderen Fällen onBindViewHolder(ViewHolder holder, int position) auslöst.

 // Update only part of ViewHolder that you are interested in 
    // Invoked before onBindViewHolder(ViewHolder holder, int position) 
     @Override 
     public void onBindViewHolder(ViewHolder holder, int position, List<Object> payloads) { 
      if(!payloads.isEmpty()) { 
       if (payloads.get(0) instanceof Integer) { 
        holder.tvScore.setText(String.valueOf((Integer)payloads.get(0))) 
       } 
      }else { 
       super.onBindViewHolder(holder,position, payloads); 
      } 
     } 

    // Update ALL VIEW holder 
    @Override 
     public void onBindViewHolder(ViewHolder holder, int position) { 
      MItem item = mList.get(position) 
      // some update 
     } 
+1

Was für eine wunderbare Antwort! – wonsuc

+1

Warum ist es aber eine Liste von Nutzlasten? In welchem ​​Fall haben Sie mehr als ein Objekt in der Liste? Falls Sie notifyItemChanged mehrmals an derselben Position aufrufen? –

+0

Wenn Sie Kotlin verwenden, gibt es einen Hinweis darauf, dass Payload der Typ "Any" ist und in Java ist "Object", so dass Sie dort alles passieren können, was Sie wollen. Später werden Sie Ihre Objekte in 'onBindViewHolder (ViewHolder-Halter, int-Position, Liste Payloads)' werfen. Weitere Informationen finden Sie unter: https://developer.android.com/reference/android/support/v7/widget/RecyclerView.Adapter.html#notifyItemChanged(int, java.lang.Object) – murt

Verwandte Themen