Android recyclerView 项目布局参数不起作用

Posted

技术标签:

【中文标题】Android recyclerView 项目布局参数不起作用【英文标题】:Android recyclerView item layout params not working 【发布时间】:2016-12-06 09:49:52 【问题描述】:

我正在编写一个简单的聊天 UI。我正在使用一个九补丁文件来完成这项工作。

当我第一次用一些模拟数据初始化我的适配器时,它工作正常,但如果我在运行时添加一些东西,recyclerView 内的布局会中断。

虽然我用来设置对齐的布局参数似乎不起作用,但它不会引发任何错误。实际上,对齐有效,但它的大小变为 match_parent 而不是 wrap_content。

这是我的适配器代码。

public class Adapter_Chat extends RecyclerView.Adapter<Adapter_Chat.Adapter_Chat_ViewHolder> 

private List<ChatMessageModel> data = Collections.EMPTY_LIST;

public Adapter_Chat(List<ChatMessageModel> data) 
    this.data = data;


@Override
public Adapter_Chat_ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) 
    return new Adapter_Chat_ViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_rv_chat_message, parent, false));



public void addNewMessage(ChatMessageModel model) 
    data.add(model);
    notifyDataSetChanged();


@Override
public void onBindViewHolder(Adapter_Chat_ViewHolder holder, int position) 
    ChatMessageModel item = data.get(position);

    switch (item.getType()) 
        case mine: 
            holder.iv_chat_profileImage.setVisibility(View.INVISIBLE);
            holder.tv_item_chat_message_nameText.setVisibility(View.INVISIBLE);
            holder.tv_item_chat_message_contentText.setBackgroundResource(R.drawable.in_message_bg);
            RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) holder.tv_item_chat_message_contentText.getLayoutParams();
            params.addRule(RelativeLayout.ALIGN_PARENT_RIGHT, RelativeLayout.TRUE);
            params.height = RelativeLayout.LayoutParams.WRAP_CONTENT;
            params.width = RelativeLayout.LayoutParams.WRAP_CONTENT;
            holder.tv_item_chat_message_contentText.setLayoutParams(params);

        
        break;

        case others: 
            holder.iv_chat_profileImage.setVisibility(View.VISIBLE);
            holder.tv_item_chat_message_nameText.setVisibility(View.VISIBLE);
            holder.tv_item_chat_message_contentText.setBackgroundResource(R.drawable.out_message_bg);
            RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) holder.tv_item_chat_message_contentText.getLayoutParams();
            params.addRule(RelativeLayout.ALIGN_PARENT_LEFT, RelativeLayout.TRUE);
            params.height = RelativeLayout.LayoutParams.WRAP_CONTENT;
            params.width = RelativeLayout.LayoutParams.WRAP_CONTENT;
            holder.tv_item_chat_message_contentText.setLayoutParams(params);

        
        break;
    


    holder.tv_item_chat_message_contentText.setText(item.getMessage().trim());
    holder.tv_item_chat_message_nameText.setText(item.getSender().trim());


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


public class Adapter_Chat_ViewHolder extends RecyclerView.ViewHolder 

    public TextView tv_item_chat_message_nameText, tv_item_chat_message_contentText;
    public ImageView iv_chat_profileImage;

    public Adapter_Chat_ViewHolder(View itemView) 
        super(itemView);
        tv_item_chat_message_contentText = (TextView) itemView.findViewById(R.id.tv_item_chat_message_contentText);
        tv_item_chat_message_nameText = (TextView) itemView.findViewById(R.id.tv_item_chat_message_nameText);
        iv_chat_profileImage = (ImageView) itemView.findViewById(R.id.iv_chat_profileImage);
    


布局是,

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_
android:layout_>

<ImageView
    android:src="@drawable/bg"
    android:scaleType="fitXY"
    android:layout_margin="16dp"
    android:layout_
    android:layout_
    android:id="@+id/iv_chat_profileImage" />

<TextView
    android:id="@+id/tv_item_chat_message_nameText"
    android:text="name"
    android:layout_
    android:layout_
    android:layout_marginLeft="64dp"
    android:layout_marginTop="16dp" />

<TextView
    android:layout_marginTop="32dp"
    android:layout_marginLeft="64dp"
    android:layout_marginRight="16dp"
    android:gravity="right"
    android:background="@drawable/out_message_bg"
    android:id="@+id/tv_item_chat_message_contentText"
    android:text="content"
    android:layout_
    android:layout_/>

我的 onBindViewHolder 方法有问题吗?更改项目的对齐方式不应该是这样的吗?

【问题讨论】:

【参考方案1】:

addRule() 方法将保留现有规则添加到视图。因此,在不删除现有规则的情况下动态添加规则不会产生预期的效果。

如下所示更新开关盒。

switch (item.getType()) 
    case mine: 
        ---------- exisiting code ----------
        RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) holder.tv_item_chat_message_contentText.getLayoutParams();
        params.addRule(RelativeLayout.ALIGN_PARENT_RIGHT, RelativeLayout.TRUE);
        params.addRule(RelativeLayout.ALIGN_PARENT_LEFT, 0);
        params.height = RelativeLayout.LayoutParams.WRAP_CONTENT;
        params.width = RelativeLayout.LayoutParams.WRAP_CONTENT;
        holder.tv_item_chat_message_contentText.setLayoutParams(params);

    
    break;

    case others: 
        ---------- exisiting code ----------          
        RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) holder.tv_item_chat_message_contentText.getLayoutParams();
        params.addRule(RelativeLayout.ALIGN_PARENT_LEFT, RelativeLayout.TRUE);
        params.addRule(RelativeLayout.ALIGN_PARENT_RIGHT, 0);
        params.height = RelativeLayout.LayoutParams.WRAP_CONTENT;
        params.width = RelativeLayout.LayoutParams.WRAP_CONTENT;
        holder.tv_item_chat_message_contentText.setLayoutParams(params);

    
    break;

对于 API 级别 >= 17,可以使用一种新方法来删除任何现有规则,而不是将其值设置为 0。我们可以使用

 params.addRule(RelativeLayout.ALIGN_PARENT_RIGHT, 0);

变成

 params.removeRule(RelativeLayout.ALIGN_PARENT_RIGHT);

【讨论】:

太棒了。我忘了删除现有的规则。谢谢你的回答。【参考方案2】:

Android 布局,如 ListView 、Recycler View 或 gridView Android 重用 UI 对象。

在使用这种布局时,应始终记住处理 if else 条件,也就是说,如果您使用视图在一种代码中可见,则应提供 else 以使该视图不可见,因此当 listview 或recylerview 重用视图,它将始终根据条件显示正确的视图。

在这个问题中,您还为我的项目添加了 ALIGN_PARENT_RIGHT 和其他项目的 ALIGN_PARENT_LEFT 规则,但您忘记添加规则,以便我的项目不显示在 LEFT 上,其他项目不显示在 RIGHT 上。

所以您可以使用 addRule(ALIGN_PARENT_LEFT,0) 或 removeRule(ALIGN_PARENT_LEFT) (API >= JELLY_BEAN_MR1,i.e17) 用于我的和 addRule(ALIGN_PARENT_RIGHT,0) 或 removeRule(ALIGN_PARENT_RIGHT) (API >= JELLY_BEAN_MR1,i .e17) 为我的。

【讨论】:

以上是关于Android recyclerView 项目布局参数不起作用的主要内容,如果未能解决你的问题,请参考以下文章

Android13.0 UI开发——列表控件RecyclerView的横向布局排列实现

如何在 recyclerview 适配器中将动态视图添加到 android 布局

在recyclerview android中以编程方式更改布局管理器

水平 RecyclerView 不环绕布局

如图,Android 编程,右侧三个recyclerview布局,为啥是靠顶部,不是居中的?布局

Android RecyclerView GridLayoutManager 中心项目并保持相同的宽度