NotifyDataSetChanged Recycler 视图:Recycler 时无法调用此方法
NotifyDataSetChanged Recycler view : Cannot call this method while Recycler
我正在制作一个聊天应用程序。我有一个回收者的观点。我使用 Picasso 下载用户和他正在聊天的朋友的图像。为了不为每条消息下载图像,当我下载第一张图像时,我只是将它放入位图中并每次都使用它。
问题:我无法调用 NotifyDataSetChanged。我已经尝试了我在网上找到的所有可能的东西。
ERROR :
Cannot call this method while RecyclerView is computing a layout or scrolling android.support.v7.widget.RecyclerView
我必须 "manually" 刷新视图以便加载图像。文字没问题。
它与 Handler 一起运行,但它甚至不进入函数(因此视图不会刷新)。
这是我的代码(除了这个 notifydatasetchanged 一切正常)
public class ChatActivity extends AppCompatActivity {
private RecyclerView recyclerChat;
private ListMessageAdapter adapter;
private EditText editWriteMessage;
private LinearLayoutManager linearLayoutManager;
private FirebaseAuth mAuth;
private DatabaseReference UserRef, MessageIDREF, UserMessageRef, SendMessageUser;
private List<ChatClass> ListOfChats = new ArrayList<>();
private ImageButton btnSend;
private String currentUserID, currentDateMessage, currentTimeMessage;
private CommunActivit obj = new CommunActivit();
private String FRIENDID;
private Toolbar mToolbar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chat);
mAuth=FirebaseAuth.getInstance();
currentUserID = mAuth.getCurrentUser().getUid();
MessageIDREF = FirebaseDatabase.getInstance().getReference().child("Friends");
UserMessageRef = FirebaseDatabase.getInstance().getReference().child("Message").child(obj.getsIDMESSAGE());
btnSend = (ImageButton) findViewById(R.id.btnSend);
editWriteMessage = (EditText) findViewById(R.id.editWriteMessage) ;
FRIENDID = obj.getsIDFRIEND();
mToolbar = (Toolbar) findViewById(R.id.main_app_bar2);
setSupportActionBar(mToolbar);
ActionBar ab = getSupportActionBar();
final String Title = obj.getsFRIENDName();
ab.setTitle(Title);
btnSend.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
SendMessageToGroupChat();
editWriteMessage.setText("");
}
});
retrievedata();
/*recyclerChat = (RecyclerView)findViewById(R.id.recyclerChat);
adapter = new ListMessageAdapter(this,ListOfChats);
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(this);
recyclerChat.setLayoutManager(layoutManager);
recyclerChat.setItemAnimator(new DefaultItemAnimator());
recyclerChat.setAdapter(adapter);*/
linearLayoutManager = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);
recyclerChat = (RecyclerView) findViewById(R.id.recyclerChat);
recyclerChat.setLayoutManager(linearLayoutManager);
adapter = new ListMessageAdapter(this, ListOfChats);
recyclerChat.setAdapter(adapter);
/* editWriteMessage.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
recyclerChat.smoothScrollToPosition(adapter.getItemCount());
return false;
}
});*/
}
private void SendMessageToGroupChat() {
String message = editWriteMessage.getText().toString();
String messageKey = UserMessageRef.push().getKey();
if (TextUtils.isEmpty(message)) {
Toast.makeText(this, "Please write a message first", Toast.LENGTH_SHORT).show();
} else {
Calendar calendarDate = Calendar.getInstance();
SimpleDateFormat DateFormat = new SimpleDateFormat("MMM dd, yyyy");
currentDateMessage = DateFormat.format(calendarDate.getTime());
Calendar calendarTime = Calendar.getInstance();
SimpleDateFormat TimeFormat = new SimpleDateFormat("hh:mm a");
currentTimeMessage = TimeFormat.format(calendarTime.getTime());
HashMap<String, Object> groupMessageKey = new HashMap<>();
UserMessageRef.updateChildren(groupMessageKey);
SendMessageUser = UserMessageRef.child(messageKey);
HashMap<String, Object> messageInfoMap = new HashMap<>();
messageInfoMap.put("name", obj.getsUsername());
messageInfoMap.put("message", message);
messageInfoMap.put("date", currentDateMessage);
messageInfoMap.put("time", currentTimeMessage);
messageInfoMap.put("image", obj.getsUserImageLink());
SendMessageUser.updateChildren(messageInfoMap);
}
}
public void retrievedata() {
UserMessageRef.addChildEventListener(new ChildEventListener() {
@Override
public void onChildAdded(@NonNull DataSnapshot dataSnapshot, @Nullable String s) /**** HERE IS THE PROBLEM***/
{
if (dataSnapshot.exists()) {
DisplayMessages(dataSnapshot);
}
}
@Override
public void onChildChanged(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {
if (dataSnapshot.exists()) {
DisplayMessages(dataSnapshot);
}
}
@Override
public void onChildRemoved(@NonNull DataSnapshot dataSnapshot) {
}
@Override
public void onChildMoved(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
});
}
private void DisplayMessages(DataSnapshot dataSnapshot)
{
Iterator iterator = dataSnapshot.getChildren().iterator();
while (iterator.hasNext()) {
String chatDate = (String) ((DataSnapshot) iterator.next()).getValue();
String chatImage = (String) ((DataSnapshot) iterator.next()).getValue();
String chatMessage = (String) ((DataSnapshot) iterator.next()).getValue();
String chatName = (String) ((DataSnapshot) iterator.next()).getValue();
String chatTime = (String) ((DataSnapshot) iterator.next()).getValue();
ListOfChats.add(new ChatClass(chatName, chatMessage, chatDate + " " + chatTime, chatImage));
adapter.notifyDataSetChanged();
recyclerChat.smoothScrollToPosition(adapter.getItemCount()); /**AUTO SCROLL**/
}
}
class ListMessageAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private Context context;
private ChatClass consersation;
private List<ChatClass> List_of_chats;
private CommunActivit obj = new CommunActivit();
private Bitmap BitmapUser;
private Bitmap BitmapFriend;
public ListMessageAdapter(Context context, List<ChatClass> List_of_chats) {
this.context = context;
this.List_of_chats = List_of_chats;
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if (viewType == 1) {
View view = LayoutInflater.from(context).inflate(R.layout.rc_item_message_friend, parent, false);
return new ItemMessageFriendHolder(view);
} else if (viewType == 2) {
View view = LayoutInflater.from(context).inflate(R.layout.rc_item_message_user, parent, false);
return new ItemMessageUserHolder(view);
}
return null;
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
final int pos =position;
if (holder instanceof ItemMessageFriendHolder) {
((ItemMessageFriendHolder) holder).txtContent.setText(List_of_chats.get(position).getMessage());
if (BitmapFriend == null) {
Picasso.get().load(List_of_chats.get(position).getImageLink()).into(new Target() {
@Override
public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
BitmapFriend = bitmap;
}
@Override
public void onBitmapFailed(Exception e, Drawable errorDrawable) {
}
@Override
public void onPrepareLoad(Drawable placeHolderDrawable) {
}
});
((ItemMessageFriendHolder) holder).avata.setImageBitmap(BitmapFriend);
}
else
{
((ItemMessageFriendHolder) holder).avata.setImageBitmap(BitmapFriend);
new Handler().post(new Runnable() {
@Override
public void run() {
notifyDataSetChanged();
}
});
}
}
else
{
if (holder instanceof ItemMessageUserHolder) {
((ItemMessageUserHolder) holder).txtContent.setText(List_of_chats.get(position).getMessage());
if (BitmapUser == null) {
Picasso.get().load(List_of_chats.get(position).getImageLink()).into(new Target() {
@Override
public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
BitmapUser = bitmap;
}
@Override
public void onBitmapFailed(Exception e, Drawable errorDrawable) {
}
@Override
public void onPrepareLoad(Drawable placeHolderDrawable) {
}
});
((ItemMessageUserHolder) holder).avata.setImageBitmap(BitmapUser);
} else {
((ItemMessageUserHolder) holder).avata.setImageBitmap(BitmapUser);
new Handler().post(new Runnable() {
@Override
public void run() {
notifyDataSetChanged();
}
});
}
}
}
}
@Override
public int getItemViewType(int position) {
int viewtype = -1;
if (List_of_chats.get(position).getUsername().equals(obj.getsUsername())) {
return 2;
}
else
{
return 1;
}
}
@Override
public int getItemCount() {
return List_of_chats.size();
}
}
class ItemMessageUserHolder extends RecyclerView.ViewHolder {
public TextView txtContent;
public CircleImageView avata;
public ItemMessageUserHolder(View itemView) {
super(itemView);
txtContent = (TextView) itemView.findViewById(R.id.textContentUser);
avata = (CircleImageView) itemView.findViewById(R.id.imageView2);
}
}
class ItemMessageFriendHolder extends RecyclerView.ViewHolder {
public TextView txtContent;
public CircleImageView avata;
public ItemMessageFriendHolder(View itemView) {
super(itemView);
txtContent = (TextView) itemView.findViewById(R.id.textContentFriend);
avata = (CircleImageView) itemView.findViewById(R.id.imageView3);
}
}
试试这个。
dialeecyclerView.post(new Runnable()
{
@Override
public void run() {
myadapter.notifyDataSetChanged();
}
});
来源 -
这是因为您在 onBindViewHolder
中调用 notifyDataSetChanged
是这样的:
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
...
((ItemMessageFriendHolder) holder).avata.setImageBitmap(BitmapFriend);
new Handler().post(new Runnable() {
@Override
public void run() {
notifyDataSetChanged();
}
});
...
}
您不应该强制适配器在尚未完成绑定视图之前刷新自身。
因此,您需要从 onBindViewHolder
中删除以下代码:
new Handler().post(new Runnable() {
@Override
public void run() {
notifyDataSetChanged();
}
});
然后在需要时调用 notifyDataSetChanged()
。例如,当您的数据集发生更改时。
我正在制作一个聊天应用程序。我有一个回收者的观点。我使用 Picasso 下载用户和他正在聊天的朋友的图像。为了不为每条消息下载图像,当我下载第一张图像时,我只是将它放入位图中并每次都使用它。
问题:我无法调用 NotifyDataSetChanged。我已经尝试了我在网上找到的所有可能的东西。
ERROR :
Cannot call this method while RecyclerView is computing a layout or scrolling android.support.v7.widget.RecyclerView
我必须 "manually" 刷新视图以便加载图像。文字没问题。 它与 Handler 一起运行,但它甚至不进入函数(因此视图不会刷新)。 这是我的代码(除了这个 notifydatasetchanged 一切正常)
public class ChatActivity extends AppCompatActivity {
private RecyclerView recyclerChat;
private ListMessageAdapter adapter;
private EditText editWriteMessage;
private LinearLayoutManager linearLayoutManager;
private FirebaseAuth mAuth;
private DatabaseReference UserRef, MessageIDREF, UserMessageRef, SendMessageUser;
private List<ChatClass> ListOfChats = new ArrayList<>();
private ImageButton btnSend;
private String currentUserID, currentDateMessage, currentTimeMessage;
private CommunActivit obj = new CommunActivit();
private String FRIENDID;
private Toolbar mToolbar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chat);
mAuth=FirebaseAuth.getInstance();
currentUserID = mAuth.getCurrentUser().getUid();
MessageIDREF = FirebaseDatabase.getInstance().getReference().child("Friends");
UserMessageRef = FirebaseDatabase.getInstance().getReference().child("Message").child(obj.getsIDMESSAGE());
btnSend = (ImageButton) findViewById(R.id.btnSend);
editWriteMessage = (EditText) findViewById(R.id.editWriteMessage) ;
FRIENDID = obj.getsIDFRIEND();
mToolbar = (Toolbar) findViewById(R.id.main_app_bar2);
setSupportActionBar(mToolbar);
ActionBar ab = getSupportActionBar();
final String Title = obj.getsFRIENDName();
ab.setTitle(Title);
btnSend.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
SendMessageToGroupChat();
editWriteMessage.setText("");
}
});
retrievedata();
/*recyclerChat = (RecyclerView)findViewById(R.id.recyclerChat);
adapter = new ListMessageAdapter(this,ListOfChats);
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(this);
recyclerChat.setLayoutManager(layoutManager);
recyclerChat.setItemAnimator(new DefaultItemAnimator());
recyclerChat.setAdapter(adapter);*/
linearLayoutManager = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);
recyclerChat = (RecyclerView) findViewById(R.id.recyclerChat);
recyclerChat.setLayoutManager(linearLayoutManager);
adapter = new ListMessageAdapter(this, ListOfChats);
recyclerChat.setAdapter(adapter);
/* editWriteMessage.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
recyclerChat.smoothScrollToPosition(adapter.getItemCount());
return false;
}
});*/
}
private void SendMessageToGroupChat() {
String message = editWriteMessage.getText().toString();
String messageKey = UserMessageRef.push().getKey();
if (TextUtils.isEmpty(message)) {
Toast.makeText(this, "Please write a message first", Toast.LENGTH_SHORT).show();
} else {
Calendar calendarDate = Calendar.getInstance();
SimpleDateFormat DateFormat = new SimpleDateFormat("MMM dd, yyyy");
currentDateMessage = DateFormat.format(calendarDate.getTime());
Calendar calendarTime = Calendar.getInstance();
SimpleDateFormat TimeFormat = new SimpleDateFormat("hh:mm a");
currentTimeMessage = TimeFormat.format(calendarTime.getTime());
HashMap<String, Object> groupMessageKey = new HashMap<>();
UserMessageRef.updateChildren(groupMessageKey);
SendMessageUser = UserMessageRef.child(messageKey);
HashMap<String, Object> messageInfoMap = new HashMap<>();
messageInfoMap.put("name", obj.getsUsername());
messageInfoMap.put("message", message);
messageInfoMap.put("date", currentDateMessage);
messageInfoMap.put("time", currentTimeMessage);
messageInfoMap.put("image", obj.getsUserImageLink());
SendMessageUser.updateChildren(messageInfoMap);
}
}
public void retrievedata() {
UserMessageRef.addChildEventListener(new ChildEventListener() {
@Override
public void onChildAdded(@NonNull DataSnapshot dataSnapshot, @Nullable String s) /**** HERE IS THE PROBLEM***/
{
if (dataSnapshot.exists()) {
DisplayMessages(dataSnapshot);
}
}
@Override
public void onChildChanged(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {
if (dataSnapshot.exists()) {
DisplayMessages(dataSnapshot);
}
}
@Override
public void onChildRemoved(@NonNull DataSnapshot dataSnapshot) {
}
@Override
public void onChildMoved(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
});
}
private void DisplayMessages(DataSnapshot dataSnapshot)
{
Iterator iterator = dataSnapshot.getChildren().iterator();
while (iterator.hasNext()) {
String chatDate = (String) ((DataSnapshot) iterator.next()).getValue();
String chatImage = (String) ((DataSnapshot) iterator.next()).getValue();
String chatMessage = (String) ((DataSnapshot) iterator.next()).getValue();
String chatName = (String) ((DataSnapshot) iterator.next()).getValue();
String chatTime = (String) ((DataSnapshot) iterator.next()).getValue();
ListOfChats.add(new ChatClass(chatName, chatMessage, chatDate + " " + chatTime, chatImage));
adapter.notifyDataSetChanged();
recyclerChat.smoothScrollToPosition(adapter.getItemCount()); /**AUTO SCROLL**/
}
}
class ListMessageAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private Context context;
private ChatClass consersation;
private List<ChatClass> List_of_chats;
private CommunActivit obj = new CommunActivit();
private Bitmap BitmapUser;
private Bitmap BitmapFriend;
public ListMessageAdapter(Context context, List<ChatClass> List_of_chats) {
this.context = context;
this.List_of_chats = List_of_chats;
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if (viewType == 1) {
View view = LayoutInflater.from(context).inflate(R.layout.rc_item_message_friend, parent, false);
return new ItemMessageFriendHolder(view);
} else if (viewType == 2) {
View view = LayoutInflater.from(context).inflate(R.layout.rc_item_message_user, parent, false);
return new ItemMessageUserHolder(view);
}
return null;
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
final int pos =position;
if (holder instanceof ItemMessageFriendHolder) {
((ItemMessageFriendHolder) holder).txtContent.setText(List_of_chats.get(position).getMessage());
if (BitmapFriend == null) {
Picasso.get().load(List_of_chats.get(position).getImageLink()).into(new Target() {
@Override
public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
BitmapFriend = bitmap;
}
@Override
public void onBitmapFailed(Exception e, Drawable errorDrawable) {
}
@Override
public void onPrepareLoad(Drawable placeHolderDrawable) {
}
});
((ItemMessageFriendHolder) holder).avata.setImageBitmap(BitmapFriend);
}
else
{
((ItemMessageFriendHolder) holder).avata.setImageBitmap(BitmapFriend);
new Handler().post(new Runnable() {
@Override
public void run() {
notifyDataSetChanged();
}
});
}
}
else
{
if (holder instanceof ItemMessageUserHolder) {
((ItemMessageUserHolder) holder).txtContent.setText(List_of_chats.get(position).getMessage());
if (BitmapUser == null) {
Picasso.get().load(List_of_chats.get(position).getImageLink()).into(new Target() {
@Override
public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
BitmapUser = bitmap;
}
@Override
public void onBitmapFailed(Exception e, Drawable errorDrawable) {
}
@Override
public void onPrepareLoad(Drawable placeHolderDrawable) {
}
});
((ItemMessageUserHolder) holder).avata.setImageBitmap(BitmapUser);
} else {
((ItemMessageUserHolder) holder).avata.setImageBitmap(BitmapUser);
new Handler().post(new Runnable() {
@Override
public void run() {
notifyDataSetChanged();
}
});
}
}
}
}
@Override
public int getItemViewType(int position) {
int viewtype = -1;
if (List_of_chats.get(position).getUsername().equals(obj.getsUsername())) {
return 2;
}
else
{
return 1;
}
}
@Override
public int getItemCount() {
return List_of_chats.size();
}
}
class ItemMessageUserHolder extends RecyclerView.ViewHolder {
public TextView txtContent;
public CircleImageView avata;
public ItemMessageUserHolder(View itemView) {
super(itemView);
txtContent = (TextView) itemView.findViewById(R.id.textContentUser);
avata = (CircleImageView) itemView.findViewById(R.id.imageView2);
}
}
class ItemMessageFriendHolder extends RecyclerView.ViewHolder {
public TextView txtContent;
public CircleImageView avata;
public ItemMessageFriendHolder(View itemView) {
super(itemView);
txtContent = (TextView) itemView.findViewById(R.id.textContentFriend);
avata = (CircleImageView) itemView.findViewById(R.id.imageView3);
}
}
试试这个。
dialeecyclerView.post(new Runnable()
{
@Override
public void run() {
myadapter.notifyDataSetChanged();
}
});
来源 -
这是因为您在 onBindViewHolder
中调用 notifyDataSetChanged
是这样的:
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
...
((ItemMessageFriendHolder) holder).avata.setImageBitmap(BitmapFriend);
new Handler().post(new Runnable() {
@Override
public void run() {
notifyDataSetChanged();
}
});
...
}
您不应该强制适配器在尚未完成绑定视图之前刷新自身。
因此,您需要从 onBindViewHolder
中删除以下代码:
new Handler().post(new Runnable() {
@Override
public void run() {
notifyDataSetChanged();
}
});
然后在需要时调用 notifyDataSetChanged()
。例如,当您的数据集发生更改时。