如何动态修改回收站视图的布局?
how to dynamically modify the recycler view's layout?
我使用 Firebase 编写了一个聊天应用程序。
在ChatActivity 中,有一个recycler 视图来显示聊天信息。下图是第一次加载是正确的
输入发送给他人的消息时,部分消息的布局会发生变化。
MessageAdapter 中的代码
public MessageAdapter(List<YeMessage> mMessageList){
this.mMsgList = mMessageList;
}
@Override
public MessageViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.item_message, parent, false);
mContext = parent.getContext();
ref = FirebaseDatabase.getInstance().getReference();
return new MessageViewHolder(view);
}
public class MessageViewHolder extends RecyclerView.ViewHolder{
@BindView(R.id.msg_message)
TextView messageText;
@BindView(R.id.msg_imageView)
ImageView image;
public MessageViewHolder(View view){
super(view);
ButterKnife.bind(this, view);
}
}
@Override
public void onBindViewHolder(MessageViewHolder holder, int position) {
mAuth = FirebaseAuth.getInstance();
current_user_id = mAuth.getCurrentUser().getUid();
YeMessage c = mMsgList.get(position);
String from_user = c.getFrom();
ref.child("Users").child(from_user).addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
RelativeLayout.LayoutParams rp_msg = (RelativeLayout.LayoutParams)holder.messageText.getLayoutParams();
RelativeLayout.LayoutParams rp_img = (RelativeLayout.LayoutParams)holder.image.getLayoutParams();
image = dataSnapshot.child("imageUrl").getValue().toString();
if(from_user.equals(current_user_id)){
//lp.gravity = Gravity.END;
//end
rp_img.addRule(RelativeLayout.ALIGN_PARENT_END);
//rp_img.addRule(RelativeLayout.ALIGN_PARENT_TOP);
holder.image.setLayoutParams(rp_img);
//rp_msg.addRule(RelativeLayout.ALIGN_BOTTOM, R.id.msg_imageView);
rp_msg.addRule(RelativeLayout.START_OF, R.id.msg_imageView);
holder.messageText.setLayoutParams(rp_msg);
Glide.with(mContext)
.load(image)
.into(holder.image);
}else {
//lp.gravity = Gravity.START;
rp_img.addRule(RelativeLayout.ALIGN_PARENT_START);
rp_img.addRule(RelativeLayout.ALIGN_PARENT_TOP);
holder.image.setLayoutParams(rp_img);
rp_msg.addRule(RelativeLayout.ALIGN_PARENT_TOP);
rp_msg.addRule(RelativeLayout.END_OF, R.id.msg_imageView);
holder.messageText.setLayoutParams(rp_msg);
Glide.with(mContext)
.load(image)
.into(holder.image);
}
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
YeMessage msg = mMsgList.get(position);
holder.messageText.setText(msg.getMessage());
}
@Override
public int getItemCount() {
return mMsgList.size();
}
我觉得是我对recycler view的生命周期了解太少了。
而且我发现如果要在onBindViewHolder()中改变gravity,并不是每次都能成功。因为它会在调用 onCreateViewHolder() 时正确布局。
如何确保每次都调用 onCreateViewHolder(),从而以编程方式完成创建布局?
添加item_message.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
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/message_single_item"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation = "horizontal"
android:padding="15dp">
<android.support.v7.widget.AppCompatImageView
android:id="@+id/msg_imageView"
android:layout_width="45sp"
android:layout_height="45sp" />
<TextView
android:id="@+id/msg_message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/message_background"
android:padding="10dp"
android:textColor="#ffffff"
/>
</RelativeLayout>
我认为您可以为传入和传出消息设置两种不同的布局。以后改设计的时候对你有用。
您可以根据需要自定义 RecyclerView。详细解答可以参考http://www.codexpedia.com/android/android-recyclerview-with-multiple-different-layouts/
就你的布局而言。
对于收到的消息-
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal" android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp">
<ImageView
android:layout_width="50dp"
android:layout_height="50dp"
android:background="#000000"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="askjjnads dma dm"
android:layout_gravity="center"
android:layout_marginLeft="10dp"
android:layout_marginRight="20dp"
/>
</LinearLayout>
外发消息-
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal" android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="end"
android:padding="10dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="askjjnads dma dm"
android:layout_gravity="center"
android:layout_marginLeft="20dp"
android:layout_marginRight="10dp"
/>
<ImageView
android:layout_width="50dp"
android:layout_height="50dp"
android:background="#000000"/>
</LinearLayout>
我使用 Firebase 编写了一个聊天应用程序。
在ChatActivity 中,有一个recycler 视图来显示聊天信息。下图是第一次加载是正确的
输入发送给他人的消息时,部分消息的布局会发生变化。
MessageAdapter 中的代码
public MessageAdapter(List<YeMessage> mMessageList){
this.mMsgList = mMessageList;
}
@Override
public MessageViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.item_message, parent, false);
mContext = parent.getContext();
ref = FirebaseDatabase.getInstance().getReference();
return new MessageViewHolder(view);
}
public class MessageViewHolder extends RecyclerView.ViewHolder{
@BindView(R.id.msg_message)
TextView messageText;
@BindView(R.id.msg_imageView)
ImageView image;
public MessageViewHolder(View view){
super(view);
ButterKnife.bind(this, view);
}
}
@Override
public void onBindViewHolder(MessageViewHolder holder, int position) {
mAuth = FirebaseAuth.getInstance();
current_user_id = mAuth.getCurrentUser().getUid();
YeMessage c = mMsgList.get(position);
String from_user = c.getFrom();
ref.child("Users").child(from_user).addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
RelativeLayout.LayoutParams rp_msg = (RelativeLayout.LayoutParams)holder.messageText.getLayoutParams();
RelativeLayout.LayoutParams rp_img = (RelativeLayout.LayoutParams)holder.image.getLayoutParams();
image = dataSnapshot.child("imageUrl").getValue().toString();
if(from_user.equals(current_user_id)){
//lp.gravity = Gravity.END;
//end
rp_img.addRule(RelativeLayout.ALIGN_PARENT_END);
//rp_img.addRule(RelativeLayout.ALIGN_PARENT_TOP);
holder.image.setLayoutParams(rp_img);
//rp_msg.addRule(RelativeLayout.ALIGN_BOTTOM, R.id.msg_imageView);
rp_msg.addRule(RelativeLayout.START_OF, R.id.msg_imageView);
holder.messageText.setLayoutParams(rp_msg);
Glide.with(mContext)
.load(image)
.into(holder.image);
}else {
//lp.gravity = Gravity.START;
rp_img.addRule(RelativeLayout.ALIGN_PARENT_START);
rp_img.addRule(RelativeLayout.ALIGN_PARENT_TOP);
holder.image.setLayoutParams(rp_img);
rp_msg.addRule(RelativeLayout.ALIGN_PARENT_TOP);
rp_msg.addRule(RelativeLayout.END_OF, R.id.msg_imageView);
holder.messageText.setLayoutParams(rp_msg);
Glide.with(mContext)
.load(image)
.into(holder.image);
}
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
YeMessage msg = mMsgList.get(position);
holder.messageText.setText(msg.getMessage());
}
@Override
public int getItemCount() {
return mMsgList.size();
}
我觉得是我对recycler view的生命周期了解太少了。
而且我发现如果要在onBindViewHolder()中改变gravity,并不是每次都能成功。因为它会在调用 onCreateViewHolder() 时正确布局。
如何确保每次都调用 onCreateViewHolder(),从而以编程方式完成创建布局?
添加item_message.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
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/message_single_item"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation = "horizontal"
android:padding="15dp">
<android.support.v7.widget.AppCompatImageView
android:id="@+id/msg_imageView"
android:layout_width="45sp"
android:layout_height="45sp" />
<TextView
android:id="@+id/msg_message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/message_background"
android:padding="10dp"
android:textColor="#ffffff"
/>
</RelativeLayout>
我认为您可以为传入和传出消息设置两种不同的布局。以后改设计的时候对你有用。
您可以根据需要自定义 RecyclerView。详细解答可以参考http://www.codexpedia.com/android/android-recyclerview-with-multiple-different-layouts/
就你的布局而言。
对于收到的消息-
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal" android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp">
<ImageView
android:layout_width="50dp"
android:layout_height="50dp"
android:background="#000000"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="askjjnads dma dm"
android:layout_gravity="center"
android:layout_marginLeft="10dp"
android:layout_marginRight="20dp"
/>
</LinearLayout>
外发消息-
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal" android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="end"
android:padding="10dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="askjjnads dma dm"
android:layout_gravity="center"
android:layout_marginLeft="20dp"
android:layout_marginRight="10dp"
/>
<ImageView
android:layout_width="50dp"
android:layout_height="50dp"
android:background="#000000"/>
</LinearLayout>