作为我的Android应用程序的一部分,我正在集成一个非常简单的自定义群聊功能;这只是一个概念验证功能。我知道这是暂时的,每当我重新启动应用程序时,我的聊天就会消失。我的应用使用Fragments和ViewPager在我的应用中创建标签。
我支持此功能的是一个LinkedList,它包含Message对象(发送时间,发件人姓名,消息)。无论何时发送或接收聊天,都会将其添加到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);
}
}
答案 0 :(得分:1)
在数组适配器中插入新数据后使用以下命令:
yourAdapterName.notifyDataSetChanged();
答案 1 :(得分:0)
您的CustomArrayAdapter
未使用您的LinkedList
。它使用Object[]
。根据您的问题和评论,我假设您在创建CustomArrayAdapter
时,在toArray()
上致电LinkedList
以获取Object[]
。
但是,此时Object[]
与LinkedList
完全分离。假设,LinkedList
一开始就有5个Message
个对象。您拨打toArray()
,然后获得包含这5个Object[5]
个对象的Message
。您稍后在add()
上致电LinkedList
,添加第6个Message
。 Object[5]
仍然是Object[5]
,对第6 Message
一无所知。 AdapterView
将更新的唯一方法是完全替换CustomArrayAdapter
。
所以,摆脱Object[]
。 ArrayAdapter
在其一半构造函数中占用List
。所以,替换:
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;
}
使用:
public class CustomArrayAdapter extends ArrayAdapter<Message> {
Context context;
int resource;
public CustomArrayAdapter(Context context, int resource, List<Message> messages) {
super(context, resource, messages);
this.context = context;
this.resource = resource;
}
然后,在getView()
中,将Message item = (Message) objects[position];
替换为Message item=getItem(position);
。
最后,当新的Message
到达时,请致电add()
上的CustomArrayAdapter
,这将同时更新您的List<Message>
并更新附加的AdapterView
。< / p>
答案 2 :(得分:0)
像这样更改代码。这不会做太多改变,
public class CustomArrayAdapter extends ArrayAdapter {
Context context;
int resource;
List objects ;
Activity activity ;
public CustomArrayAdapter(Context context, int resource, List objects) {
super(context, resource, objects);
this.context = context;
this.resource = resource;
//clone the arraylist.
this.objects = new ArrayList(objects);
activity = (Activity) context;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
MessageHolder messageHolder = null;
if (row == null) {
LayoutInflater inflater = LayoutInflater.from(context);
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.get(position);
messageHolder.chat_information.setText(item.getSenderName() + Constants.NEWLINE + item.getSendTime());
messageHolder.chat_message.setText(item.getMessageText());
return row;
}
public void setObjects(List newObjects)
{
if (objects != null)
{
objects.clear();
objects.addAll(newObjects);
}
}
public void refreshList() {
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
notifyDataSetChanged();
}
});
}
private class MessageHolder {
TextView chat_information;
TextView chat_message;
}
}
还有一个聊天消息调用setObjects()
方法和链接列表并调用refreshList()
方法