当我点击不同的人聊天室应用程序打开同一个人聊天

Posted

技术标签:

【中文标题】当我点击不同的人聊天室应用程序打开同一个人聊天【英文标题】:When I click on different person Chat room the app opening the same person chat 【发布时间】:2021-09-10 01:35:16 【问题描述】:

我遇到了问题,请检查查找问题:当我点击不同的聊天室时,它会打开同一个聊天室,如下所示:

这是 Chatsfragment.java(左侧屏幕)

public class ChatsFragment extends Fragment

private RecyclerView recyclerView;

private FriendsAdapter userAdapter;
private List<Users> mUsers;

FirebaseUser fuser;
DatabaseReference reference;

private List<String> usersList;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)

    View view = inflater.inflate(R.layout.fragment_chats, container, false);

    recyclerView = view.findViewById(R.id.ChatsFragment_recyclerView);
    recyclerView.setHasFixedSize(true);
    recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));


    usersList = new ArrayList<>();

    fuser = FirebaseAuth.getInstance().getCurrentUser();
    reference = FirebaseDatabase.getInstance().getReference("Chats");
    reference.addValueEventListener(new ValueEventListener() 
        @Override
        public void onDataChange(@NonNull DataSnapshot dataSnapshot) 
            usersList.clear();

            for(DataSnapshot snapshot:dataSnapshot.getChildren())

                Chat chat=snapshot.getValue(Chat.class);

                assert chat != null;
                if (chat.getSender().equals(fuser.getUid())) 

                    usersList.add(chat.getReceiver());

                

                if (chat.getReceiver().equals(fuser.getUid())) 

                    usersList.add(chat.getSender());

                

            


            Set<String> hashSet = new HashSet<String>(usersList);
            usersList.clear();
            usersList.addAll(hashSet);
            readChats();


        

        @Override
        public void onCancelled(@NonNull DatabaseError databaseError) 

        
    );

    UpdateToken();
    return view;


private void UpdateToken() 
    FirebaseUser firebaseUser = FirebaseAuth.getInstance().getCurrentUser();
    String refreshToken = FirebaseInstanceId.getInstance().getToken();
    Token token = new Token(refreshToken);
    FirebaseDatabase.getInstance().getReference("Tokens").child(FirebaseAuth.getInstance().getCurrentUser().getUid()).setValue(token);


private void readChats() 

    mUsers=new ArrayList<>();

    reference= FirebaseDatabase.getInstance().getReference("Users");

    reference.addValueEventListener(new ValueEventListener() 
        @Override
        public void onDataChange(@NonNull DataSnapshot dataSnapshot) 

            //mUsers.clear();

            for(DataSnapshot snapshot:dataSnapshot.getChildren())

                Users user=snapshot.getValue(Users.class);

                for(String id:usersList)
                

                    assert user != null;
                    if (user.getUser_id().equals(id)) 

                        mUsers.add(user);

                    

                

            

            userAdapter=new FriendsAdapter(getContext(),mUsers,true);
            recyclerView.setAdapter(userAdapter);


        

        @Override
        public void onCancelled(@NonNull DatabaseError databaseError) 

        
    );


这是 MessageActivity.java(右侧屏幕)

public class MessageActivity extends AppCompatActivity 

CircleImageView profile_image;
TextView username,fullname;

FirebaseUser fuser;
DatabaseReference reference;

private Toolbar toolbar;
Intent intent;
boolean notify = false;

TextView btn_send;
EditText text_send;

MessageAdapter messageAdapter;
List<Chat> mchat;

RecyclerView recyclerView;
String userid;

private APIService apiService;

@Override
protected void onCreate(Bundle savedInstanceState) 
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_message);

    toolbar = findViewById(R.id.MessageActivity_toolbar);
    setSupportActionBar(toolbar);
    getSupportActionBar().setTitle("");
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);

    username = (TextView)findViewById(R.id.MessageActivity_userName);
    fullname = (TextView)findViewById(R.id.MessageActivity_fullname);
    profile_image = (CircleImageView)findViewById(R.id.MessageActivity_user_img);
    btn_send =findViewById(R.id.MessageActivity_btn_send);
    text_send = findViewById(R.id.MessageActivity_text_send);

    apiService = Client.getClient("https://fcm.googleapis.com/").create(APIService.class);

    recyclerView = findViewById(R.id.MessageActivity_recyclerView);
    recyclerView.setHasFixedSize(true);
    LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getApplicationContext());
    linearLayoutManager.setStackFromEnd(true);
    recyclerView.setLayoutManager(linearLayoutManager);

    intent = getIntent();
    userid = intent.getStringExtra("userid");

    fuser = FirebaseAuth.getInstance().getCurrentUser();
    reference = FirebaseDatabase.getInstance().getReference("Users").child(userid);

    reference.addValueEventListener(new ValueEventListener() 
        @Override
        public void onDataChange(@NonNull DataSnapshot dataSnapshot) 
            Users user = dataSnapshot.getValue(Users.class);
            username.setText(user.getUsername());
            fullname.setText(user.getFullName());
            Glide.with(MessageActivity.this)
                    .load(user.getProfilePhoto())
                    .into(profile_image);
            readMesagges(fuser.getUid(), userid, user.getProfilePhoto());
        

        @Override
        public void onCancelled(@NonNull DatabaseError databaseError) 

        
    );

    btn_send.setOnClickListener(new View.OnClickListener() 
        @Override
        public void onClick(View view) 
            notify = true;
            String msg = text_send.getText().toString();
            if (!msg.equals(""))
                sendMessage(fuser.getUid(), userid, msg);
             else 
                Toast.makeText(MessageActivity.this, "You can't send empty message", Toast.LENGTH_SHORT).show();
            
            text_send.setText("");
            closeKeyboard();
        
    );



private void sendMessage(String sender, final String receiver, String message)

    DatabaseReference reference = FirebaseDatabase.getInstance().getReference();

    HashMap<String, Object> hashMap = new HashMap<>();
    hashMap.put("sender", sender);
    hashMap.put("receiver", receiver);
    hashMap.put("message", message);
    hashMap.put("isseen", false);

    reference.child("Chats").push().setValue(hashMap);

    final String msg = message;
    reference = FirebaseDatabase.getInstance().getReference("Users").child(fuser.getUid());
    reference.addValueEventListener(new ValueEventListener() 
        @Override
        public void onDataChange(@NonNull DataSnapshot dataSnapshot) 
            Users user = dataSnapshot.getValue(Users.class);
            if (notify) 
                sendNotifiaction(receiver, user.getUsername(), msg);
            
            notify = false;
        

        @Override
        public void onCancelled(@NonNull DatabaseError databaseError) 

        
    );



private void sendNotifiaction(String receiver, final String username, final String message) 

    DatabaseReference tokens = FirebaseDatabase.getInstance().getReference("Tokens");
    Query query = tokens.orderByKey().equalTo(receiver);
    query.addValueEventListener(new ValueEventListener() 
        @Override
        public void onDataChange(@NonNull DataSnapshot dataSnapshot) 
            for (DataSnapshot snapshot : dataSnapshot.getChildren())
                Token token = snapshot.getValue(Token.class);
                Data data = new Data(fuser.getUid(), R.mipmap.ic_launcher, username+":"+message, "New Message",
                        userid);

                NotificationSender sender = new NotificationSender(data, token.getToken());

                apiService.sendNotification(sender).enqueue(new Callback<MyResponse>() 
                    @Override
                    public void onResponse(Call<MyResponse> call, Response<MyResponse> response) 
                        if (response.code() == 200)
                            if (response.body().success != 1)
                                Toast.makeText(MessageActivity.this, "Failed", Toast.LENGTH_SHORT).show();
                            
                        
                    

                    @Override
                    public void onFailure(Call<MyResponse> call, Throwable t) 

                    
                );
            
        

        @Override
        public void onCancelled(@NonNull DatabaseError databaseError) 

        
    );



private void readMesagges(final String myid, final String userid, final String imageurl)
    mchat = new ArrayList<>();

    reference = FirebaseDatabase.getInstance().getReference("Chats");
    reference.addValueEventListener(new ValueEventListener() 
        @Override
        public void onDataChange(@NonNull DataSnapshot dataSnapshot) 
            mchat.clear();
            for (DataSnapshot snapshot : dataSnapshot.getChildren())
                Chat chat = snapshot.getValue(Chat.class);
                if (chat.getReceiver().equals(myid) && chat.getSender().equals(userid) ||
                        chat.getReceiver().equals(userid) && chat.getSender().equals(myid))
                    mchat.add(chat);
                
                messageAdapter = new MessageAdapter(MessageActivity.this, mchat, imageurl);
                recyclerView.setAdapter(messageAdapter);

            
        

        @Override
        public void onCancelled(@NonNull DatabaseError databaseError) 

        
    );


private void closeKeyboard()
    View view = this.getCurrentFocus();
    if(view != null)
        InputMethodManager imm = (InputMethodManager) this.getSystemService(Context.INPUT_METHOD_SERVICE);
        imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
    
 

这里是 FriendsAdapter.java

    public FriendsAdapter(Context mcontext, List<Users> muser, boolean ischat) 
        this.mcontext = mcontext;
        this.muser = muser;
        this.ischat = ischat;
    

    @NonNull
    @Override
    public FriendsAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) 
        View view = LayoutInflater.from(mcontext).inflate(R.layout.friends_single_layout,parent,false);
        return new FriendsAdapter.ViewHolder(view);

    

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

        firebaseUser = FirebaseAuth.getInstance().getCurrentUser();
        users = muser.get(position);
        holder.username.setText(users.getFullName());
//        holder.fullname.setText(users.getFullName());
        Glide.with(mcontext)
                .load(users.getProfilePhoto())
                .into(holder.profileimage);

        if (ischat)
            lastMessage(users.getUser_id(), holder.last_msg);
         else 
            holder.last_msg.setText(users.getFullName());
        

        holder.itemView.setOnClickListener(new View.OnClickListener() 
            @Override
            public void onClick(View v) 
                Intent intent = new Intent(mcontext, MessageActivity.class);
                intent.putExtra("userid",users.getUser_id());
                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                mcontext.startActivity(intent);
            
        );

    

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

    public class ViewHolder extends RecyclerView.ViewHolder 

        public TextView username,last_msg;
        public CircleImageView profileimage;

        public ViewHolder(@NonNull View itemView) 
            super(itemView);

            username = itemView.findViewById(R.id.FriendSingle_userName);
            last_msg = itemView.findViewById(R.id.FriendSingle_lastMsg);
            profileimage = itemView.findViewById(R.id.FriendSingle_user_img);
        
    

    //check for last message
    private void lastMessage(final String userid, final TextView last_msg)
        theLastMessage = "default";
        final FirebaseUser firebaseUser = FirebaseAuth.getInstance().getCurrentUser();
        DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Chats");

        reference.addValueEventListener(new ValueEventListener() 
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) 
                for (DataSnapshot snapshot : dataSnapshot.getChildren())
                    Chat chat = snapshot.getValue(Chat.class);
                    if (firebaseUser != null && chat != null) 
                        if (chat.getReceiver().equals(firebaseUser.getUid()) && chat.getSender().equals(userid) ||
                                chat.getReceiver().equals(userid) && chat.getSender().equals(firebaseUser.getUid())) 
                            theLastMessage = chat.getMessage();
                        
                    
                

                switch (theLastMessage)
                    case  "default":
                        last_msg.setText(users.getFullName());
                        break;

                    default:
                        last_msg.setText(theLastMessage);
                        break;
                

                theLastMessage = "default";
            

            @Override
            public void onCancelled(@NonNull DatabaseError databaseError) 

            
        );
    

同样,问题是每当用户点击 recyclerView 项目时,它会显示相同的聊天室,请找出错误并尽快让我知道。

感谢您的宝贵时间

【问题讨论】:

【参考方案1】:

根据您发布的内容(似乎缺少 FriendsAdapter.java 的一部分),问题似乎出在您的 FriendsAdapter 中。您可能已经在 Adapter 级别定义了 users 变量,但它应该在 ViewHolder 级别定义或仅用作局部变量。

您在bindViewHolder 方法中调用users = muser.get(position),因此如果users 在您的onClickListener 被触发时在适配器级别定义,则users 变量将设置为最后一个单元格的用户,而不是与单击的单元格关联的用户对象。

所以,从适配器级别删除users 的定义(可能看起来像这样):

User users;

或者在bindViewHolder方法中使用users作为局部变量:

User users = muser.get(position);

或者把定义放在你的ViewHolder

public class ViewHolder extends RecyclerView.ViewHolder 

    public User users;
    public TextView username,last_msg;
    public CircleImageView profileimage;

    public ViewHolder(@NonNull View itemView) 
        super(itemView);

        username = itemView.findViewById(R.id.FriendSingle_userName);
        last_msg = itemView.findViewById(R.id.FriendSingle_lastMsg);
        profileimage = itemView.findViewById(R.id.FriendSingle_user_img);
    

【讨论】:

以上是关于当我点击不同的人聊天室应用程序打开同一个人聊天的主要内容,如果未能解决你的问题,请参考以下文章

当我打开某个屏幕时如何收不到通知? - 安卓

与特定联系人打开 LINE android 应用程序的聊天屏幕

在聊天应用程序中实现推送通知

单击按钮时在 Ionic 上保持键盘打开(聊天应用程序)

从另一个移动应用程序启动 lync 聊天

与连接到同一个公共热点的所有用户聊天的 Android 聊天应用程序