Android recyclerView 项目布局参数不工作
Android recyclerView item layout params not working
我正在写一个简单的聊天记录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_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:src="@drawable/bg"
android:scaleType="fitXY"
android:layout_margin="16dp"
android:layout_width="48dp"
android:layout_height="48dp"
android:id="@+id/iv_chat_profileImage" />
<TextView
android:id="@+id/tv_item_chat_message_nameText"
android:text="name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
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_width="wrap_content"
android:layout_height="wrap_content"/>
我的onBindViewHolder方法有问题吗?改变项目的对齐方式不应该是这样的吗?
addRule()
方法将保留添加到视图的现有规则。因此动态添加规则而不删除现有规则不会产生预期的效果。
像下面这样更新 switch case。
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 Level >= 17,可以使用一种新方法来删除任何现有规则,而不是将它们的值设置为0。我们可以使用
params.addRule(RelativeLayout.ALIGN_PARENT_RIGHT, 0);
变成
params.removeRule(RelativeLayout.ALIGN_PARENT_RIGHT);
Android ListView、Recycler View 或 gridView 等布局 Android 重用 UI 个对象。
在使用这种布局时,应始终记住处理 if else 条件,也就是说,如果您使用视图在一种条件下可见,则应提供其他视图以使该视图不可见,因此当listview 或 recylerview 重用视图,它将始终根据条件显示正确的视图。
在这个问题中,您还添加了规则,让我的项目在 ALIGNT_PARENT_RIGHT 上,其他项目在 ALIGN_PARENT_LEFT 上,但是您忘记添加规则,不在我的左侧和右侧显示它其他.
所以你可以使用 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) 我的。
当我第一次用一些模拟数据初始化我的适配器时,它工作正常,但如果我在运行时添加一些东西,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_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:src="@drawable/bg"
android:scaleType="fitXY"
android:layout_margin="16dp"
android:layout_width="48dp"
android:layout_height="48dp"
android:id="@+id/iv_chat_profileImage" />
<TextView
android:id="@+id/tv_item_chat_message_nameText"
android:text="name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
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_width="wrap_content"
android:layout_height="wrap_content"/>
我的onBindViewHolder方法有问题吗?改变项目的对齐方式不应该是这样的吗?
addRule()
方法将保留添加到视图的现有规则。因此动态添加规则而不删除现有规则不会产生预期的效果。
像下面这样更新 switch case。
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 Level >= 17,可以使用一种新方法来删除任何现有规则,而不是将它们的值设置为0。我们可以使用
params.addRule(RelativeLayout.ALIGN_PARENT_RIGHT, 0);
变成
params.removeRule(RelativeLayout.ALIGN_PARENT_RIGHT);
Android ListView、Recycler View 或 gridView 等布局 Android 重用 UI 个对象。
在使用这种布局时,应始终记住处理 if else 条件,也就是说,如果您使用视图在一种条件下可见,则应提供其他视图以使该视图不可见,因此当listview 或 recylerview 重用视图,它将始终根据条件显示正确的视图。
在这个问题中,您还添加了规则,让我的项目在 ALIGNT_PARENT_RIGHT 上,其他项目在 ALIGN_PARENT_LEFT 上,但是您忘记添加规则,不在我的左侧和右侧显示它其他.
所以你可以使用 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) 我的。