我的ListView
包含包含View
和TextView
的项目:
chat_item.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以获得更好的性能,但是当我解决这个问题时我会这样做)
答案 0 :(得分:1)
问题在于,当ListView回收并重用视图时,会将冲突的规则添加到RelativeLayout.LayoutParams
TextView的@id/message
实例中。特别是每当观看一个&#34; ME&#34;消息被重用于&#34; OTHER&#34;消息,反之亦然。
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()
)提供不同的实际布局,但在这种情况下它可能过度杀伤。但是,如果两种观点之间的差异较大,则可能值得考虑。