NotifyDataSetChanged Recycler视图:Recycler时无法调用此方法

时间:2019-02-28 00:45:58

标签: android database android-recyclerview adapter notifydatasetchanged

我正在制作一个聊天应用程序。我有一个回收站视图。我使用Picasso下载用户和与之聊天的朋友的图像。为了不为每条消息下载图像,当我下载第一个图像时,我只是将其放入位图并每次使用。

问题:我无法致电NotifyDataSetChanged。我已经尝试过在网上找到的所有可能的东西。

ERROR : 
Cannot call this method while RecyclerView is computing a layout or scrolling android.support.v7.widget.RecyclerView

我必须“手动”刷新视图,以便加载图像。文字没问题。 它与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);
    }
}

2 个答案:

答案 0 :(得分:0)

尝试一下。

dialeecyclerView.post(new Runnable()
                {
                    @Override
                    public void run() {
                    myadapter.notifyDataSetChanged();
                }
                });

来源-Cannot call this method while RecyclerView is computing a layout or scrolling when try remove item from recyclerview

答案 1 :(得分:0)

这是因为您要像这样在notifyDataSetChanged内部调用onBindViewHolder

@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()。例如,当您的数据集更改时。