Search code examples
androidandroid-studioandroid-layoutlistviewandroid-listview

How do I align ListView items based on a condition?


I am creating a chat program with Android Studio, and I am having trouble figuring out a way to show a list of messages that are left aligned for incoming messages and right aligned for outgoing messages. Right now, they are all left aligned.

What is the simplest way to left and right align text based on if the user id is the same as the current logged in user id? Below is what it looks like right now.

Current List View Sample


Solution

  • Assuming you are using Firebase for this app and getting the currently logged-in user details, you can make some changes to the Adapter class (MessageAdapter in this example).

    Credits to numerous youtube videos and online resources that I used to do this in my app

    1. Create chat_item_right.xml and chat_item_left.xml for 2 different users
    2. Make some changes in the MessageAdapter class
    public class MessageAdapter extends RecyclerView.Adapter<MessageAdapter.MyViewHolder> {
    
        public static final int MSG_TYPE_LEFT = 0;
        public static final int MSG_TYPE_RIGHT = 1;
    
        private Context mContext;
        private List<Chat> mChat;
        private String imageurl;
    
        private FirebaseUser firebaseUser;
    
        public MessageAdapter(Context mContext, List<Chat> mChat, String imageurl) {
            this.mContext = mContext;
            this.mChat = mChat;
            this.imageurl = imageurl;
            firebaseUser = FirebaseAuth.getInstance().getCurrentUser();
        }
    
        @NonNull
        @Override
        public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
            // Get the view type and create the right view
            View view;
            if (viewType == MSG_TYPE_RIGHT) {
                view = LayoutInflater.from(mContext).inflate(R.layout.chat_item_right, parent, false);
            }
            else {
                view = LayoutInflater.from(mContext).inflate(R.layout.chat_item_left, parent, false);
            }
            return new MyViewHolder(view);
        }
    
        // Method to get each chat message and show it
        @Override
        public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
            Chat chat = mChat.get(position);
    
            if (imageurl.equals("default")) {
                holder.profile_image.setImageResource(R.mipmap.ic_launcher);
            }
            else {
                Glide.with(mContext).load(imageurl).into(holder.profile_image);
            }
           
            if (chat.getType().equals("text")) {
                holder.show_message.setText(chat.getMessage());
            }
            else if (chat.getType().equals("image")) {
                // Depends on your code here
                Glide.with(mContext).load(chat.getMessage()).into(holder.image_message);
            }
        }
    
        @Override
        public int getItemCount() {
            return mChat.size();
        }
    
        public class MyViewHolder extends RecyclerView.ViewHolder {
            private TextView show_message, txt_seen;
            private ImageView profile_image, image_message;
    
            public MyViewHolder(@NonNull View itemView) {
                super(itemView);
                show_message = itemView.findViewById(R.id.show_message);
                profile_image = itemView.findViewById(R.id.profile_image);
                txt_seen = itemView.findViewById(R.id.txt_seen);
                image_message = itemView.findViewById(R.id.image_message);     
            }
        }
    
        @Override
        public int getItemViewType(int position) {
            // If i'm the sender show message on right else show it on left
            if (mChat.get(position).getSender().equals(firebaseUser.getUid())) {
                return  MSG_TYPE_RIGHT;
            }
            else {
                return MSG_TYPE_LEFT;
            }
        }
    
    }
    
    
    1. Call this in your MessageActivity or Fragment class
    private MessageAdapter messageAdapter;
    private List<Chat> mChat;
    private DatabaseReference reference;
    private FirebaseUser firebaseUser;
    private String userid;
    
    . // All your relevant code here
    .
    .
    
    firebaseUser = FirebaseAuth.getInstance().getCurrentUser();
    
    // You should have stored the current user the moment you have logged in
    // in SharedPrefs perhaps (or DataStore or etc) so that we can compare later
    // during set view_item to left or right
    // For e.g sending the userID as bundle from Login Page to MessageActivity
    // intent = new Intent(this, MessageActivity.class);
    // bundle.putString("userid", user);
    userid = intent.getStringExtra("userid");
    
    private void readMessages(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);
                        // Add to chat list only messages between you and the sender
                        assert chat != null;
                        // The below code depends on your Chat object class
                        // So please modify accordingly
                        if (chat.getReceiver() != null && chat.getSender() != null) {
                            if (chat.getReceiver().equals(myId) && chat.getSender().equals(userid) ||
                                    chat.getReceiver().equals(userid) && chat.getSender().equals(myId)) {
                                mChat.add(chat);
                            }
                        }
                    }
                    // Create a new adapter and set it to our view
                    messageAdapter = new MessageAdapter(MessageActivity.this, mChat, imageurl);
                    recyclerView.setAdapter(messageAdapter);
                }
    
                @Override
                public void onCancelled(@NonNull DatabaseError databaseError) {
    
                }
            });
        }
    
    // Call the function
    readMessages(firebaseUser.getUid(), userid, user.getImageURL());