【已解决】 求助,使用recyclerView时,notifyDataSetChanged顺序错乱
我的adapter里面传入一个list,初始化的时候是对的,当我切换不同日期的数据,从数据库中获取,想要显示在上面时,却乱序了。
数据库中获取的数据没错,我把获取的list覆盖了本来的list,更新时有数据,但是是错乱重复的,不同月份信息还混在了一起
public void notifyListDateDataChanged(List<BillDetail> newBillDetailsList){
this.mBillDetailsList.clear();
this.mBillDetailsList.addAll(newBillDetailsList);
for (int i = 0; i <mBillDetailsList.size(); i++) {
Log.d(TAG, "notifyListDateDataChanged: 第"+i+":"+mBillDetailsList.get(i).get_id());
}
notifyDataSetChanged();
}
上面代码是外部传入list更改数据用的,有没有大神踩过这个坑,求助,是我理解的不对吗
adapter全部代码
public class BillListAdapter extends RecyclerView.Adapter<BillListAdapter.InnerViewHolder> {
private static final String TAG = "BillListAdapter";
private List<BillDetail> mBillDetailsList;
private TextView tvListNote,tvListAmount;
private ImageView tvListSrc;
private TextView tvTotalDate,tvTotalOut,tvTotalIn;
private Table_Bill_Dao mTable_bill_dao;
private final int VIEW_TYPE_BILL = 1;
private final int VIEW_TYPE_NOT_BILL = -1;
private Table_Icon_Dao mTable_icon_dao;
public BillListAdapter(List<BillDetail> billDetailList){
this.mBillDetailsList = billDetailList;
}
@NonNull
@Override
public BillListAdapter.InnerViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view;
mTable_bill_dao = new Table_Bill_Dao(parent.getContext());
mTable_icon_dao = new Table_Icon_Dao(parent.getContext());
if(viewType == VIEW_TYPE_BILL){//每个数据项
view = View.inflate(parent.getContext(), R.layout.detail_list_layout_per,null);
Log.d(TAG, "onCreateViewHolder: in"+VIEW_TYPE_BILL);
}
else{//统计数据项
view = View.inflate(parent.getContext(), R.layout.detail_list_layout_count,null);
Log.d(TAG, "onCreateViewHolder: in"+VIEW_TYPE_NOT_BILL);
}
return new InnerViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull BillListAdapter.InnerViewHolder holder, int position) {
Log.d(TAG, "onBindViewHolder: 现在的position是"+position);
if(mBillDetailsList.get(position).get_id()!=-1){
holder.setData(mBillDetailsList.get(position));
holder.itemView.setTag(String.valueOf(mBillDetailsList.get(position).get_id())+mBillDetailsList.get(position).get_date());
Log.d(TAG, "onBindViewHolder: 数据加载"+holder.getAdapterPosition()+" "
+mBillDetailsList.get(holder.getAdapterPosition()).get_id());
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.d(TAG, "onClick: 点到了第"+holder.getAdapterPosition()+"项,库里的id是");
}
});
}else{
holder.setTotalData(mBillDetailsList.get(position));
}
}
@Override
public int getItemCount() {
return mBillDetailsList.size();
}
@Override
public int getItemViewType(int position) {
if(mBillDetailsList.get(position).get_id()==-1){//代表不是账单项
return VIEW_TYPE_NOT_BILL;
}else return VIEW_TYPE_BILL;
}
@Override
public long getItemId(int position) {
return position;
}
public void notifyListDateDataChanged(List<BillDetail> newBillDetailsList){//外部更新list
this.mBillDetailsList.clear();
notifyItemRangeRemoved(0,mBillDetailsList.size());
this.mBillDetailsList.addAll(newBillDetailsList);
for (int i = 0; i <mBillDetailsList.size(); i++) {
Log.d(TAG, "notifyListDateDataChanged: 第"+i+":"+mBillDetailsList.get(i).get_id());
}
notifyDataSetChanged();
}
public class InnerViewHolder extends RecyclerView.ViewHolder{
public InnerViewHolder(@NonNull View itemView) {//根据布局类型初始化
super(itemView);
if(itemView.findViewById(R.id.detail_list_notes)!=null){
tvListNote = itemView.findViewById(R.id.detail_list_notes);
tvListAmount = itemView.findViewById(R.id.detail_list_amount);
tvListSrc = itemView.findViewById(R.id.detail_list_src);
}
if(itemView.findViewById(R.id.detail_total_date)!=null){
tvTotalDate = itemView.findViewById(R.id.detail_total_date);
tvTotalOut = itemView.findViewById(R.id.detail_total_count_outgo);
tvTotalIn = itemView.findViewById(R.id.detail_total_count_income);
}
}
public void setData(BillDetail billDetail) {//设置数据
CategoryIcon categoryIcon = mTable_icon_dao.getIconById(billDetail.getIcon_id());
Log.d(TAG, "setData: 现在加载的是"+billDetail.get_id());
int resourceId = itemView.getResources().getIdentifier(categoryIcon.getSrc(),"drawable",itemView.getContext().getPackageName());
if(Constants.OUTGO_STRING.equals(categoryIcon.getType())){
tvListAmount.setText("-"+billDetail.getAmount());
}else{
tvListAmount.setText(billDetail.getAmount());
}
if(billDetail.getNotes()==null||billDetail.getNotes().length()<1){
tvListNote.setText(categoryIcon.getDescription());
}else{
tvListNote.setText(billDetail.getNotes());
}
if(resourceId!=0){
tvListSrc.setImageDrawable(ContextCompat.getDrawable(itemView.getContext(),resourceId));
}
}
public void setTotalData(BillDetail billDetail) {//设置数据项数据
String inPerDay = mTable_bill_dao.countInPerDay(billDetail.get_date());
String outPerDay = mTable_bill_dao.countOutPerDay(billDetail.get_date());
Log.d(TAG, "setTotalData: 现在加载的是"+billDetail.get_id());
tvTotalDate.setText(billDetail.get_date());
if(outPerDay==null)
tvTotalOut.setText("0");
else
tvTotalOut.setText(outPerDay);
if(inPerDay==null)
tvTotalIn.setText("0");
else
tvTotalIn.setText(inPerDay);
}
}
}
我看了你的代码:
1、这个地方
这两个内容的创建,意义不大:
因为onCreateViewHolder是多次调用的
2、这里的删除我没理解
为啥会有这个删除的
3、这里的代码写得不好
多次findViewById了,同一个作用的呢。
重复的原因是啥呢?
问题应该是出现在这里:
这些控件是属于类的内部的,为啥整到外部类里呢?
当onCreateViewHolder时,你去创建InnerViewHolder,就给以上这些变量赋值。
这个是循环动作,意味着,表示最后一个。
当这个方法onBindViewHolder回调时,你设置数据,设置的是谁的呀?当然是只能设置最后一个控件的。所以你前面所有的item项都没有设置到了。
具体,结合你的UI现象分析一下。
对适配器里的每一项理解不够。
上全部代码吧。一般来说不会,还有一个api,就是更新第几行到第几行.
只好新建,但是这样感觉效率很低