【问题标题】:Align views left and right programmatically in android recycler view在android回收器视图中以编程方式左右对齐视图
【发布时间】:2019-06-25 21:47:04
【问题描述】:

我正在使用 android recycler view 创建聊天布局

activity_main

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="ch.uffapp.recyclerview.MainActivity">

<android.support.v7.widget.RecyclerView
    android:id="@+id/recycler_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_marginBottom="100dp" />

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    android:layout_alignParentBottom="true"
    android:layout_marginBottom="50dp">

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="opponent text message"
        android:id="@+id/opponent_send_text_message"/>

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="opponent image message"
        android:id="@+id/opponent_send_image_message"/>

</LinearLayout>

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    android:layout_alignParentBottom="true">

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="own text message"
        android:id="@+id/own_send_text_message"/>

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="own image message"
        android:id="@+id/own_send_image_message" />

</LinearLayout>

</RelativeLayout>

recycler_view_item

<RelativeLayout android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:android="http://schemas.android.com/apk/res/android">

<LinearLayout android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:id="@+id/private_dialog_item_view">

    <RelativeLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="5dp">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textColor="@android:color/white"
            android:id="@+id/private_dialog_message_view"/>

        <ImageView
            android:layout_width="200dp"
            android:layout_height="200dp"
            android:scaleType="centerCrop"
            android:id="@+id/private_dialog_image_view"/>

    </RelativeLayout>

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:layout_gravity="right">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textColor="@android:color/white"
            android:id="@+id/private_dialog_time_view"
            android:text="09:00 pm"
            android:layout_marginRight="10dp"
            android:textSize="10dp"
            android:layout_marginBottom="5dp"/>

        <ImageView
            android:layout_width="10dp"
            android:layout_height="10dp"
            android:src="@drawable/ic_message_read_icon"
            android:layout_marginRight="5dp"/>

    </LinearLayout>

</LinearLayout>

</RelativeLayout>

我的适配器

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> 
{

private Context context;
private List<UffMessage> uffMessages = new ArrayList<>();

public MyAdapter(Context context, List<UffMessage> uffMessages) {
    this.context = context;
    this.uffMessages = uffMessages;
}

public class MyViewHolder extends RecyclerView.ViewHolder {

    private TextView messageView;
    private TextView timeView;
    private ImageView imageView;
    private LinearLayout itemBOdy;

    public MyViewHolder(View itemView) {
        super(itemView);
        messageView = (TextView) 
itemView.findViewById(R.id.private_dialog_message_view);
        timeView = (TextView) 
itemView.findViewById(R.id.private_dialog_time_view);
        imageView = (ImageView) 
itemView.findViewById(R.id.private_dialog_image_view);
        itemBOdy = (LinearLayout) 
itemView.findViewById(R.id.private_dialog_item_view);
    }

}

@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View itemView = LayoutInflater.from(parent.getContext())
            .inflate(R.layout.recycler_view_item, parent, false);
    return new MyViewHolder(itemView);
}

@Override
public void onBindViewHolder(MyViewHolder holder, int position) {
    resetUI(holder);
    UffMessage uffMessage = uffMessages.get(position);

    if (uffMessage.isOwnMessage) {
        makeOwn(holder);
    } else {
        makeOpponent(holder);
    }



    switch (uffMessage.messageType) {
        case "text":
            holder.messageView.setVisibility(View.VISIBLE);
            holder.messageView.setText(uffMessage.textMessage);
            holder.timeView.setText(uffMessage.messageTime);
            break;
        case "image":
            holder.imageView.setVisibility(View.VISIBLE);
            holder.imageView.setImageResource(R.drawable.edge6);
            holder.timeView.setText(uffMessage.messageTime);
            break;
    }
}

@Override
public int getItemCount() {
    return uffMessages.size();
}

private void resetUI(MyViewHolder holder) {
    holder.messageView.setVisibility(View.GONE);
    holder.imageView.setVisibility(View.GONE);
}

private void makeOpponent(MyViewHolder holder) {
    RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) 
holder.itemBOdy.getLayoutParams();
    params.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
    holder.itemBOdy.setLayoutParams(params);

holder.itemBOdy.setBackgroundColor(context.getResources()
.getColor(R.color.colorPrimary));
}

private void makeOwn(MyViewHolder holder) {
    RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) 
holder.itemBOdy.getLayoutParams();
    params.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
    holder.itemView.setLayoutParams(params);

holder.itemBOdy.setBackgroundColor(context.getResources()
.getColor(R.color.colorAccent));
}

}

主活动

public class MainActivity extends AppCompatActivity implements 
View.OnClickListener {

private Button ownTextMessageBtn;
private Button ownImageMessageBtn;
private Button opponentTextMessageBtn;
private Button opponentImageMessageBtn;
private RecyclerView recyclerView;
private LinearLayoutManager layoutManager;
private List<UffMessage> uffMessages = new ArrayList<>();
private MyAdapter myAdapter;

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

    ownTextMessageBtn = (Button) findViewById(R.id.own_send_text_message);
    ownImageMessageBtn = (Button) findViewById(R.id.own_send_image_message);
    opponentTextMessageBtn = (Button) 
findViewById(R.id.opponent_send_text_message);
    opponentImageMessageBtn = (Button) 
findViewById(R.id.opponent_send_image_message);
    layoutManager = new LinearLayoutManager(this);
    layoutManager.setStackFromEnd(true);
    recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
    recyclerView.setLayoutManager(layoutManager);
    ownTextMessageBtn.setOnClickListener(this);
    ownImageMessageBtn.setOnClickListener(this);
    opponentTextMessageBtn.setOnClickListener(this);
    opponentImageMessageBtn.setOnClickListener(this);

    myAdapter = new MyAdapter(getApplicationContext(), uffMessages);
    recyclerView.setAdapter(myAdapter);

}

@Override
public void onClick(View v) {
    switch (v.getId()) {
        case R.id.own_send_text_message:
            uffMessages.add(new UffMessage("hi how are you", "12:00 pm", 
R.drawable.edge6, "text", true));
            myAdapter.notifyDataSetChanged();
            break;

        case R.id.own_send_image_message:
            uffMessages.add(new UffMessage("hi how are you", "12:00 pm", 
R.drawable.edge6, "image", true));
            myAdapter.notifyDataSetChanged();
            break;

        case R.id.opponent_send_text_message:
            uffMessages.add(new UffMessage("hi how are you", "12:00 pm", 
R.drawable.edge6, "text", false));
            myAdapter.notifyDataSetChanged();
            break;

        case R.id.opponent_send_image_message:
            uffMessages.add(new UffMessage("hi how are you", "12:00 pm", 
R.drawable.edge6, "image", false));
            myAdapter.notifyDataSetChanged();
            break;
    }
}
}

但问题是某些视图会自动扩展,我想将它们左右对齐而不扩展它们。

【问题讨论】:

    标签: android android-recyclerview


    【解决方案1】:

    视图会被回收,因此在您滚动一段时间后会看到规则

    params.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
    params.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
    

    堆叠在一个视图上导致拉伸视图。

    为什么不用简单易懂的FrameLayout 替换低效的RelativeLayout 而使用重力呢?

    final FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) holder.itemBOdy.getLayoutParams();
    params.gravity = GravityCompat.START; // or GravityCompat.END
    holder.itemBOdy.setLayoutParams(params);
    

    【讨论】:

    • replace the inefficient RelativeLayout with a simple-to-understand FrameLayout您尚未更改项目布局。
    【解决方案2】:

    最好的方法是有单元格布局,以便您可以在单元格内左右对齐项目:

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:id="@+id/layout_msg_container"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">
    
        <TextView
            android:id="@+id/tv_message"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
    
    </LinearLayout>
    

    在视图持有者中,您可以通过父布局的android:gravity 属性(在本例中为layout_msg_container)更改内容的左/右对齐方式。

    LinearLayout layoutContainer = itemView.findViewById(R.id.layout_msg_container);
    layoutContainer.setGravity(Gravity.END);
    

    layoutContainer.setGravity(Gravity.START);
    

    【讨论】:

      猜你喜欢
      • 2016-07-17
      • 2017-01-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多