【发布时间】:2017-07-26 23:45:29
【问题描述】:
这是我在 Stack Overflow 上的第一个问题,我一直在 Android 上构建一个简单的聊天应用程序,它从在线数据库加载聊天历史记录,并将使用自定义消息适配器显示在列表视图中。
这是程序的当前状态:
但是,数组列表下第 6 条聊天消息后,列表项的布局不正确,并且后面的所有聊天消息都在重复前 6 条消息的布局。
这是我的适配器的代码:
public class messageAdapter extends ArrayAdapter<chatMessage> {
private Activity activity;
private List<chatMessage> messages;
public messageAdapter(Activity context, int resource, List<chatMessage> objects) {
super(context, resource, objects);
this.activity = context;
this.messages = objects;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
LayoutInflater inflater = (LayoutInflater) activity.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
int layoutResource = 0; // determined by view type
chatMessage chatMessage = getItem(position);
int viewType = getItemViewType(position);
if (chatMessage.isMine()) {
layoutResource = R.layout.chat_bubble_right;
} else {
layoutResource = R.layout.chat_bubble_left;
}
if (convertView != null) {
holder = (ViewHolder) convertView.getTag();
} else {
convertView = inflater.inflate(layoutResource, parent, false);
holder = new ViewHolder(convertView);
convertView.setTag(holder);
Log.d("ViewID", "generated");
}
//set message content
holder.message.setText(chatMessage.getContent());
return convertView;
}
@Override
public int getViewTypeCount() {
// return the total number of view types. this value should never change
// at runtime
return 2;
}
@Override
public int getItemViewType(int position) {
// return a value between 0 and (getViewTypeCount - 1)
return position % 2;
}
private class ViewHolder {
private TextView message;
public ViewHolder(View v) {
message = (TextView) v.findViewById(R.id.txt_msg);
}
}
这是我将聊天消息加载到数组列表中的方法:
private class getChatHistory extends AsyncTask<DBConnection,Long,JSONArray> {
@Override
protected JSONArray doInBackground(DBConnection... params) {
return params[0].getChatHistory(userID);
}
@Override
protected void onPostExecute(JSONArray jsonArray) {
chatData = jsonArray;
if (chatData != null)
{
for (int i = 0; i < chatData.length(); i++)
{
JSONObject currentItem = null;
try
{
currentItem = chatData.getJSONObject(i);
int msgID = currentItem.getInt("MessageID");
String currentText = currentItem.getString("MessageContent");
int senderID = currentItem.getInt("SenderID");
int receiverID = currentItem.getInt("ReceiverID");
chatMessage currentMessage = new chatMessage(currentText, senderID, userID);
Log.d("Is Mine", Boolean.toString(currentMessage.isMine()));
messageHistory.add(currentMessage);
DBAdapter.notifyDataSetChanged();
} catch (JSONException e) {
e.printStackTrace();
}
}
}
}
}
这是我从我运行的 PHP 文件中获得的 JSONArray:
[{"MessageID":"1","SenderID":"1","ReceiverID":"8","Duration":"2.4","MessageContent":"agnblean liajiaj vliwv fla","MessageLength":"26","Status":"received","Date":"2016-04-04 14:00:00"},
{"MessageID":"2","SenderID":"8","ReceiverID":"1","Duration":"3.1","MessageContent":"akwuehrgeubwfcofawve","MessageLength":"20","Status":"received","Date":"2016-04-04 17:00:00"},
{"MessageID":"3","SenderID":"8","ReceiverID":"1","Duration":"3.1","MessageContent":"akwuehrgeubwfjurawve","MessageLength":"20","Status":"received","Date":"2016-04-04 17:00:05"},
{"MessageID":"4","SenderID":"8","ReceiverID":"1","Duration":"3.1","MessageContent":"akwuehrgeubwalwrawve","MessageLength":"20","Status":"received","Date":"2016-04-04 17:00:10"},
{"MessageID":"5","SenderID":"1","ReceiverID":"8","Duration":"3.1","MessageContent":"akwuehrgeubwalwrawve","MessageLength":"20","Status":"received","Date":"2016-04-04 17:01:10"},
{"MessageID":"8","SenderID":"1","ReceiverID":"8","Duration":"4.6","MessageContent":"vsjkgkgredjegwhkaga","MessageLength":"23","Status":"received","Date":"2016-04-05 05:00:00"},
{"MessageID":"9","SenderID":"8","ReceiverID":"1","Duration":"5.2","MessageContent":"agrlanwligna","MessageLength":"21","Status":"received","Date":"2016-04-06 00:00:00"},
{"MessageID":"10","SenderID":"8","ReceiverID":"1","Duration":"7.2","MessageContent":"akewgaughurawaarg","MessageLength":"12","Status":"received","Date":"2016-04-12 00:00:00"},
{"MessageID":"11","SenderID":"1","ReceiverID":"8","Duration":"7.2","MessageContent":"wgkakjrgnjange","MessageLength":"41","Status":"received","Date":"2016-04-15 00:00:00"},
{"MessageID":"12","SenderID":"1","ReceiverID":"8","Duration":"4.67","MessageContent":"yikes","MessageLength":"5","Status":"received","Date":"2016-04-21 00:00:00"},
{"MessageID":"13","SenderID":"8","ReceiverID":"1","Duration":"8.2","MessageContent":"iobanoine","MessageLength":"4","Status":"received","Date":"2016-04-30 00:00:00"}]
所以我认为这将为聊天历史记录生成正确的布局,其中活动用户是用户 ID = 1,所有发件人 ID = 1 的消息都应该在列表视图的右侧,但是相反,我得到了这个:
这是列表视图中第 5-8 个元素的截图,但是第 7 个元素在右侧而不是在左侧,后面的元素继续重复前 6 个元素的模式。我已经检查了转换视图的日志,它只显示了 6 次,这是否与此错误有关?以及如何解决适配器无法正确定位列表项资源的问题?
编辑:我已将 getItemViewType() 的覆盖更改为此
@Override
public int getItemViewType(int position) {
chatMessage chatMessage = getItem(position);
if (chatMessage.isMine()) {
return 0;
} else {
return 1;
}
}
我还删除了getViewTypeCount的覆盖方法,并在getView()方法中稍微改变了条件:
int viewType = getItemViewType(position);
if (viewType==0) {
layoutResource = R.layout.chat_bubble_right;
} else {
layoutResource = R.layout.chat_bubble_left;
}
现在聊天消息列表的顺序正常到第8个元素,然后顺序又变错了。
编辑 2
我已经跟踪日志中生成的列表项(即新项)的数量,这是我向下滚动到列表视图底部后得到的结果:
04-06 19:23:54.894 11202-11202/com.example.user.normalinterface D/ViewID: generated
04-06 19:23:54.907 11202-11202/com.example.user.normalinterface D/ViewID: generated
04-06 19:23:54.912 11202-11202/com.example.user.normalinterface D/ViewID: generated
04-06 19:23:54.914 11202-11202/com.example.user.normalinterface D/ViewID: generated
04-06 19:23:56.850 11202-11202/com.example.user.normalinterface D/ViewID: generated
这是否与我的问题有关?列表视图中的所有后续记录似乎都在重复列表中前 5 项的模式。
【问题讨论】:
-
我有一个非常相似的问题,当我找到解决方案时,我会发布我的解决方案。
标签: android listview android-arrayadapter