2015-10-16 12 views
21

İlk olarak, ingilizce hakkında özür dilerim. yaklaşık RecyclerView belgelerine göre notifyItemChanged(int position, Object payload)Örnek: RecyclerView.Adapter.notifyItemChanged (int konumu, Nesne yükü)

pozisyonunda madde, isteğe bağlı bir yük nesnesi ile değişmiş olduğu herhangi bir kayıtlı gözlemci haberdar medthod.

Bu yöntemde ikinci paramenatör payload'u nasıl kullanacağımı anlamıyorum. "Yük" hakkında birçok belge aradım ama her şey belirsizdi.

Bu yöntem hakkında bilgi sahibiseniz, lütfen bana açık bir örnek gösteriniz. Çok teşekkür ederim.

cevap

19

Özelliği gösteren bu örnek kod göz atın. notifyItemChanged(position, payload) numaralı telefonu arayarak, position numaralı adrese tıklandığında RecyclerView numaralı telefonu tıklatır. Logcat deyimini arayarak onBindViewHolder(holder, position, payload)'un çağrıldığını doğrulayabilirsiniz.

bunu gibi en az sürümünü destek kütüphanelerin 23.1.1 kullandığınızdan emin olun:

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

Eğer tüm tutucu Görünüm ama sadece bölümünü güncellemek isterseniz
<?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

Sadece kodunuzu test ettim. Testimde işe yaramaz bir şey var: temel onBind (yük olmadan) asla çağrılamaz. Şimdi neden yapıyorsun Ben sadece notifyItemRangeChanged (index, mArrayList.size()); veya notifyItemInserted (i); – Cocorico

+4

olgunlaşmamış kayıt etiketine bakın +1 – styler1972

1

onBindViewHolder yöntemi çağrıldığında ViewHolder'daki verilere kısmi bir güncelleştirme yapmak istediğinizde "isteğe bağlı bir yük nesnesi" iletebilirsiniz. Ancak, yükün her zaman geçirileceğinden emin değilsiniz, örneğin görünüm eklenmediyse, daha fazla kontrol gerçekleştirmeniz gerekir.

Her neyse, null'u iletirseniz, öğeye tam bir güncelleme gerçekleştirilir ve bunun için endişelenmenize gerek kalmaz.

26

, bu yöntem ne ihtiyaç vardır. tvScore

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

[...]

- kodunuzda bir yere

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); 
     } 

    } 

Ve ViewHolder aşağıdakilere sahip

Image adaptör tekTextView güncellemek için çağrı

onBindViewHolder (ViewHolder tutucu, int position, Liste yükler), ilk önce geri çekmeyi yakalar. payloads gereksinimlerinizle eşleşmiyorsa, diğer durumlarda onBindViewHolder(ViewHolder holder, int position) numaralı tetikleyici olan süper sınıf super.onBindViewHolder(holder,position, payloads); numaralı zorunlu telefonu arayın.

 // 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

Ne harika bir cevap! – wonsuc

+1

Neden bir yük listesi listesi var? Bu durumda listede birden fazla nesne var mı? Aynı konumda birden çok kez notifyItemChanged'ı çağırırsanız? –

+0

Kotlin'i kullanıyorsanız, yükün 'Any' türünde ve Java'da' Object' olduğunu varsayalım, böylece istediğiniz herhangi bir şeyi iletebilirsiniz. Daha sonra, nesnelerinizi 'onBindViewHolder (ViewHolder tutucu, int konum, Liste yükler)' içinde olacak. Daha fazla bilgi için: https://developer.android.com/reference/android/support/v7/widget/RecyclerView.Adapter.html#notifyItemChanged(int, java.lang.Object) – murt