【问题标题】:how to auto scroll to the newest message in recycler view?如何在回收站视图中自动滚动到最新消息?
【发布时间】:2021-05-28 12:20:30
【问题描述】:

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

请给我一个解决方案,让我可以像 WhatsApp 一样使用这个聊天应用程序,当我参加这个活动时,我想在屏幕上看到最新消息。当打开键盘输入消息时,最后一条消息应该在键盘上方。 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) {

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

【问题讨论】:

    标签: java android firebase-realtime-database android-recyclerview android-linearlayout


    【解决方案1】:

    我从你的问题中得到的是你想在 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);
           }
        }
    });
    
    }
    

    【讨论】:

    • 谢谢你的回答,你能给我上面的java代码吗
    • @Shreyaspatne 添加了 java 代码。现在在messagerecycler.setAdapter(messageEnvironmentAdapter); 下方添加这一行 recyclerView.smoothScrollToPosition(messageArrayList.size());并在此调用 setListeners()
    • 请详细说明具体放置在哪里,代码流程
    • listner 函数中左下右是什么
    • MessageEnvironmentAdapter messageEnvironmentAdapter = new MessageEnvironmentAdapter(MessageEnvironmentActivity.this, messageModelArrayList); messagerecycler = findViewById(R.id.messagerecycler);线性布局管理器线性布局管理器 = 新线性布局管理器(这个); linearLayoutManager.setStackFromEnd(true); messagerecycler.setLayoutManager(linearLayoutManager); messagerecycler.setAdapter(messageEnvironmentAdapter); messagerecycler.smoothScrollToPosition(messageModelArrayList.size()); setListeners();
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-22
    • 1970-01-01
    • 2023-03-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多