Android:Listview Arrayadapter摆动

时间:2014-04-17 16:28:58

标签: android android-layout listview android-listview android-arrayadapter

我希望有一个Listview,其中行根据我想要显示的对象内的变量更改其布局。

所以我编写了一个自定义的ArrayAdapter并覆盖了getView()方法,如下所示:

public class ChatAdapter extends ArrayAdapter<Nachricht> {

    public ChatAdapter(Context context, ArrayList<Nachricht> users) {
        super(context, R.layout.message_layout_standard, users);
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        // SimpleDateFormat to change the view of the date
        SimpleDateFormat dformat = new SimpleDateFormat("dd.MM.yyyy   HH:mm");

        // Get the data item for this position
        Nachricht nachricht = getItem(position);

        // Check if an existing view is being reused, otherwise inflate the view
        if (convertView == null) {
            if(nachricht.SENDER_ID.equals(DataService.options.ownUser.USER_ID)){
                convertView = LayoutInflater.from(getContext()).inflate(R.layout.message_layout_own, null);
            }else{
                convertView = LayoutInflater.from(getContext()).inflate(R.layout.message_layout_other, null);
            }
        }

        // Lookup view for data population
        TextView chatdate = (TextView) convertView.findViewById(R.id.date_chat);
        TextView chatsender = (TextView) convertView.findViewById(R.id.sender_chat);
        TextView chatmessage = (TextView) convertView.findViewById(R.id.message_chat);

        if(!nachricht.SENDER_ID.equals(DataService.options.ownUser.USER_ID)){

            // Set the sender of the message
            chatsender.setText("" + DataService.freunde.get(DataService.freunde.indexOf(new Freund(nachricht.SENDER_ID, ""))).name);
            // Set the Message
            chatmessage.setText(nachricht.TEXT);

            //Set the Date/Clock of the Message
            chatdate.setText(dformat.format(nachricht.DATE));

        }else{
            // Set the sender of the message
            chatsender.setText("Du");
            // Set the Message
            chatmessage.setText(nachricht.TEXT);
            chatdate.setText(dformat.format(nachricht.DATE));

        }

        // Return the completed view to render on screen
        return convertView;

    }
}

我的观点的xml看起来像这样。只有边距和颜色不同:

<?xml version="1.0" encoding="utf-8"?>

<!--
    Dies ist das Layout zu der Java-Class 'ChatAdapter'
    Es erstellt die Chat-Nachrichten in der ListView
    der einzelnen Chats.
-->


<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:layout_width="wrap_content">


        <TextView
            android:id="@+id/sender_chat"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:gravity="left"
            android:height="20sp"
            android:text="sender_chat"
            android:textColor="#000000"
            android:textSize="11sp"
            android:textStyle="bold" />

        <ImageView
            android:id="@+id/background_chat"
            android:scaleType="fitXY"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:layout_marginLeft="5dp"
            android:layout_marginTop="5dp"
            android:layout_marginRight="70dp"
            android:layout_below="@+id/sender_chat"
            android:layout_above="@+id/date_chat"
            android:src="@drawable/message_own" />

        <TextView
            android:textColor="#000000"
            android:id="@+id/message_chat"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:gravity="left"
            android:layout_marginLeft="15dp"
            android:layout_marginTop="7dp"
            android:layout_marginBottom="7dp"
            android:layout_marginRight="70dp"
            android:layout_below="@+id/sender_chat"

            android:text="message_chat"
            android:textSize="15sp" />



        <TextView
            android:textColor="#000000"
            android:layout_below="@+id/message_chat"
            android:id="@+id/date_chat"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:height="20dp"
            android:text="date_chat"
            android:textSize="11sp"/>

</RelativeLayout>

放置列表的片段布局:

    <?xml version="1.0" encoding="utf-8"?>

<RelativeLayout
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    xmlns:android="http://schemas.android.com/apk/res/android">

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Senden"
        android:id="@+id/button"
        android:layout_alignParentBottom="true"
        android:layout_alignParentRight="true"
        android:layout_alignParentEnd="true" />

    <EditText
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/nachrichtChatText"
        android:layout_alignTop="@+id/button"
        android:layout_toLeftOf="@+id/button"
        android:layout_alignParentBottom="true"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true" />

    <ListView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/talkView"
        android:layout_alignParentRight="true"
        android:layout_alignParentEnd="true"
        android:layout_above="@+id/button"
        android:layout_below="@+id/button2"
        android:cacheColorHint="@android:color/transparent"/>

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:text="Chatmitglieder"
        android:id="@+id/chatTeilnehmer"
        android:layout_alignParentTop="true"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"
        android:layout_toLeftOf="@+id/button2"
        android:layout_above="@+id/talkView" />

    <Button
        style="?android:attr/buttonStyleSmall"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text=" + "
        android:id="@+id/buttonChangeChat"
        android:layout_alignParentTop="true"
        android:layout_alignRight="@+id/button"
        android:layout_alignEnd="@+id/button" />
</RelativeLayout>

它工作正常,直到我的列表中有两个不同布局的视图。然后列表似乎每隔几秒在布局之间来回切换。

好奇的图片:http://imgur.com/5KbXKu2

我试图只使用一个布局并更改它的属性但是当我滚动得太快时我有一些奇怪的显示错误。可能是由于listview的回收。

接下来我尝试为每个项目使用不同的行类,但也许你们中的任何一个都知道如何让它工作?

2 个答案:

答案 0 :(得分:0)

您必须覆盖BaseAdapter中的getViewTypeCount()getItemViewType(),以指定您有两种不同类型的观看次数。

Here就是一个例子。

答案 1 :(得分:0)

对于您的不同类型,我选择更改与LayoutParams无关的属性,例如使用setPadding或左侧的视图,其可见性在gone / invisible之间切换或gone / visible。我喜欢setPadding方法,在我看来它将是最快最干净的方法。

我敢打赌这个混乱与改变每个getView()的布局参数有关:它应该有效,但你需要每次都在requestLayout内调用getView,这会对性能产生负面影响。我不是这方面的专家,但是当您为每个视图一次又一次地强制convertViewmeasure阶段时,甚至可能会失去使用layout获胜的时间(在快速投掷的情况下连续发生数十次的事情)

来自http://developer.android.com/training/custom-views/optimizing-view.html另一个非常昂贵的操作是遍历布局。每当视图调用requestLayout()时,Android UI系统都需要遍历整个视图层次结构,以找出每个视图需要的大小。如果发现有冲突的测量,则可能需要多次遍历层次结构。 UI设计者有时会创建嵌套ViewGroup对象的深层次结构,以使UI正常运行。这些深层视图层次结构会导致性能问题。使您的视图层次结构尽可能浅。

setPadding解决方案外,如果您将来添加更多类型(即文件附加/语音/图像......),实施ViewTypeCount等等并不是一个坏主意。 ......正如@Picpik建议的那样。这样,在convertView中,您将获得重用与新视图相同类型的视图,并且可以安全地使用不同的布局方法。