如何自动滚动到recyclerView的底部?

Posted

技术标签:

【中文标题】如何自动滚动到recyclerView的底部?【英文标题】:How to scroll automatically to the bottom of the recyclerVew? 【发布时间】:2021-08-24 05:29:26 【问题描述】:

我正在制作一个聊天应用程序,我需要滚动到回收站视图的底部以显示最后一条消息。 发这个问题的主要目的是问如何滚动到recyclerView的底部。 我已经在 readMessage() 方法中尝试了下面这行代码,但仍然无法正常工作。

groupChatRecyclerView.smoothScrollToPosition(messageAdapter.getItemCount());

对于recyclerView:groupChatRecyclerView.setHasFixedSize(true);

对于 LinearLayoutManager:

linearLayoutManager = new LinearLayoutManager(getApplicationContext()); linearLayoutManager.setStackFromEnd(true); linearLayoutManager.setReverseLayout(false); groupChatRecyclerView.setLayoutManager(linearLayoutManager);

请问有人可以帮我吗? 代码:

private void readMessage() 
    mchat = new ArrayList<>();

    reference = groupReference.child("Messages");
    reference.addValueEventListener(new ValueEventListener() 
        @Override
        public void onDataChange(@NonNull DataSnapshot dataSnapshot) 
            mchat.clear();
            for (DataSnapshot snapshot : dataSnapshot.getChildren())
                GroupChats chat = snapshot.getValue(GroupChats.class);
                mchat.add(chat);

                messageAdapter = new GroupMessageAdapter(GroupMessageActivity.this, mchat, (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE));
                groupChatRecyclerView.setAdapter(messageAdapter);
                //linearLayoutManager.smoothScrollToPosition(groupChatRecyclerView, null, messageAdapter.getItemCount()-1);
               // groupChatRecyclerView.smoothScrollToPosition(messageAdapter.getItemCount());
            
        

        @Override
        public void onCancelled(@NonNull DatabaseError error) 

        
    );


GroupMessageAdapter 代码:

package com.example.chats.Adapter;




public class GroupMessageAdapter  extends 
RecyclerView.Adapter<RecyclerView.ViewHolder> 

private Context mContext;
public static final int MSG_TYPE_LEFT = 0;
public static final int MSG_TYPE_RIGHT = 1;
public static final int MSG_TYPE_IMAGE_LEFT = 2;
public static final int MSG_TYPE_IMAGE_RIGHT = 3;
private List<GroupChats> mChat;
FirebaseUser fuser;
LayoutInflater inflater;
DatabaseReference userRef = FirebaseDatabase.getInstance().getReference("Users");

public GroupMessageAdapter(Context mContext, List<GroupChats> mChat, LayoutInflater inflater) 
    this.mContext = mContext;
    this.mChat = mChat;
    this.inflater = inflater;


@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) 
    RecyclerView.ViewHolder viewHolder = null;
    inflater = LayoutInflater.from(parent.getContext());

    switch (viewType)
        case MSG_TYPE_LEFT:
            View textOnlyLViewHolder = inflater.inflate(R.layout.group_item_left, parent,false);
            viewHolder = new LeftMessageG(textOnlyLViewHolder);
            break;
        case MSG_TYPE_RIGHT:
            View textOnlyRViewHolder = inflater.inflate(R.layout.chat_item_right, parent,false);
            viewHolder = new RightMessageG(textOnlyRViewHolder);
            break;
        case MSG_TYPE_IMAGE_LEFT:
            View imageOnlyLViewHolder = inflater.inflate(R.layout.group_image_left, parent,false);
            viewHolder = new LeftImageG(imageOnlyLViewHolder);
            break;
        case MSG_TYPE_IMAGE_RIGHT:
            View imageOnlyRViewHolder = inflater.inflate(R.layout.image_right, parent,false);
            viewHolder = new RightImageG(imageOnlyRViewHolder);
            break;
        default:
    

    return viewHolder;


@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) 

    GroupChats chat = mChat.get(position);

    try

        String mess = chat.getMessage();

        userRef.child(chat.getSender()).addValueEventListener(new ValueEventListener() 
            @Override
            public void onDataChange(@NonNull DataSnapshot snapsh) 
                if (snapsh.exists())
                    final String userImage = snapsh.child("imageURL").getValue().toString();


                    switch (holder.getItemViewType())
                        case MSG_TYPE_RIGHT:
                            RightMessageG rightM = (RightMessageG) holder;
                            rightM.show_messageR.setText(mess);
                            rightM.show_messageR.setOnClickListener(new View.OnClickListener() 
                                @Override
                                public void onClick(View v) 
                                    Toast.makeText(mContext, mess, Toast.LENGTH_SHORT).show();
                                
                            );
                            rightM.text_seen.setVisibility(View.INVISIBLE);
                            break;
                        case MSG_TYPE_LEFT:
                            LeftMessageG leftM = (LeftMessageG) holder;
                            leftM.show_messageL.setText(mess);
                            Glide.with(mContext).load(userImage).into(leftM.photoGMember);
                            break;
                        case MSG_TYPE_IMAGE_RIGHT:
                            RightImageG rightI = (RightImageG) holder;
                            rightI.text_seen.setVisibility(View.INVISIBLE);
                            rightI.show_imageR.setOnClickListener(new View.OnClickListener() 
                                @Override
                                public void onClick(View v) 
                                    Intent intent = new Intent(mContext, FullImage.class);
                                    intent.putExtra("image", mess);
                                    mContext.startActivity(intent);
                                
                            );
                            Glide.with(rightI.show_imageR).load(mess).into(rightI.show_imageR);
                            break;
                        case MSG_TYPE_IMAGE_LEFT:
                            LeftImageG leftI = (LeftImageG) holder;
                            Glide.with(mContext).load(userImage).into(leftI.photoGMember);
                            Glide.with(mContext).load(mess).into(leftI.show_imageL);
                            break;
                    
                
            

            @Override
            public void onCancelled(@NonNull DatabaseError error) 

            
        );

    catch (Exception e)

    



@Override
public int getItemCount() 
    return mChat.size();


@Override
public int getItemViewType(int position) 
    fuser = FirebaseAuth.getInstance().getCurrentUser();

    if (mChat.get(position).getSender().equals(fuser.getUid()))
        if (mChat.get(position).getType().equals("text"))
            return MSG_TYPE_RIGHT;
        else 
            return MSG_TYPE_IMAGE_RIGHT;
        

    
    else 
        if (mChat.get(position).getType().equals("text"))
            return MSG_TYPE_LEFT;
        else 
            return MSG_TYPE_IMAGE_LEFT;
        
    


public class LeftMessageG extends RecyclerView.ViewHolder
    public TextView show_messageL;
    public CircleImageView text_seen,photoGMember;

    public LeftMessageG(@NonNull View itemView) 
        super(itemView);
        show_messageL = itemView.findViewById(R.id.show_messageLL);
        text_seen = itemView.findViewById(R.id.text_seen);
        photoGMember = itemView.findViewById(R.id.photoGMember);
    


public class RightMessageG extends RecyclerView.ViewHolder
    public TextView show_messageR;
    public CircleImageView text_seen;

    public RightMessageG(@NonNull View itemView) 
        super(itemView);
        show_messageR = itemView.findViewById(R.id.show_messageR);
        text_seen = itemView.findViewById(R.id.text_seen);
    


public class RightImageG extends RecyclerView.ViewHolder
    public ImageView show_imageR;
    public CircleImageView text_seen;

    public RightImageG(@NonNull View itemView) 
        super(itemView);
        show_imageR = itemView.findViewById(R.id.show_imageR);
        text_seen = itemView.findViewById(R.id.text_seen);
    


public class LeftImageG extends RecyclerView.ViewHolder
    public ImageView show_imageL;
    public CircleImageView text_seen, photoGMember;

    public LeftImageG(@NonNull View itemView) 
        super(itemView);
        show_imageL = itemView.findViewById(R.id.show_imageL);
        text_seen = itemView.findViewById(R.id.text_seen);
        photoGMember = itemView.findViewById(R.id.photoGMember);
    

【问题讨论】:

这能回答你的问题吗? How to scroll to the bottom of a RecyclerView? scrollToPosition doesn't work 您的列表中显示了多少条消息? 添加新消息后它会继续变化 【参考方案1】:

试试这个

groupChatRecyclerView.smoothScrollToPosition(groupChatRecyclerView.getAdapter().getItemCount() - 1);

【讨论】:

【参考方案2】:

在你的 readMessage 函数中添加这个

groupChatRecyclerView.scrollToPosition(mchat.size - 1);

滚动到添加到 RecyclerView 的最后一项。

【讨论】:

我已经尝试过了,但它不起作用。我不知道为什么 从你的代码看来你没有尝试过,你尝试了一些不同的东西(即注释掉)

以上是关于如何自动滚动到recyclerView的底部?的主要内容,如果未能解决你的问题,请参考以下文章

Android-->RecyclerView 显示底部,滚动底部(无动画)

没有滚动时屏幕底部的 Recyclerview 页脚和滚动时位于列表末尾的 Recyclerview 页脚

检测 RecyclerView 滚动时何时到达最底部位置

解决RecyclerView&ListView滚动到顶部或者底部边界出现阴影问题

AdapterView 和 RecyclerView 的连续滚动

java 监听RecyclerView滚动到顶部/底部