RecyclerView 异步加载 乱序 问题的解决
Posted Mars-xq
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了RecyclerView 异步加载 乱序 问题的解决相关的知识,希望对你有一定的参考价值。
参考:
郭霖 : Android ListView异步加载图片乱序问题,原因分析及解决方案
方法一:
1、 onCreateViewHolder
中获取 RecyclerView
@Override
public TestHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
View view = inflater.inflate(R.layout.layout_item, parent, false);
Log.e(TAG, "onCreateViewHolder: parent.getClass=====>" + parent.getClass());
if (parent instanceof RecyclerView) {
mRecyclerView = ((RecyclerView) parent); //核心
}
TestHolder holder = new TestHolder(view);
return holder;
}
2、onBindViewHolder中 :itemView子控件 setTag
holder.tvTitle.setTag(key);
3、onBindViewHolder中异步结果的地方 : mRecyclerView.findViewWithTag
找到对应控件再设置值
holder.tvTitle.postDelayed(new Runnable() {
@Override
public void run() {
if (mRecyclerView == null) {
return;
}
//异步获取的值
String value = finalI + " > " + (finalPosition * 100);
addValueToMemoryCache(key, value);
TextView view = (TextView) mRecyclerView.findViewWithTag(key); // 核心
if (view != null && !TextUtils.isEmpty(value)) {
view.setText(value);
view.setVisibility(View.VISIBLE);
}
}
}, i);
方法二:
1、RecyclerView.Adapter
实现类中定义方法和变量:
private HashMap<String, String> mHashMap = new HashMap<>();
/**
* 從缓存中获取已存在的值
*
* @param key
* @return
*/
private String getValueFromMemoryCache(String key) {
return mHashMap.get(key);
}
/**
* 添加到缓存中
*
* @param key
* @param value
*/
private void addValueToMemoryCache(String key, String value) {
if (getValueFromMemoryCache(key) == null) {
mHashMap.put(key, value);
}
}
2、onBindViewHolder
方法中getValueFromMemoryCache
有值直接设置,没值再异步获取,异步获取后addValueToMemoryCache
String memoryValue = getValueFromMemoryCache(key);
if (!TextUtils.isEmpty(memoryValue)) {
holder.tvTitle.setText(memoryValue);
holder.tvTitle.setVisibility(View.VISIBLE);
} else if (position % 2 == 0) {
holder.tvTitle.setVisibility(View.GONE);
} else {
holder.tvTitle.postDelayed(new Runnable() {
@Override
public void run() {
if (mRecyclerView == null) {
return;
}
//异步获取的值
String value = finalI + " > " + (finalPosition * 100);
addValueToMemoryCache(key, value);
TextView view = (TextView) mRecyclerView.findViewWithTag(key);
if (view != null && !TextUtils.isEmpty(value)) {
view.setText(value);
view.setVisibility(View.VISIBLE);
}
}
}, i);
}
demo:
import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import com.xq.divider.R;
import java.util.HashMap;
import java.util.List;
import java.util.Random;
public class TestAdapter extends RecyclerView.Adapter<TestAdapter.TestHolder> {
private List<String> data;
private static final String TAG = TestAdapter.class.getSimpleName();
private HashMap<String, String> mHashMap = new HashMap<>();
private RecyclerView mRecyclerView;
public TestAdapter(List<String> data) {
this.data = data;
}
public void setData(List<String> data) {
this.data = data;
notifyDataSetChanged();
}
@Override
public TestHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
View view = inflater.inflate(R.layout.layout_item, parent, false);
Log.e(TAG, "onCreateViewHolder: parent.getClass=====>" + parent.getClass());
if (parent instanceof RecyclerView) {
mRecyclerView = ((RecyclerView) parent);
}
TestHolder holder = new TestHolder(view);
return holder;
}
@Override
public void onBindViewHolder(final TestHolder holder, final int position) {
if (data != null && data.size() > 0) {
final String key = data.get(position);
Random random = new Random();
int i = random.nextInt(5 * 1000);
holder.tvContent.setText(key);
holder.tvTitle.setText("");
final int finalPosition = position;
final int finalI = i;
holder.tvTitle.setTag(key);
String memoryValue = getValueFromMemoryCache(key);
if (!TextUtils.isEmpty(memoryValue)) {
holder.tvTitle.setText(memoryValue);
holder.tvTitle.setVisibility(View.VISIBLE);
} else if (position % 2 == 0) {
holder.tvTitle.setVisibility(View.GONE);
} else {
holder.tvTitle.postDelayed(new Runnable() {
@Override
public void run() {
if (mRecyclerView == null) {
return;
}
//异步获取的值
String value = finalI + " > " + (finalPosition * 100);
addValueToMemoryCache(key, value);
TextView view = (TextView) mRecyclerView.findViewWithTag(key);
if (view != null && !TextUtils.isEmpty(value)) {
view.setText(value);
view.setVisibility(View.VISIBLE);
}
}
}, i);
}
}
}
@Override
public int getItemCount() {
return data == null ? 0 : data.size();
}
static class TestHolder extends RecyclerView.ViewHolder {
public TextView tvContent;
public TextView tvTitle;
public TestHolder(View itemView) {
super(itemView);
tvContent = (TextView) itemView.findViewById(R.id.tv_content);
tvTitle = (TextView) itemView.findViewById(R.id.tv_title);
tvContent.setTextSize(20.0f);
tvTitle.setTextSize(16.0f);
}
}
/**
* 從缓存中获取已存在的值
*
* @param key
* @return
*/
private String getValueFromMemoryCache(String key) {
return mHashMap.get(key);
}
/**
* 添加到缓存中
*
* @param key
* @param value
*/
private void addValueToMemoryCache(String key, String value) {
if (getValueFromMemoryCache(key) == null) {
mHashMap.put(key, value);
}
}
}
以上是关于RecyclerView 异步加载 乱序 问题的解决的主要内容,如果未能解决你的问题,请参考以下文章
基于Android官方AsyncListUtil优化改进RecyclerView分页加载机制