Java RecyclerView,显示我在RecyclerView上发送的最后一条消息
我的代码有问题,我创建了个人聊天,但当我发送消息时,RecyclerView不会自动显示最后发送的消息,但我必须向下滚动,如何确保自动显示最后发送的消息 公共类ChatListAdapter扩展了RecyclerView.Adapter{Java RecyclerView,显示我在RecyclerView上发送的最后一条消息,java,android,android-layout,android-recyclerview,Java,Android,Android Layout,Android Recyclerview,我的代码有问题,我创建了个人聊天,但当我发送消息时,RecyclerView不会自动显示最后发送的消息,但我必须向下滚动,如何确保自动显示最后发送的消息 公共类ChatListAdapter扩展了RecyclerView.Adapter{ private Activity mActivity; private DatabaseReference mDataBaseReference; private String mDisplayName; private ArrayList<DataSn
private Activity mActivity;
private DatabaseReference mDataBaseReference;
private String mDisplayName;
private ArrayList<DataSnapshot> mDataSnapshot;
private ChildEventListener mListener = new ChildEventListener () {
@Override
public void onChildAdded(DataSnapshot dataSnapshot,String s) {
mDataSnapshot.add (dataSnapshot);
notifyDataSetChanged ();
}
@Override
public void onChildChanged(DataSnapshot dataSnapshot,String s) {
}
@Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
}
@Override
public void onChildMoved(DataSnapshot dataSnapshot,String s) {
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
};
public ChatListAdapter(Activity activity, DatabaseReference ref, String name){
mActivity = activity;
mDataBaseReference = ref.child ("messaggi");
mDisplayName = name;
mDataSnapshot = new ArrayList <> ();
mDataBaseReference.addChildEventListener (mListener);
}
public class ChatViewHolder extends RecyclerView.ViewHolder{
TextView autore;
TextView messaggio;
LinearLayout.LayoutParams params;
public ChatViewHolder(View itemView) {
super (itemView);
autore = (TextView)itemView.findViewById (R.id.tv_autore);
messaggio = (TextView)itemView.findViewById (R.id.tv_messaggio);
params = (LinearLayout.LayoutParams) autore.getLayoutParams ();
}
}
@NonNull
@Override
public ChatViewHolder onCreateViewHolder(@NonNull ViewGroup parent,int viewType) {
LayoutInflater inflater = (LayoutInflater)mActivity.getSystemService (Context.LAYOUT_INFLATER_SERVICE);
View v = inflater.inflate (R.layout.chat_msg_row, parent, false);
ChatViewHolder vh = new ChatViewHolder (v);
return vh;
}
@Override
public void onBindViewHolder(@NonNull ChatViewHolder holder,int position) {
DataSnapshot snapshot = mDataSnapshot.get (position);
Messaggio msg = snapshot.getValue (Messaggio.class);
holder.autore.setText (msg.getAutore ());
holder.messaggio.setText (msg.getMessaggio ());
boolean sonoIo = msg.getAutore ().equals (mDisplayName);
setChatItemStyle(sonoIo, holder);
}
private void setChatItemStyle(boolean sonoIo, ChatViewHolder holder){
if(sonoIo){
holder.params.gravity = Gravity.END;
holder.autore.setTextColor (Color.GREEN);
holder.messaggio.setBackgroundResource(R.drawable.in_msg_bg);
}else{
holder.params.gravity = Gravity.START;
holder.autore.setTextColor (Color.CYAN);
holder.messaggio.setBackgroundResource(R.drawable.out_msg_bg);
}
holder.autore.setLayoutParams (holder.params);
holder.messaggio.setLayoutParams (holder.params);
}
@Override
public int getItemCount() {
return mDataSnapshot.size ();
}
public void clean(){
mDataBaseReference.removeEventListener (mListener);
}
private Activity;
私有数据库引用mDataBaseReference;
私有字符串mDisplayName;
私有ArrayList mDataSnapshot;
private ChildEventListener mListener=新的ChildEventListener(){
@凌驾
公共void onChildAdded(DataSnapshot DataSnapshot,字符串s){
mDataSnapshot.add(dataSnapshot);
notifyDataSetChanged();
}
@凌驾
公共void onChildChanged(DataSnapshot DataSnapshot,字符串s){
}
@凌驾
ChildRemoved上的公共void(DataSnapshot DataSnapshot){
}
@凌驾
已移动ChildMoved上的公共void(DataSnapshot DataSnapshot,字符串s){
}
@凌驾
已取消的公共void(DatabaseError DatabaseError){
}
};
公共ChatListAdapter(活动、数据库引用、字符串名称){
活动性=活动性;
mDataBaseReference=ref.child(“messaggi”);
mDisplayName=名称;
mDataSnapshot=newarraylist();
mDataBaseReference.addChildEventListener(MLListener);
}
公共类ChatViewHolder扩展了RecyclerView.ViewHolder{
文本视图自动;
文本视图消息;
LinearLayout.LayoutParams参数;
公共聊天室视图持有者(查看项目视图){
超级(项目视图);
autore=(TextView)itemviewbyd(R.id.tv\u autore);
messaggio=(TextView)itemView.findViewById(R.id.tv_messaggio);
params=(LinearLayout.LayoutParams)autore.getLayoutParams();
}
}
@非空
@凌驾
public ChatViewHolder onCreateViewHolder(@NonNull ViewGroup父级,int viewType){
LayoutInflater充气器=(LayoutInflater)mActivity.getSystemService(Context.LAYOUT\u充气器\u服务);
视图v=充气机充气(R.layout.chat\u msg\u行,父级,false);
ChatViewHolder vh=新的ChatViewHolder(v);
返回vh;
}
@凌驾
public void onBindViewHolder(@NonNull ChatViewHolder,int位置){
DataSnapshot snapshot=mDataSnapshot.get(位置);
Messaggio msg=snapshot.getValue(Messaggio.class);
holder.autore.setText(msg.getAutore());
holder.messaggio.setText(msg.getMessaggio());
布尔sonoIo=msg.getAutore().equals(mDisplayName);
setChatItemStyle(sonoIo,支架);
}
私有void setChatItemStyle(布尔sonoIo、ChatViewHolder){
国际单项体育联合会(索诺里奥){
holder.params.gravity=gravity.END;
holder.autore.setTextColor(Color.GREEN);
持有人信息收进背景资源(R.drawable.in_msg_bg);
}否则{
holder.params.gravity=gravity.START;
holder.autore.setTextColor(Color.CYAN);
持有人.信息.收件背景资源(R.可提取.输出\u信息\u背景);
}
holder.autore.setLayoutParams(holder.params);
holder.messaggio.setLayoutParams(holder.params);
}
@凌驾
public int getItemCount(){
返回mDataSnapshot.size();
}
公共空间清洁(){
mDataBaseReference.removeEventListener(mListener);
}
}您可以在
LinearLayoutManager
上将stackFromEnd
设置为true。如果您的聊天信息首先返回最近的信息,您也可以在manager上反转,而不是在数据中反转。然后,要在更改的数据集上自动滚动,只需在您的RecyclerView xml上设置android:transcriptMode
为normal
(仅在已位于底部时滚动)或alwaysScroll
(更改后始终滚动到底部)
boolean reverseLayout = true; // Or false if your data is already reversed
LinearLayoutManager manager = new LinearLayoutManager(context, LinearLayoutManager.VERTICAL, reverseLayout);
manager.setStackFromEnd(true);
yourRecyclerView.setLayoutManager(manager);
我假设您正在使用回收器视图来填充消息 就是这样 变量声明
private RecyclerView rvChat;
一次创建
rvChat = findViewById(R.id.a_individual_chat_rv_chat);
OnChildaded(在notifyDataSetChanged之后)
尝试使用
notifyItemInserted
而不是notifyDataSetChanged
它询问notifyItemInserted上的int(我需要在这里写什么?);并在末尾插入的示例中创建me private void notifyItemInsetted(){},对吗?因此,您可以给notifyItemInserted(mDataSnapshot.size()-1)所有内容都正确,但即使有这些更改,我也必须保持向下滚动。在notifyItemInserted之后,执行此操作<代码>recyclerView.scrollToPosition(mDataSnapshot.size()-1)代码>另一个建议是,不要在适配器类的范围之外维护数据集。这看起来可能更容易,但会导致一致性问题。而是通过构造函数将数据集传递给适配器,并添加一个方法来替换数据集并在其中通知适配器。我是否也必须输入所有这些代码?我在代码的哪一部分发布了?这是在你的“回收者”视图中设置的。您的代码中没有引用,因此您需要应用它,因为它是有意义的。我已经测试过,这是一个用于回收器视图的片段适配器模型构造。
rvChat.smoothScrollToPosition(rvChat.getAdapter().getItemCount());