如何自动滚动到回收站视图中的最新消息?

how to auto scroll to the newest message in recycler view?

你好,我尝试使用可能的方法在打开聊天框时自动向下滚动到最新消息,就像打开任何 WhatsApp 或任何聊天应用程序一样。 smoothscrolltoposition、smoothscroller 等等。chat design image

当我遇到这个问题时,请给我一个像 WhatsApp 一样使用这个聊天应用程序的解决方案 activity 我想在屏幕上看到最新消息。当打开键盘输入消息时,最后一条消息应该在键盘上方。 chat application image

我使用的代码是

    MessageEnvironmentAdapter messageEnvironmentAdapter = new MessageEnvironmentAdapter(MessageEnvironmentActivity.this, messageModelArrayList);
    messagerecycler = findViewById(R.id.messagerecycler);
    LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
    linearLayoutManager.setStackFromEnd(true);
    messagerecycler.setLayoutManager(linearLayoutManager);
    messagerecycler.setAdapter(messageEnvironmentAdapter);

从 firebase 实时数据库获取数据

    chatreference.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot snapshot) {
            messageModelArrayList.clear();
            for (DataSnapshot dataSnapshot : snapshot.getChildren()) {
                MessageModel messageModel = dataSnapshot.getValue(MessageModel.class);
                messageModelArrayList.add(messageModel);
            }
            messageEnvironmentAdapter.notifyDataSetChanged();
        }

        @Override
        public void onCancelled(@NonNull DatabaseError error) {

        }
    });

发送消息数据并存储在实时数据库中

    reference.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot snapshot) {
            simage = snapshot.child("imageuri").getValue().toString();
            rimage = reciverimage;
        }

        @Override
        public void onCancelled(@NonNull DatabaseError error) {

        }
    });
    sendmessagebtn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            String messagetext = editmessage.getText().toString().trim();
            if (messagetext.isEmpty()) {
                Toast.makeText(MessageEnvironmentActivity.this, "please enter valid message", Toast.LENGTH_SHORT).show();
                return;
            }

            editmessage.setText("");
            Date date = new Date();

            MessageModel messageModel = new MessageModel(messagetext, senderuid, date.getTime());

            database.getReference().child("chats")
                    .child(senderroom)
                    .child("messages")
                    .push()
                    .setValue(messageModel).addOnCompleteListener(new OnCompleteListener<Void>() {
                @Override
                public void onComplete(@NonNull Task<Void> task) {
                    database.getReference().child("chats")
                            .child(reciverroom)
                            .child("messages")
                            .push().setValue(messageModel).addOnCompleteListener(new OnCompleteListener<Void>() {
                        @Override
                        public void onComplete(@NonNull Task<Void> task) {

                        }
                    });
                }
            });
        }
    });

我从你的问题中得到的是,你想在编辑文本上方的 Recyclerview 中显示最后一条消息。好的,在 OnCreate 方法中添加非常简单 setRecyclerView() 并且因为当您的消息数组列表为空时 messageArrayList-1 将为 -1。所以在 setRecyclerView() 下面添加 setListeners() 就像下面的

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
                              savedInstanceState: Bundle?): View? {
        binding =FragmentGroupChatBinding.inflate(layoutInflater,container,false)
        initViews()
        setRecyclerView()
        setListeners()
        return binding.root
    }

private fun setRecyclerView() {
        recyclerView.layoutManager = LinearLayoutManager(requireActivity())
        adapter = MessagesAdapter(messageArrayList)
        recyclerView.adapter = adapter
        adapter.setClickListener(this)
        recyclerView.scrollToPosition(messageArrayList.size-1)
    } 



private fun setListeners() {
    recyclerView.addOnLayoutChangeListener { v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom ->
        if (bottom < oldBottom) {
            if (messageArrayList.isEmpty()){
                recyclerView.postDelayed(Runnable {
                    recyclerView.smoothScrollToPosition(messageArrayList.size) }, 100)
            }else{
                recyclerView.postDelayed(Runnable {
                    recyclerView.smoothScrollToPosition(messageArrayList.size-1) }, 100)
            }
        }
    }
}

下面一行就可以了

recyclerView.scrollToPosition(messageArrayList.size-1)

JAVA 代码

private void setListeners() {
     recyclerView.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
    @Override
    public void onLayoutChange(View v, int left, int top, int right, int bottom, 
   int oldLeft, int oldTop, int oldRight, int oldBottom) {
        if (bottom < oldBottom)
            if (messageArrayList.size()==0){
             recyclerView.postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            recyclerView.smoothScrollToPosition(messageArrayList.size());            
                        }
                    }, 100);
         }else{
         recyclerView.postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            recyclerView.smoothScrollToPosition(messageArrayList.size()-1);            
                        }
                    }, 100);
       }
    }
});

}