将 RecyclerView 内的 RelativeLayout 向右对齐

pul*_*ion 4 android android-layout

当您与某人聊天时,我正在尝试开发类似 Activity 的 Whatsapp。我已经能够创建如下内容:

在此处输入图片说明

此处的聊天消息有 2 种类型 - 已发送和已接收。我希望收到的消息在左侧,发送的消息在右侧。为此,我创建了一个带有 LinearLayoutManager 的 RecyclerView 左侧和右侧对齐的以下布局:

接收消息的布局,即显示在左侧。

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginBottom="8dp"
    android:layout_marginLeft="8dp"
    android:layout_marginTop="8dp"
    android:background="@drawable/message_view_border">

    <!--The message text-->
    <TextView
        android:id="@+id/message_content"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textStyle="bold"/>
    <!--the timestamp-->
    <TextView
        android:id="@+id/time_stamp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/message_content"
        android:textStyle="bold"/>

</RelativeLayout>
Run Code Online (Sandbox Code Playgroud)

已发送消息的布局,即显示在右侧。

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginBottom="8dp"
    android:background="@drawable/message_view_border"
    android:layout_marginRight="8dp"
    android:layout_marginTop="8dp"
    android:layout_gravity="right"
    android:gravity="right">

    <!--The message text-->
    <TextView
        android:id="@+id/message_content"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textStyle="bold"/>
    <!--the timestamp-->
    <TextView
        android:id="@+id/time_stamp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/message_content"
        android:textStyle="bold"/>

</RelativeLayout>
Run Code Online (Sandbox Code Playgroud)

问题:正如您在图像中看到的,右侧显示的消息(带有文本“rtdfg”)没有这样做。我不明白,为什么即使在相对布局上将 layout_gravity 设置为正确之后它也不会这样做。

任何人都可以阐明为什么会发生这种情况以及如何将其与右侧对齐?

编辑 1:我正在提供我正在做的工作供您参考的活动。

public class ChatActivity extends AppCompatActivity {

    private ChatMessagesAdapter chatMessagesAdapter;
    private RecyclerView recyclerView;
    private LinearLayoutManager linearLayoutManager;

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

        //Get the root view that is the recycler view
        ViewGroup viewGroup = (ViewGroup) ((ViewGroup) this
                .findViewById(android.R.id.content)).getChildAt(0);

        recyclerView = (RecyclerView) viewGroup.findViewById(R.id.chart_activity_recycler_view);

        //Set up the layout manager for the RecyclerView
        linearLayoutManager = new LinearLayoutManager(this);
        recyclerView.setLayoutManager(linearLayoutManager);

        //Attach the adapter to the RecyclerView
        chatMessagesAdapter = new ChatMessagesAdapter();
        recyclerView.setAdapter(chatMessagesAdapter);

        //Retrieve the added text
        final EditText typedText = (EditText)viewGroup.findViewById(R.id.typed_message);
        //Setup the listener on the send button.
        Button sendButton = (Button)viewGroup.findViewById(R.id.send_button);
        sendButton.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View v){
                //On clicking the send button, update the adapter source and as the adapter source gets updated,
                //trigger notification of the adapter with the updated data source.
                //Secondly, ensure that the type of message that gets displayed varies for Sender versus Receiver
                //as in Left vs Right

                //If the "typed" message is empty then no point in sending it.
                String typedMessageText = typedText.getText().toString();
                if(typedMessageText.isEmpty()){
                    return;
                }
                //Construct the message typed by the Sender
                Message messageFromSender = new Message();

                //Set the message text from the typed message EditText
                messageFromSender.setMessageText(typedText.getText().toString());
                messageFromSender.setUserStatus(Message.SENDER);
                //For the timestamp, retrieve the time-stamp from the system
                messageFromSender.setTimeStamp(System.currentTimeMillis()/1000L);
                chatMessagesAdapter.getChatMessagesSource().add(messageFromSender);

                //Now, notify the adapter of the change in source
                chatMessagesAdapter.notifyDataSetChanged();
            }
        });
    }

    private class ChatMessagesAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>{

        //Initialize the source from the JSON file having messages
        private List<Message> messageList = getListOfSenderMessagesFromJSONSource();

        @Override
        public int getItemViewType(int position){
            int viewType = messageList.get(position).getUserStatus();
            if(viewType == Message.RECEIVER){
                return Message.RECEIVER;
            }
            else if(viewType == Message.SENDER){
                return Message.SENDER;
            }
            else if(viewType == Message.DATE_DIVIDER){
                return Message.DATE_DIVIDER;
            }
            return -1;
        }
        @Override
        public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType){
            //Add the code for constructing a ViewHolder
            LayoutInflater inflater = LayoutInflater.from(ChatActivity.this);
            RelativeLayout viewGroup1;
            RecyclerView.ViewHolder viewHolder = null;
            switch(viewType){
                case Message.RECEIVER:
                    viewGroup1 = (RelativeLayout) inflater.inflate(R.layout.layout_chat_message_receiver, viewGroup, false);
                    viewHolder = new ChatMessageViewHolder(viewGroup1);
                    break;
                case Message.SENDER:
                    viewGroup1 = (RelativeLayout) inflater.inflate(R.layout.layout_chat_message_sender, viewGroup, false);
                    viewHolder = new ChatMessageViewHolder(viewGroup1);
                    break;
                default:   //I know its not a good idea to return a receiver message template as default but for now it suffices
                    viewGroup1 = (RelativeLayout) inflater.inflate(R.layout.layout_chat_message_receiver, viewGroup, false);
                    viewHolder = new ChatMessageViewHolder(viewGroup1);
                    break;
            }
            return viewHolder;
        }
        @Override
        public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int position){
            switch(viewHolder.getItemViewType()){
                case Message.RECEIVER:
                    ((ChatMessageViewHolder)viewHolder).bindMessage(messageList.get(position));
                    break;
                case Message.SENDER:
                    ((ChatMessageViewHolder)viewHolder).bindMessage(messageList.get(position));
                    break;
            }
        }
        @Override
        public int getItemCount(){
            return messageList.size();
        }

        private List<Message> getListOfSenderMessagesFromJSONSource(){
            List<Message> messageList = new ArrayList<>();

            //Parse the given JSONFile to get the individual messages
            //Name of the file: sampleChats.json

            Message chatMessage = null;
            try {
                JSONArray rootJSONArray =  new JSONArray(Message.chatMessagesJSONString);
                JSONArray level1JSONArray = (JSONArray)rootJSONArray.get(0);
                JSONObject jsonObjectInsideLevel1Array = level1JSONArray.getJSONObject(0);

                JSONObject messageObject = jsonObjectInsideLevel1Array.getJSONObject("message").getJSONObject("pn_gcm").getJSONObject("data");
            /*Retrieved message object has the following structure
            "data": {
          "name": "Dr. Renu Gupta",
          "userType": "doctor",
          "timestamp": 1480535381,
          "senderId": "1578",
          "text": "Hi Fgdfgdgf!",
          "type": "chat",
          "cardType": "text",
          "notificationType": "QChat"
            }
            * */
                //Populate the fields with the fields from JSON data
                String senderName = messageObject.getString("name");
                String userType = messageObject.getString("userType");
                long timeStamp = messageObject.getInt("timestamp");
                long senderId = messageObject.getInt("senderId");
                String messageText = messageObject.getString("text");
                String messageType = messageObject.getString("type");
                String cardType = messageObject.getString("cardType");
                String notificationType = messageObject.getString("notificationType");

                //Populate the message list with the retrieved JSON object
                chatMessage = new Message();
                chatMessage.setSenderName(senderName);
                chatMessage.setUserType(userType);
                chatMessage.setSenderID(senderId);
                chatMessage.setTimeStamp(timeStamp);
                chatMessage.setMessageText(messageText);
                chatMessage.setMessageType(messageType);
                chatMessage.setCardType(cardType);
                chatMessage.setNotificationType(notificationType);

                //Don't forget to set the sender status
                chatMessage.setUserStatus(Message.RECEIVER);

            } catch (JSONException e) {
                e.printStackTrace();
            }
            messageList.add(chatMessage);
            return messageList;
        }

        public List<Message> getChatMessagesSource(){
            return messageList;
        }

    }

    private class ChatMessageViewHolder extends RecyclerView.ViewHolder{

        //Root view
        private View messageView;
        //Child views
        private TextView chatMessageContent;
        private TextView timeStamp;

        private Message toBeBindedChatMessage;

        Drawable placeHolder;

        public ChatMessageViewHolder(View displayMessageView){
            super(displayMessageView);
            messageView = displayMessageView;
            chatMessageContent = (TextView)messageView.findViewById(R.id.message_content);
            timeStamp = (TextView)messageView.findViewById(R.id.time_stamp);
            placeHolder = getResources().getDrawable(R.drawable.dante_dmc_623_350);
        }
        public void bindMessage(Message toBeBindedChatMessage){
            this.toBeBindedChatMessage = toBeBindedChatMessage;

            //Bind the view with messsage object
            //Bind the message content
            chatMessageContent.setText(toBeBindedChatMessage.getMessageText());
            //Bind the Time Stamp
            timeStamp.setText(Message.timeStampToHH_MMFormat(toBeBindedChatMessage.getTimeStamp()*1000));


        }
    }
}
Run Code Online (Sandbox Code Playgroud)

SLe*_*ner 5

要快速修复,请执行此操作。

RelativeLayout的宽度应该match_parent使其占据其容器的整个宽度。

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginBottom="8dp"
    android:background="@drawable/message_view_border"
    android:layout_marginRight="8dp"
    android:layout_marginTop="8dp">

    <!--The message text-->
    <TextView
        android:id="@+id/message_content"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentEnd="true"
        android:layout_alignParentRight="true"
        android:textStyle="bold"/>
    <!--the timestamp-->
    <TextView
        android:id="@+id/time_stamp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/message_content"
        android:layout_alignParentEnd="true"
        android:layout_alignParentRight="true"
        android:layout_marginRight="5dp"
        android:layout_marginTop="5dp"
        android:textStyle="bold"/>

</RelativeLayout>
Run Code Online (Sandbox Code Playgroud)