I want to have a Listview in which the rows change their layout based on a variable that is inside the object I want to display.
So I wrote a custom ArrayAdapter and overrode the getView() method like this:
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;
}
}
The xml for my views looks like this. Only the margins and colors are different:
<?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>
And the fragment layout where the list is placed:
<?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>
It works fine until I have two views with different layouts in my list. Then the list seems to switch back and forth between the layouts every few seconds.
Picture for the curious: https://i.stack.imgur.com/xrJVX.jpg
I tried to only use one layout and change the properties of it but when I scrolled too fast I had some strange display errors. Problably due to the recycling of the listview.
Next thing I'd try is using different row classes for each item but maybe any of you has an idea how to get this to work?