我有 ListView
,其中包含包含 View
和 TextView
的项:
聊天项目.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="90dp"
android:id="@+id/chat_message_wrapper"
xmlns:pixlui="http://schemas.android.com/apk/com.neopixl.pixlui">
<View
android:id="@+id/message_indicator"
android:layout_width="10dp"
android:layout_height="90dp"/>
<com.neopixl.pixlui.components.textview.TextView
android:id="@+id/message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/midnight_blue"
android:padding="14dp"
android:layout_centerVertical="true"/>
</RelativeLayout>
这是我的 Adapter 类中的 getView()
:
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = convertView;
if (view == null) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.chat_item, null);
}
ChatMessageItem item = getItem(position);
if(item != null) {
TextView messageTextView = (TextView) view.findViewById(R.id.message);
ViewGroup messageWrapper = (ViewGroup) view.findViewById(R.id.chat_message_wrapper);
View messageIndicatorView = view.findViewById(R.id.message_indicator);
if(messageTextView != null) {
messageTextView.setText(String.valueOf(item.getMessage()));
RelativeLayout.LayoutParams textParams = (RelativeLayout.LayoutParams)messageTextView.getLayoutParams();
RelativeLayout.LayoutParams indicatorParams = new RelativeLayout.LayoutParams(10, ViewGroup.LayoutParams.MATCH_PARENT);
RelativeLayout.LayoutParams messageWrapperParams = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 90);
if(item.getSender() == ChatMessageItem.Sender.ME) {
textParams.addRule(RelativeLayout.LEFT_OF, R.id.message_indicator);
indicatorParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
messageIndicatorView.setBackgroundColor(getContext().getResources().getColor(R.color.light_blue));
}
else if(item.getSender() == ChatMessageItem.Sender.OTHER) {
textParams.addRule(RelativeLayout.RIGHT_OF, R.id.message);
indicatorParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
messageIndicatorView.setBackgroundColor(getContext().getResources().getColor(R.color.silver));
}
messageTextView.setLayoutParams(textParams);
messageIndicatorView.setLayoutParams(indicatorParams);
messageWrapper.setLayoutParams(messageWrapperParams);
}
}
return view;
}
我添加了以下行以至少保持项目的高度不变,它过去也会改变(这可能会在以后给我带来问题,因为内容是动态的,但没关系..)
RelativeLayout.LayoutParams messageWrapperParams = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 90);
问题是当我上下滚动时,越来越多的文本消失了。 messageIndicatorView
并没有消失,只有文本消失了。如果我继续滚动,所有文本都会消失。我做错了什么,我该如何解决?谢谢。 (我知道我必须使用 ViewHolder 以获得更好的性能,但我会在解决此问题后这样做)
最佳答案
问题在于,当 ListView 回收和重用 View 时,冲突规则被添加到 @id/message
TextView 的 RelativeLayout.LayoutParams
实例中。特别是当“ME”消息的 View 被“OTHER”消息重用时,或反之亦然。
RelativeLayout.LayoutParams
保留了一个规则列表(实际上是一个按动词排列的数组,因此您不能添加,比如说,两个 LEFT_OF
规则——但任何其他组合都是可能的,包括有问题的)。
最简单的解决方案是每次都使用新的 RelativeLayout.LayoutParams
对象,方法是更改以下行:
RelativeLayout.LayoutParams textParams =
(RelativeLayout.LayoutParams)messageTextView.getLayoutParams();
进入:
RelativeLayout.LayoutParams textParams =
new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
还有其他解决方案,例如为每种 ListView 项目设置不同的实际布局(通过 getItemViewType()
),但在这种情况下可能有点矫枉过正。但是,如果两种观点之间的差异更大,则可能值得考虑。
关于android - 为什么滚动时ListView item中的文字消失了?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27464544/