为什么滚动时ListView项中的文本会消失?

时间:2014-12-13 22:59:58

标签: android android-listview android-arrayadapter

我的ListView包含包含ViewTextView的项目:

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以获得更好的性能,但是当我解决这个问题时我会这样做)

1 个答案:

答案 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())提供不同的实际布局,但在这种情况下它可能过度杀伤。但是,如果两种观点之间的差异较大,则可能值得考虑。