我希望有一个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的回收。
接下来我尝试为每个项目使用不同的行类,但也许你们中的任何一个都知道如何让它工作?
答案 0 :(得分:0)
您必须覆盖BaseAdapter
中的getViewTypeCount()
和getItemViewType()
,以指定您有两种不同类型的观看次数。
Here就是一个例子。
答案 1 :(得分:0)
对于您的不同类型,我选择更改与LayoutParams无关的属性,例如使用setPadding
或左侧的视图,其可见性在gone
/ invisible
之间切换或gone
/ visible
。我喜欢setPadding
方法,在我看来它将是最快最干净的方法。
我敢打赌这个混乱与改变每个getView()
的布局参数有关:它应该有效,但你需要每次都在requestLayout
内调用getView
,这会对性能产生负面影响。我不是这方面的专家,但是当您为每个视图一次又一次地强制convertView
和measure
阶段时,甚至可能会失去使用layout
获胜的时间(在快速投掷的情况下连续发生数十次的事情)
来自http://developer.android.com/training/custom-views/optimizing-view.html:
另一个非常昂贵的操作是遍历布局。每当视图调用requestLayout()
时,Android UI系统都需要遍历整个视图层次结构,以找出每个视图需要的大小。如果发现有冲突的测量,则可能需要多次遍历层次结构。 UI设计者有时会创建嵌套ViewGroup对象的深层次结构,以使UI正常运行。这些深层视图层次结构会导致性能问题。使您的视图层次结构尽可能浅。
除setPadding
解决方案外,如果您将来添加更多类型(即文件附加/语音/图像......),实施ViewTypeCount
等等并不是一个坏主意。 ......正如@Picpik建议的那样。这样,在convertView
中,您将获得重用与新视图相同类型的视图,并且可以安全地使用不同的布局方法。