Android: how to change layout_gravity property of name string as a list

I am trying to implement chats that can appear on the left or right. I have read many answers already posted here but I have not been able to get any of them to work for me, maybe I am missing something.

If I change the layout_gravity linearLayout in the row_item xml from left to right by hand, and then look at the graphic layout, I can see that it works as I wanted. the problem is that I cannot control this property. as I understand the problem is because existing LayoutParams have listview.LayoutParams and if I try to get LayoutParams for listview.LayoutParams object it works. but this is not what I am trying to achieve.

here's the code:

xml activity

<LinearLayout 
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:ignore="MergeRootFrame" >

<ListView
    android:id="@+id/listViewMessages"
    android:layout_width="match_parent"
    android:layout_height="0dp" 
    android:layout_weight="0.98" >

</ListView>

<RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_weight="0.02"
    android:background="#D3D3D3"
    android:orientation="horizontal" >

    <EditText
        android:id="@+id/editTextMessage"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_toLeftOf="@+id/imageButtonSend"
        android:ems="10"
        android:hint="@string/textFieldMessage"
        android:textSize="14sp"
        android:visibility="visible" >

        <requestFocus />
    </EditText>

    <ImageButton
        android:id="@+id/imageButtonSend"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_centerVertical="true"
        android:layout_marginRight="14dp"
        android:background="?android:attr/selectableItemBackground"
        android:contentDescription="@string/imageButtonSendNow_contentDescription"
        android:src="@drawable/ic_action_send_now" 
        android:onClick="onClick" />

</RelativeLayout>

</LinearLayout>

      

row_item xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/singleMessageContainer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="left"
android:orientation="horizontal"
android:padding="6dp" >

    <TextView
        android:id="@+id/textViewMessage"
        android:layout_width="wrap_content"
        android:layout_height="20dp"
        android:layout_weight="0.85"
        android:layout_marginBottom="2dp"
        android:layout_marginLeft="5dp"
        android:layout_marginTop="2dp"
        android:gravity="center_vertical"
        android:text="Message"
        android:textSize="16sp"
        tools:ignore="HardcodedText" />

    <TextView
        android:id="@+id/TextViewTime"
        android:layout_width="wrap_content"
        android:layout_height="14dp"
        android:layout_weight="0.1"
        android:layout_gravity="bottom"
        android:layout_marginLeft="22dp"
        android:gravity="center_vertical"
        android:text="Time"
        android:textSize="12sp"
        tools:ignore="HardcodedText" />

    <ImageView
        android:id="@+id/imageViewSuccess"
        android:layout_width="12dp"
        android:layout_height="12dp"
        android:layout_weight="0.05"
        android:layout_gravity="bottom"
        android:contentDescription="successIcon"
        android:src="@drawable/ic_action_accept"
        tools:ignore="HardcodedText" />

  </LinearLayout>

      

adapter code:

public class ConversationAdapter extends ArrayAdapter<Message> {

private final Context context;

static class ViewHolder {
    public TextView message;
    public TextView time;
    public ImageView success;
    public LinearLayout singleMessageContainer;

}

public ConversationAdapter(Context context, ArrayList<Message> values) {
    super(context, R.layout.conversation_list_item, values);
    this.context = context;

}

  @Override
public View getView(int position, View convertView, ViewGroup parent) {
      View rowView = convertView;
        // reuse views
        if (rowView == null) {
          LayoutInflater inflater = (LayoutInflater) context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
          rowView = inflater.inflate(R.layout.conversation_list_item, parent,false);
          // configure view holder
          ViewHolder viewHolder = new ViewHolder();
          viewHolder.message = (TextView) rowView.findViewById(R.id.textViewMessage);
          viewHolder.time = (TextView) rowView.findViewById(R.id.TextViewTime);
          viewHolder.success = (ImageView) rowView.findViewById(R.id.imageViewSuccess);
          viewHolder.singleMessageContainer = (LinearLayout)     rowView.findViewById(R.id.singleMessageContainer);

          rowView.setTag(viewHolder);
        }

        // fill data
        ViewHolder holder = (ViewHolder) rowView.getTag();

        holder.message.setText(getItem(position).getMessage());
        holder.time.setText(getItem(position).getUniversalTimeString());
        holder.success.setImageResource(R.drawable.ic_action_accept);

        boolean isMine = (getItem(position).getSender() == 0);

        holder.singleMessageContainer.setBackgroundResource(
                isMine ? R.drawable.bubble_yellow : R.drawable.bubble_green);

        // This part doesn't work
        LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) 
                holder.singleMessageContainer.getLayoutParams();
        params.gravity=(isMine ? Gravity.LEFT : Gravity.RIGHT);

        holder.singleMessageContainer.setLayoutParams(params);

        return rowView; 
  }

}

      

+3


source to share


1 answer


Decision

I kept reading about gravity and layout_gravity and came across more details that helped me solve this problem. There is a solution to use the framework layout in several of the answers to the questions here, but important things to notice were not written.

The first thing to know is that you are setting the linear layout to be horizontal, you cannot use the gravity property to both left and right only from the top or bottom so the outer container must be vertical and the inner warp must be horizontal to display the message, and other data one after the other in a row.

and then you can use the setGravity (Gravity.LEFT) or setGravity (Gravity.RIGHT) method of the outer container to correctly align the inner warpper to the left or right. you need to pay attention also to the fill_parent and wrap_content properties

here's the updated code: row_item xml:



<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/singleMessageContainer"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="left"
android:orientation="vertical"
android:padding="6dp" >

<LinearLayout
     android:id="@+id/warpper"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
     android:orientation="horizontal" >

    <TextView
        android:id="@+id/textViewMessage"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:layout_marginBottom="2dp"
        android:layout_marginLeft="5dp"
        android:layout_marginRight="5dp"
        android:layout_marginTop="2dp"
        android:text="Message"
        android:textSize="14sp"
        tools:ignore="HardcodedText" />

    <TextView
        android:id="@+id/TextViewTime"
        android:layout_width="wrap_content"
        android:layout_height="14dp"
        android:layout_gravity="bottom"
        android:text="Time"
        android:textSize="12sp"
        tools:ignore="HardcodedText" />

    <ImageView
        android:id="@+id/imageViewSuccess"
        android:layout_width="wrap_content"
        android:layout_height="12dp"
        android:layout_gravity="bottom"
        android:contentDescription="successIcon"
        android:src="@drawable/ic_action_accept"
        tools:ignore="HardcodedText" />

    </LinearLayout>

</LinearLayout>

      

and the updated adpater code:

public class ConversationAdapter extends ArrayAdapter<Message> {

private final Context context;

static class ViewHolder {
    public TextView message;
    public TextView time;
    public ImageView success;
    public LinearLayout singleMessageContainer;
    // Added
    public LinearLayout warpper;

}

public ConversationAdapter(Context context, ArrayList<Message> values) {
    super(context, R.layout.conversation_list_item, values);
    this.context = context;

}

  @Override
public View getView(int position, View convertView, ViewGroup parent) {
      View rowView = convertView;
        // reuse views
        if (rowView == null) {
          LayoutInflater inflater = (LayoutInflater) context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
          rowView = inflater.inflate(R.layout.conversation_list_item, parent,false);
          // configure view holder
          ViewHolder viewHolder = new ViewHolder();
          viewHolder.message = (TextView) rowView.findViewById(R.id.textViewMessage);
          viewHolder.time = (TextView) rowView.findViewById(R.id.TextViewTime);
          viewHolder.success = (ImageView) rowView.findViewById(R.id.imageViewSuccess);
          viewHolder.singleMessageContainer = (LinearLayout) rowView.findViewById(R.id.singleMessageContainer);
          // Added
          viewHolder.warpper = (LinearLayout) rowView.findViewById(R.id.warpper);

          rowView.setTag(viewHolder);
        }

        // fill data
        ViewHolder holder = (ViewHolder) rowView.getTag();

        holder.message.setText(getItem(position).getMessage());
        holder.time.setText(getItem(position).getUniversalTimeString());
        holder.success.setImageResource(R.drawable.ic_action_accept);

        boolean isMine = (getItem(position).getSender() == 0);

        // Changed to warpper
        holder.warpper.setBackgroundResource(
                isMine ? R.drawable.bubble_yellow : R.drawable.bubble_green);
        // Added
        holder.singleMessageContainer.setGravity(isMine ? Gravity.LEFT : Gravity.RIGHT);


        return rowView; 
  }

}

      

And it should work. The only thing you might see is a warning in the xml that one of the line layouts is useless, but it won't work without it.

Hope this helps you.

+1


source







All Articles