添加 notifyDataSetChanged() 后检测到不一致错误
Inconsistency detected error after adding notifyDataSetChanged()
我正在制作 activity 日志,但我遇到无法向下滚动的问题,不一致错误不断弹出。我也添加了 notifyDataSetChanged 方法,但我仍然无法修复错误。
这是我遇到的错误
java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid item position 7(offset:7).state:11 android.support.v7.widget.RecyclerView{edb17ac
这是我的适配器代码
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder>{
private List<ListItem> listItems;
private Context context;
public MyAdapter(List<ListItem> listItems, Context context) {
this.listItems = listItems;
this.context = context;
}
public MyAdapter(Context applicationContext, List<ListItem> listItems) {
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.list_item, parent, false);
return new ViewHolder(v);
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
for(int i=0;i<listItems.size(); i++){
if (listItems.get(position).getHead().equals("Time")){
listItems.remove(listItems.get(position));
}
}
ListItem listItem = listItems.get(position);
String key = listItem.getHead();
if (key.equals("LockTime")) {
holder.textViewHead.setText(listItem.getTime());
holder.textViewDesc.setText(listItem.getDesc());
holder.layout.setBackground(ContextCompat.getDrawable(context, R.drawable.red_gradient));
holder.image1.setImageResource(R.drawable.lockwhite);
holder.image2.setImageResource(R.drawable.lockwhite);
} else if (key.equals("UnlockTime")) {
holder.textViewHead.setText(listItem.getTime());
holder.textViewDesc.setText(listItem.getDesc());
holder.layout.setBackground(ContextCompat.getDrawable(context, R.drawable.green_gradient));
holder.image1.setImageResource(R.drawable.unlockwhite);
holder.image2.setImageResource(R.drawable.unlockwhite);
}
}
@Override
public int getItemCount() {
return listItems.size();
}
public class ViewHolder extends RecyclerView.ViewHolder{
public TextView textViewHead;
public TextView textViewDesc;
public RelativeLayout layout;
public ImageView image1;
public ImageView image2;
public ViewHolder(View itemView) {
super(itemView);
textViewHead = (TextView) itemView.findViewById(R.id.textViewHead);
textViewDesc = (TextView) itemView.findViewById(R.id.textViewDesc);
layout= (RelativeLayout) itemView.findViewById(R.id.relativelayout);
image1 = itemView.findViewById(R.id.padlock1);
image2 = itemView.findViewById(R.id.padlock2);
}
}
}
这是我的Activity
public class ActivityLog extends AppCompatActivity {
private RecyclerView recyclerView;
private RecyclerView.Adapter adapter;
private List<ListItem> listItems;
SwipeRefreshLayout swipe;
DatabaseReference database;
LinearLayout lLayout;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView = (RecyclerView) findViewById(R.id.recycle);
recyclerView.setHasFixedSize(true);
// SharedPreferences preferences=getSharedPreferences(LOCK_PREFS,MODE_PRIVATE);
database = FirebaseDatabase.getInstance().getReference("Activity Log/device321");
swipe = findViewById(R.id.swiper);
listItems = new ArrayList<>();
database.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot usersnapshot : dataSnapshot.getChildren()) {
Map<String, String> map = (Map<String, String>) usersnapshot.getValue();
for (Map.Entry<String, String> entry : map.entrySet()) {
listItems.add(new ListItem(entry.getKey(), entry.getValue(),usersnapshot.child("Time").getValue().toString()
));
}
}
recyclerView.setAdapter(new MyAdapter(getApplicationContext(),listItems));
adapter.notifyDataSetChanged();
adapter = new MyAdapter(listItems, ActivityLog.this);
recyclerView.setAdapter(adapter);
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
swipe.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
database.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot usersnapshot : dataSnapshot.getChildren()) {
Map<String, String> map = (Map<String, String>) usersnapshot.getValue();
for (Map.Entry<String, String> entry : map.entrySet()) {
listItems.add(new ListItem(entry.getKey(), entry.getValue(),usersnapshot.child("Time").getValue().toString()
));
}
}
recyclerView.setAdapter(new MyAdapter(getApplicationContext(),listItems));
adapter = new MyAdapter(listItems, ActivityLog.this);
recyclerView.setAdapter(adapter);
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
swipe.setRefreshing(false);
}
},2000);
listItems.clear();
}
});
}
}
任何帮助将不胜感激谢谢
我希望这对你有用。
您设置了两次 Adapter。删除下面的行。
recyclerView.setAdapter(new MyAdapter(getApplicationContext(),listItems));
adapter.notifyDataSetChanged();
刷新时使用 swipyrefreshlayout 时禁用 recyclerview 滚动。一次滚动和更新数据会导致不一致错误。
仅当您的适配器中有多个添加、删除或重新排列时,您才需要 notifyDataSetChanged()。当您调用 setAdapter 时,没有必要调用 notifyDataSetChanged()。
当您绑定 viewholder 时,您不应从列表中删除项目,因为您更改了位置并且需要重新创建 RecyclerView。
在您的构造函数中或除您的适配器之外的任何地方删除它们。
public MyAdapter(List<ListItem> listItems, Context context) {
for(int i=0;i<listItems.size(); i++){
if (listItems.get(position).getHead().equals("Time")){
listItems.remove(listItems.get(position));
}
}
this.listItems = listItems;
this.context = context;
}
我正在制作 activity 日志,但我遇到无法向下滚动的问题,不一致错误不断弹出。我也添加了 notifyDataSetChanged 方法,但我仍然无法修复错误。
这是我遇到的错误
java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid item position 7(offset:7).state:11 android.support.v7.widget.RecyclerView{edb17ac
这是我的适配器代码
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder>{
private List<ListItem> listItems;
private Context context;
public MyAdapter(List<ListItem> listItems, Context context) {
this.listItems = listItems;
this.context = context;
}
public MyAdapter(Context applicationContext, List<ListItem> listItems) {
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.list_item, parent, false);
return new ViewHolder(v);
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
for(int i=0;i<listItems.size(); i++){
if (listItems.get(position).getHead().equals("Time")){
listItems.remove(listItems.get(position));
}
}
ListItem listItem = listItems.get(position);
String key = listItem.getHead();
if (key.equals("LockTime")) {
holder.textViewHead.setText(listItem.getTime());
holder.textViewDesc.setText(listItem.getDesc());
holder.layout.setBackground(ContextCompat.getDrawable(context, R.drawable.red_gradient));
holder.image1.setImageResource(R.drawable.lockwhite);
holder.image2.setImageResource(R.drawable.lockwhite);
} else if (key.equals("UnlockTime")) {
holder.textViewHead.setText(listItem.getTime());
holder.textViewDesc.setText(listItem.getDesc());
holder.layout.setBackground(ContextCompat.getDrawable(context, R.drawable.green_gradient));
holder.image1.setImageResource(R.drawable.unlockwhite);
holder.image2.setImageResource(R.drawable.unlockwhite);
}
}
@Override
public int getItemCount() {
return listItems.size();
}
public class ViewHolder extends RecyclerView.ViewHolder{
public TextView textViewHead;
public TextView textViewDesc;
public RelativeLayout layout;
public ImageView image1;
public ImageView image2;
public ViewHolder(View itemView) {
super(itemView);
textViewHead = (TextView) itemView.findViewById(R.id.textViewHead);
textViewDesc = (TextView) itemView.findViewById(R.id.textViewDesc);
layout= (RelativeLayout) itemView.findViewById(R.id.relativelayout);
image1 = itemView.findViewById(R.id.padlock1);
image2 = itemView.findViewById(R.id.padlock2);
}
}
}
这是我的Activity
public class ActivityLog extends AppCompatActivity {
private RecyclerView recyclerView;
private RecyclerView.Adapter adapter;
private List<ListItem> listItems;
SwipeRefreshLayout swipe;
DatabaseReference database;
LinearLayout lLayout;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView = (RecyclerView) findViewById(R.id.recycle);
recyclerView.setHasFixedSize(true);
// SharedPreferences preferences=getSharedPreferences(LOCK_PREFS,MODE_PRIVATE);
database = FirebaseDatabase.getInstance().getReference("Activity Log/device321");
swipe = findViewById(R.id.swiper);
listItems = new ArrayList<>();
database.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot usersnapshot : dataSnapshot.getChildren()) {
Map<String, String> map = (Map<String, String>) usersnapshot.getValue();
for (Map.Entry<String, String> entry : map.entrySet()) {
listItems.add(new ListItem(entry.getKey(), entry.getValue(),usersnapshot.child("Time").getValue().toString()
));
}
}
recyclerView.setAdapter(new MyAdapter(getApplicationContext(),listItems));
adapter.notifyDataSetChanged();
adapter = new MyAdapter(listItems, ActivityLog.this);
recyclerView.setAdapter(adapter);
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
swipe.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
database.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot usersnapshot : dataSnapshot.getChildren()) {
Map<String, String> map = (Map<String, String>) usersnapshot.getValue();
for (Map.Entry<String, String> entry : map.entrySet()) {
listItems.add(new ListItem(entry.getKey(), entry.getValue(),usersnapshot.child("Time").getValue().toString()
));
}
}
recyclerView.setAdapter(new MyAdapter(getApplicationContext(),listItems));
adapter = new MyAdapter(listItems, ActivityLog.this);
recyclerView.setAdapter(adapter);
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
swipe.setRefreshing(false);
}
},2000);
listItems.clear();
}
});
}
}
任何帮助将不胜感激谢谢
我希望这对你有用。
您设置了两次 Adapter。删除下面的行。
recyclerView.setAdapter(new MyAdapter(getApplicationContext(),listItems));
adapter.notifyDataSetChanged();
刷新时使用 swipyrefreshlayout 时禁用 recyclerview 滚动。一次滚动和更新数据会导致不一致错误。
仅当您的适配器中有多个添加、删除或重新排列时,您才需要 notifyDataSetChanged()。当您调用 setAdapter 时,没有必要调用 notifyDataSetChanged()。
当您绑定 viewholder 时,您不应从列表中删除项目,因为您更改了位置并且需要重新创建 RecyclerView。 在您的构造函数中或除您的适配器之外的任何地方删除它们。
public MyAdapter(List<ListItem> listItems, Context context) {
for(int i=0;i<listItems.size(); i++){
if (listItems.get(position).getHead().equals("Time")){
listItems.remove(listItems.get(position));
}
}
this.listItems = listItems;
this.context = context;
}