【已解决】 notifyDataSetChanged 与 getItemCount 导致的刷新问题
DEMO工程文件下载
链接:https://pan.baidu.com/s/1IgeTZwW3kD0dOmGElIQ5OQ
提取码:k7qd
主函数是一个TCPClient,连接电脑server做测试,电脑发送clear则 mItemBeanLists.clear(); 如果电脑发送数据,则按照;符号行分割显示出来。
问题在于,如果我getItemCount里面返回超出mItemBeanLists真实长度的话,会导致clear或remove并刷新后显示的数据并没有真正清除!
MainActivity
public class MainActivity extends Activity {
private static final String TAG = "MainActivity";
RecyclerView recyclerView;
List<String> mItemBeanLists = new ArrayList<>();
LongListViewAdapter mListViewAdapter = new LongListViewAdapter();
PZHelp_TCPClient mTCPClient;
Handler mHandler = new Handler();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initRecyclerView();
mTCPClient = new PZHelp_TCPClient("192.168.0.161", 9999, new PZHelp_TCPClient.ReceiveListener() {
@Override
public void onSuccess() {
}
@Override
public void onFail(String err) {
}
@Override
public void Receive(String response) {
Log.d(TAG, "Receive: " + response);
if (response.equals("clear")) {
mItemBeanLists.clear();
} else {
String[] datas = response.split(";", -1);
for (int i = 0; i < datas.length; i++) {
mItemBeanLists.add(i, datas[i]);
}
}
mHandler.post(new Runnable() {
@Override
public void run() {
mListViewAdapter.notifyDataSetChanged();
for (int i = 0; i < mItemBeanLists.size(); i++) {
Log.d(TAG, " mItemBeanLists.get(i): " + mItemBeanLists.get(i));
}
}
});
}
});
mTCPClient.start();
}
private void initRecyclerView() {
recyclerView = findViewById(R.id.recyclerView);
//设置布局管理器
LinearLayoutManager mLinearLayoutManager1 = new LinearLayoutManager(this);
mLinearLayoutManager1.setOrientation(LinearLayoutManager.VERTICAL);
recyclerView.setLayoutManager(mLinearLayoutManager1);
//设置适配器
mListViewAdapter.setData(mItemBeanLists);
recyclerView.setAdapter(mListViewAdapter);
}
@Override
protected void onDestroy() {
mTCPClient.close();
super.onDestroy();
}
}
LongListViewAdapter
public class LongListViewAdapter extends RecyclerView.Adapter<LongListViewAdapter.InnerHolder> {
String TAG = "LongListViewAdapter";
private List<String> mData;
void setData(List<String> data) {
mData = data;
}
@NonNull
@Override
public LongListViewAdapter.InnerHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
//创建条目的回调函数
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_recyclerview, parent, false);
return new LongListViewAdapter.InnerHolder(view);
}
@Override
public void onBindViewHolder(@NonNull LongListViewAdapter.InnerHolder holder, int position) {
//绑定数据
if (mData != null && mData.size() > 0) {
int nowPosition = position % mData.size();
holder.setData(mData.get(nowPosition), position);
}
}
@Override
public int getItemCount() {
//设置条目数量
if (mData != null) {
return Integer.MAX_VALUE;//做循环效果
//return mData.size();
}
return 0;
}
@SuppressLint("SetTextI18n,StaticFieldLeak")
static class InnerHolder extends RecyclerView.ViewHolder {
TextView textView;
int mPosition;
InnerHolder(@NonNull View itemView) {
super(itemView);
textView = itemView.findViewById(R.id.textView);
}
void setData(String s, int position) {
textView.setText(s);
mPosition = position;
}
}
}
当我第一次发送数据后:


显示的数据正常无误
当我使用clear后:


就可以发现数据并没有完全清除,但实际上mItemBeanLists的的确确情况了,这里的显示我无法理解
再次clear便会“正常”(其实并没有,它是按照一定数量减少的,只是第二次再clear后减少的条目大于剩余的条目)
增加项1:当我返回数值固定为7,每次clear减少前2行,如果返回固定为8,每次clear减少前3行,当我固定为5后,clear直接“失效”,显示的数据不变!
解决问题:
上下文都没有,你在自嗨吗?
你用的是listView还是RecyclerView。你说notifyDatasetChanage出问题了,那你又不给适配器代码
因没有场景没有上下文集的话,根本不知道你为什么要clear,
如果说你的数据是新数据,那不是应该先清除再添加吗?
否则就是叠加数据。
getItemCount与mItemBeanLists的长度应该一致,先别做循环的效果,也就是要返回集合的长度,先把最基本的展示做好先。
另外则是前后端分离,独立思考。
后端要保证的是数据是对的,指令是收到了。也就是你那个log是有输出的。
其他的事情就是android这里实现了。
第三个就是RecyclerView适配器里的数据建议你独立来开,虽这么写,传个引用进去,外面置空你容易就崩溃了。
面向对象呀,你的适配器里有一个集合,你要清除,调用适配器.clear,你要添加就适配器.add,add之前先清除所有的,再进行添加。
以上这些,你应该可以解决这个问题了。