Нужен пример о RecyclerView.Адаптер.notifyItemChanged (int позиция, полезная нагрузка объекта)
по данным RecyclerView
документация о medthod notifyItemChanged (int позиция, полезная нагрузка объекта)
уведомить всех зарегистрированных наблюдателей, что элемент в позиции изменился с дополнительным объектом полезной нагрузки.
Я не понимаю, как использовать второй параметр payload
в этот метод. Я искал много документов о "полезной нагрузке", но все было неоднозначно.
Итак, если вы знаете об этом методе, пожалуйста, покажите мне наглядный пример об этом. Большое спасибо.
4 ответов
проверьте этот пример кода, который демонстрирует эту функцию. Это RecyclerView
что называет notifyItemChanged(position, payload)
когда деталь на положении это. Вы можете проверить это onBindViewHolder(holder, position, payload)
был вызван путем поиска оператора logcat.
убедитесь, что вы используете хотя бы версию 23.1.1
библиотек поддержки, например:
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>
если вы хотите обновить Не все вид держателя, но просто часть этот метод является то, что вам нужно.
изображение, которое у вас есть следующие 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-tvScore
mRecyclerViewAdapter.notifyItemChanged(position, new Integer(4533));
[...]
onBindViewHolder(держатель держателя, 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
}
вы можете передать "дополнительный объект полезной нагрузки", когда вы просто хотите выполнить частичное обновление данных в ViewHolder
когда onBindViewHolder
метод называется. Однако он не уверен, что полезная нагрузка всегда будет передаваться, например, если представление не прикреплено, поэтому необходимо выполнить еще несколько проверок.
в любом случае, если вы проходите null
будет выполнено полное обновление элемента, и вам не придется беспокоиться об этом.
в принципе, гораздо удобнее рассматривать полезные нагрузки как константы.
Вам не нужно передавать туда какие-либо данные, если они уже изменены в наборе данных.
Итак, создайте пару констант:
public static final String PAYLOAD_NAME = "PAYLOAD_NAME";
public static final String PAYLOAD_AGE = "PAYLOAD_AGE";
тогда в адаптере, кроме обычного onBindViewHolder(YourViweHolder holder, int position)
где вы обновляете весь элемент, например:
@Override
public void onBindViewHolder(final YourViewHolder holder, final int position) {
final YourItem item = getItem(position);
holder.tvName.setText(item.getName());
holder.tvAge.setText(String.valueOf(item.getAge()));
}
кроме того, вы реализуете:
@Override
public void onBindViewHolder(final YourViewHolder holder, final int position, final List<Object> payloads) {
if (!payloads.isEmpty()) {
final YourItem item = getItem(position);
for (final Object payload : payloads) {
if (payload.equals(PAYLOAD_NAME)) {
// in this case only name will be updated
holder.tvName.setText(item.getName());
} else if (payload.equals(PAYLOAD_AGE)) {
// only age will be updated
holder.tvAge.setText(String.valueOf(item.getAge()));
}
}
} else {
// in this case regular onBindViewHolder will be called
super.onBindViewHolder(holder, position, payloads);
}
}
вы можете обрабатывать столько случаев, сколько вам нужно, и обновлять только представления, которые на самом деле измененный.
Последний шаг-вы просто делаете:
adapter.notifyItemChanged(somePosition, YourAdapter.PAYLOAD_NAME);