2015-10-16 29 views
21

まず、私の英語については残念です。 はmedthod notifyItemChanged(int position, Object payload)RecyclerView.Adapter.notifyItemChanged(int position、Object payload)の例が必要

RecyclerViewドキュメントに応じた位置にある項目は、オプションのペイロード・オブジェクトに変更されたことを、登録オブザーバに通知します。

この方法では、第2パラメータの使用方法はわかりません。​​私は "ペイロード"について多くの文書を検索しましたが、すべてがあいまいでした。

この方法について知っていれば、それに関する明確な例を教えてください。どうもありがとうございました。

答えて

19

機能を示すサンプルコードをご覧ください。ポジションpositionの項目をクリックすると、がnotifyItemChanged(position, payload)と表示されます。 logcat文を探して、onBindViewHolder(holder, position, payload)が呼び出されたことを確認できます。

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:

は、あなたがそうのように、少なくともバージョンのサポートライブラリの23.1.1を使用していることを確認します。 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

私はあなたのコードをテストしました。私のテストでは役に立たないことがあります。基本的なonBind(ペイロードなし)は決して呼び出されません。あなたは今なぜですか?私はnotifyItemRangeChanged(index、mArrayList.size())を呼び出します。または notifyItemInserted(i); – Cocorico

+4

未熟なログタグを愛する+1 – styler1972

1

onBindViewHolderメソッドが呼び出されたときに、ViewHolderのデータを部分的に更新するだけの場合は、「オプションのペイロードオブジェクト」を渡すことができます。ただし、ペイロードが常に渡されるかどうかはわかりません(たとえば、ビューが接続されていない場合など)。

とにかく、nullに合格すると、アイテムの完全な更新が実行されますので、気にする必要はありません。

26

あなたがないすべてホルダーの表示が、それのほんの一部を更新したい場合は、このメソッドは何が必要です。 tvScore

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

[...]

- あなたは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); 
     } 

    } 

そしてどこかにあなたのコードでは、あなたが単一のTextViewを更新するためのアダプタを呼び出して、次いる

画像

onBindViewHolder(ViewHolderホルダー、int位置、リストペイロード)は、最初にコールバックをキャッチします。 payloadsが要件に一致しない場合は、スーパークラスsuper.onBindViewHolder(holder,position, payloads);を呼び出して、他の場合はonBindViewHolder(ViewHolder holder, int position)をトリガーしなければなりません。

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

すてきな答え! – wonsuc

+1

それはなぜペイロードのリストですか?その場合、リストに複数のオブジェクトがありますか?あなたはnotifyItemChangedを同じ位置で複数回呼び出す場合は? –

+0

もしあなたがKotlinを使っているなら、ペイロードは 'Any'の型で、Javaでは' Object'なので、あなたが何かを渡すことができるというヒントがあります。後であなたのオブジェクトを 'onBindViewHolder(ViewHolderホルダー、int位置、リストペイロード)'にキャストします。詳細はhttps://developer.android.com/reference/android/support/v7/widget/RecyclerView.Adapter.html#notifyItemChanged(int、java.lang.Object)をご覧ください。 – murt

関連する問題