【发布时间】:2016-04-13 16:11:08
【问题描述】:
作为我的 Android 应用程序的一部分,我正在集成一个非常简单的自定义群聊功能;这只是一个概念验证功能。我知道这是暂时的,每当我重新启动我的应用程序时,我的聊天就会消失。我的应用使用 Fragments 和 ViewPager 在我的应用中创建标签。
我支持此功能的是一个 LinkedList,其中包含消息对象(发送时间、发件人姓名、消息)。每当发送或接收聊天时,它都会被添加到 LinkedList。在 MainActivity.java 的开头,我声明了列表
public static LinkedList<Message> chatList;
在onCreate方法中,我初始化列表
chatList = new LinkedList<Message>();
我有一个在后台运行的侦听器线程,用于侦听传入的消息。我在它的构造函数中将 chatList 传递给了这个线程
MyListener myListener = new MyListener(MainActivity.this, chatList);
Thread listenerThread = new Thread(myListener);
listenerThread.start();
每当监听线程接收到消息时,它都会将其粘贴到 LinkedList 中
chatList.add(new_message_object);
为了显示聊天,我使用了一个由自定义 ArrayAdapter 支持的 ListView,我在其中重写了 getView() 方法。 ArrayAdapter 从我的 LinkedList 的 toArray() 方法中获取数组,并在屏幕上显示聊天。
这个过程几乎有效。每当收到聊天记录时,LinkedList 就会成功填充。问题是让 ListView 立即更新并显示聊天。如果我在我的应用程序中切换到一个新的片段/选项卡,然后切换回我的聊天选项卡,那么列表就会被填充;但是,每当我想看到任何新聊天时,我都必须这样做。
对于我在本地输入的任何聊天(即在我的聊天功能中)也是如此。它仍然添加到 LinkedList,但 ListView 没有刷新。
我不想使用 SwipeRefreshLayout,我宁愿更新列表本身。我在自定义 ArrayAdapter 中创建了一个方法
public void refreshList(){
this.notifyDataSetChanged();
}
每当有新消息对象添加到 LinkedList 时,我都会调用它,但它不会刷新列表。
那么,我做错了什么?就像我说的,我更喜欢 ListView 更新本身,就像一个适当的聊天程序一样。
谢谢
编辑:
根据要求,这是我的自定义 ArrayAdapter
public class CustomArrayAdapter extends ArrayAdapter {
Context context;
int resource;
Object[] objects;
public CustomArrayAdapter(Context context, int resource, Object[] objects) {
super(context, resource, objects);
this.context = context;
this.resource = resource;
this.objects = objects;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
MessageHolder messageHolder = null;
if(row == null){
LayoutInflater inflater = ((Activity)context).getLayoutInflater();
row = inflater.inflate(resource, parent, false);
messageHolder = new MessageHolder();
messageHolder.chat_information = (TextView) row.findViewById(R.id.chat_information);
messageHolder.chat_message = (TextView) row.findViewById(R.id.chat_message);
row.setTag(messageHolder);
} else {
messageHolder = (MessageHolder) row.getTag();
}
Message item = (Message) objects[position];
messageHolder.chat_information.setText(item.getSenderName() + Constants.NEWLINE + item.getSendTime());
messageHolder.chat_message.setText(item.getMessageText());
return row;
}
public void refreshList(){
this.notifyDataSetChanged();
}
private class MessageHolder {
TextView chat_information;
TextView chat_message;
}
}
编辑 2:
我正在添加我的 Chat.java 片段。
public class Chat extends Fragment {
private View rootView;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.chat, container, false);
return rootView;
}
@Override
public void onViewCreated(View rootView, Bundle savedInstanceState) {
super.onViewCreated(rootView, savedInstanceState);
displayChats();
}
@Override
public View getView() {
Button sendChatButton = (Button) rootView.findViewById(R.id.text_send);
sendChatButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Date rightNow = new Date();
SimpleDateFormat timeSDF = new SimpleDateFormat(Constants.SIMPLE_TIME);
SimpleDateFormat dateSDF = new SimpleDateFormat(Constants.SIMPLE_DATE);
SharedPreferences myAppPreferences = getContext().getSharedPreferences(Constants.PREFS_NAME, getContext().MODE_PRIVATE);
EditText chatEntryWindow = (EditText)rootView.findViewById(R.id.chat_text_compose);
String message = chatEntryWindow.getText().toString();
String username = myAppPreferences.getString("username", Constants.TABLET_ID);
Message myMessage = new Message(username, message, 0, dateSDF.format(rightNow), timeSDF.format(rightNow));
CustomArrayAdapter caa = new CustomArrayAdapter(getActivity(), R.layout.outgoing_line_of_chat, MainActivity.chatList);
caa.add(myMessage);
caa.notifyDataSetChanged();
new SendChat(getActivity(), message, username).execute();
}
});
return super.getView();
}
public void displayChats(){
ListView list = (ListView) rootView.findViewById(R.id.chat_text_display);
ArrayAdapter adapter = new CustomArrayAdapter(getActivity(), R.layout.outgoing_line_of_chat, MainActivity.chatList);
list.setAdapter(adapter);
}
}
【问题讨论】:
-
“ArrayAdapter 读取我的 LinkedList 的 toArray() 方法并在屏幕上显示聊天”——这对我来说没有多大意义。我建议您编辑您的问题并发布您的
getView()方法,或者可能是整个ArrayAdapter。通常,您在ArrayAdapter上调用add()/insert()/remove()来更新内容并刷新附加的AdapterView,但notifyDataSetChanged()(在直接操作List之后)应该有效果一样。 -
@CommonsWare 这意味着 ArrayAdapter 需要一个数组,而 LinkedList.toArray() 方法将 LinkedList 转换为 ArrayAdapter 可用的数组。
-
我怀疑你有更大的问题。我仍然建议您编辑您的问题并发布您的
ArrayAdapter子类。 -
@CommonsWare 我已将我的 ArrayAdapter 添加到帖子中。
-
我已经更新了我的答案。
标签: android listview android-arrayadapter