NotifyDataSetChanged Recycler view: невозможно вызвать этот метод, пока Recycler - PullRequest
0 голосов
/ 28 февраля 2019

Я делаю приложение для чата.У меня есть вид переработчика.Я использую Picasso для загрузки изображений пользователя и друга, с которым он общается.Чтобы не загружать изображение для каждого сообщения, при загрузке первого изображения я просто помещаю его в растровое изображение и использую его каждый раз.

ПРОБЛЕМА: я не могу вызвать NotifyDataSetChanged.Я перепробовал все возможные вещи, которые нашел в сети.

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

Мне нужно «вручную» обновить вид, чтобы загружались изображения.Нет проблем для текста.Он работает с обработчиком, но даже не входит в функцию (поэтому представление не обновляется).Вот мой код (все работает, кроме этого 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 голосов
/ 28 февраля 2019

Это потому, что вы звоните 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(), когда вам это нужно.Например, когда ваш набор данных изменен.

0 голосов
/ 28 февраля 2019
...