Reputation: 2832
At the moment i'm working on a messaging page for my application. The problem is that i use two different xml's within a list view. Now i can get the data to display on the page in the correct order, however, when i scroll the data still appears in the correct order but in a different style. For example before scrolling the last message would use the messagesent.xml if i scroll up then scroll down that same message now has the message.xml style. The code i'm currently using is below.
public class MessagingAdapter extends ArrayAdapter<MessagingObject> {
private static final String userID = "USERID";
private static final int TYPE_ITEM1 = 0;
private static final int TYPE_ITEM2 = 1;
public String newid;
public Context context;
public ArrayList<MessagingObject> object = new ArrayList<MessagingObject>();
int type;
public MessagingAdapter(Context context, int textViewResourceId, ArrayList<MessagingObject> objects) {
super(context, textViewResourceId, objects);
this.context = context;
this.object = objects;
}
@Override
public int getItemViewType(int position) {
if (userID.equals(newid)) {
type = TYPE_ITEM1;
} else {
type = TYPE_ITEM2;
}
return type;
}
@Override
public int getViewTypeCount() {
return 2;
}
@Override
public View getView(int position, View convertview, ViewGroup parent) {
MessagingObject i = object.get(position);
newid = i.getMessageID();
LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertview = inflater.inflate(R.layout.messagesright_layout, null);
if (convertview == null) {
convertview = inflater.inflate(R.layout.messagesright_layout, null);
}
if (type == TYPE_ITEM1) {
convertview = inflater.inflate(R.layout.messagesright_layout, null);
TextView sentmessage = (TextView) convertview.findViewById(R.id.messagesent_text);
sentmessage.setText(object.get(position).getMessage());
TextView senttime = (TextView) convertview.findViewById(R.id.messagesentTime);
String senttimestring = new String().valueOf(object.get(position).getTimeStamp());
senttime.setText(senttimestring);
} else {
convertview = inflater.inflate(R.layout.messages_layout, null);
TextView message = (TextView) convertview.findViewById(R.id.message_text);
message.setText(object.get(position).getMessage());
TextView time = (TextView) convertview.findViewById(R.id.messageTime);
String timestring = new String().valueOf(object.get(position).getTimeStamp());
time.setText(timestring);
}
return convertview;
}
Now i understand this is to do with Listview Recycling, however, i've tried some solutions i've found on other stack overflow posts with no luck, and i haven't been able to find many that cover this problem with 2 xmls.
Thanks for having a look!
Upvotes: 2
Views: 127
Reputation: 157457
your getView
is wrong. You should ask the type at the position and inflate the view only if the convertView
is null.
@Override
public View getView(int position, View convertview, ViewGroup parent) {
MessagingObject i = object.get(position);
newid = i.getMessageID();
int type = getItemViewType(position);
if (convertview == null) {
LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (type == TYPE_ITEM1) {
convertview = inflater.inflate(R.layout.messagesright_layout, null);
} else if (type == TYPE_ITEM2) {
convertview = inflater.inflate(R.layout.messages_layout, null);
}
}
if (type == TYPE_ITEM1) {
TextView sentmessage = (TextView) convertview.findViewById(R.id.messagesent_text);
sentmessage.setText(object.get(position).getMessage());
TextView senttime = (TextView) convertview.findViewById(R.id.messagesentTime);
String senttimestring = new String().valueOf(object.get(position).getTimeStamp());
senttime.setText(senttimestring);
} else {
TextView message = (TextView) convertview.findViewById(R.id.message_text);
message.setText(object.get(position).getMessage());
TextView time = (TextView) convertview.findViewById(R.id.messageTime);
String timestring = new String().valueOf(object.get(position).getTimeStamp());
time.setText(timestring);
}
return convertview;
}
Upvotes: 2
Reputation: 2382
I have coded a list which has 2 xml's for the layouts of the different rows in a list and I have not seen this issue.
I don't store the view type in a local variable, instead I always call "getItemViewType" at the beginning of "getView" so I am guaranteed to get the correct view type for the current position, see my tweaks to your code below (I have not checked this compiles)
public class MessagingAdapter extends ArrayAdapter<MessagingObject> {
private static final String userID = "USERID";
private static final int TYPE_ITEM1 = 0;
private static final int TYPE_ITEM2 = 1;
public String newid;
public Context context;
public ArrayList<MessagingObject> object = new ArrayList<MessagingObject>();
int type;
public MessagingAdapter(Context context, int textViewResourceId, ArrayList<MessagingObject> objects) {
super(context, textViewResourceId, objects);
this.context = context;
this.object = objects;
}
@Override
public int getItemViewType(int position) {
if (userID.equals(newid)) {
return = TYPE_ITEM1;
} else {
return = TYPE_ITEM2;
}
}
@Override
public int getViewTypeCount() {
return 2;
}
@Override
public View getView(int position, View convertview, ViewGroup parent) {
MessagingObject i = object.get(position);
newid = i.getMessageID();
LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (getItemViewType(position) == TYPE_ITEM1) {
convertview = inflater.inflate(R.layout.messagesright_layout, null);
TextView sentmessage = (TextView) convertview.findViewById(R.id.messagesent_text);
sentmessage.setText(object.get(position).getMessage());
TextView senttime = (TextView) convertview.findViewById(R.id.messagesentTime);
String senttimestring = new String().valueOf(object.get(position).getTimeStamp());
senttime.setText(senttimestring);
} else {
convertview = inflater.inflate(R.layout.messages_layout, null);
TextView message = (TextView) convertview.findViewById(R.id.message_text);
message.setText(object.get(position).getMessage());
TextView time = (TextView) convertview.findViewById(R.id.messageTime);
String timestring = new String().valueOf(object.get(position).getTimeStamp());
time.setText(timestring);
}
return convertview;
Upvotes: 2
Reputation: 685
try this:
if (convertview == null) {
if (type == TYPE_ITEM1) {
convertview = inflater.inflate(R.layout.messagesright_layout, null);
TextView sentmessage = (TextView) convertview.findViewById(R.id.messagesent_text);
sentmessage.setText(object.get(position).getMessage());
TextView senttime = (TextView) convertview.findViewById(R.id.messagesentTime);
String senttimestring = new String().valueOf(object.get(position).getTimeStamp());
senttime.setText(senttimestring);
} else {
convertview = inflater.inflate(R.layout.messages_layout, null);
TextView message = (TextView) convertview.findViewById(R.id.message_text);
message.setText(object.get(position).getMessage());
TextView time = (TextView) convertview.findViewById(R.id.messageTime);
String timestring = new String().valueOf(object.get(position).getTimeStamp());
time.setText(timestring);
}
Upvotes: 0