我正在构建一个聊天应用程序,我对我的片段有一个问题,其中包含一个包含所有聊天记录的列表视图。
当用户收到消息时,聊天列表会更新(显示每个聊天的最后一条消息)( image 1 )。
当聊天不可见且该聊天中收到消息时,用户将收到通知(图像2 )
此时问题就出现了。当用户点击通知时,聊天列表视图似乎已被破坏。当用户在点击通知后收到另一条消息时,他/她的手机会振动,但聊天列表视图不会更改/更新。
单击通知后,其他视图可以正常工作。
下面是一段处理listview更新的代码。
protected PacketListener packetListener = new PacketListener() {
@Override
public void processPacket(Packet packet) {
final Message message = (Message) packet;
if (message.getBody() != null) {
final String fromName = StringUtils.parseName(message.getFrom());
runOnUiThread(new Runnable(){
@Override
public void run() {
Boolean seen = false;
if(ChatFragment.currentChat != null && ChatFragment.currentChat.getContact().getUsername().equals(fromName) && VisibilityHelper.appIsVisible() && VisibilityHelper.fragmentIsVisible(ChatFragment.fragmentClassName)) {
seen = true;
}
Long chat_id = chatsDataSource.getChatByContactId(contactsDataSource.getContactByUsername(fromName).getId()).getId();
ChatMessage newChatMessage = chatMessagesDataSource.insertChatMessage(chat_id, ConstantHelper.CHAT_MESSAGES_TYPE_RECEIVED, seen, DateHelper.getDatetime(), message.getBody());
Log.d("DEBUG", VisibilityHelper.sCurrentFragmentClassName);
if(VisibilityHelper.appIsVisible() && VisibilityHelper.fragmentIsVisible(ChatsFragment.fragmentClassName)) {
ChatsFragment chatsFragment = (ChatsFragment) getFragmentManager().findFragmentByTag(ChatsFragment.fragmentClassName);
Log.d("DEBUG", "REFRESHING");
chatsFragment.refreshChatsList();
}
if(!VisibilityHelper.appIsVisible()) {
notificationHelper.externalNotification(getBaseContext(), newChatMessage);
} else {
if(ChatFragment.currentChat != null && ChatFragment.currentChat.getContact().getUsername().equals(fromName) && VisibilityHelper.appIsVisible() && VisibilityHelper.fragmentIsVisible(ChatFragment.fragmentClassName)) {
ChatFragment.chatsList.add(newChatMessage);
ChatFragment.chatsList.notifyDataSetChanged();
} else {
notificationHelper.internalNotification(getBaseContext(), newChatMessage);
}
}
}
});
}
}
};
主要活动(如何创建片段)
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().requestFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
setContentView(R.layout.activity_main);
Bundle extras = getIntent().getExtras();
initializeDataSources();
setLastContactUpdate();
if(usersDataSource.getCurrentUser() == null)
{
Intent LoginActivity = new Intent(getApplicationContext(), LoginActivity.class);
LoginActivity.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(LoginActivity);
finish();
}
else
{
if(localServiceBinder == null)
localServiceBinder = new LocalServiceBinder();
bindLocalService();
runDispatchMethod(extras, savedInstanceState);
if (savedInstanceState == null) {
getAndSaveUserDetails();
GCMRegistrationID = registerGCM();
}
}
}
protected void runDispatchMethod(Bundle extras, Bundle savedInstanceState) {
if(savedInstanceState == null) {
startFragment(new ChatsFragment(), false);
}
if(extras != null && extras.getString(ConstantHelper.RECEIVED_MESSAGES_FROM) != null && !extras.getString(ConstantHelper.RECEIVED_MESSAGES_FROM).equals("")) {
getFragmentManager().popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
startFragment(new ChatsFragment(), false);
ChatFragment chatFragment = new ChatFragment();
Bundle chatExtras = (Bundle) new Bundle();
chatExtras.putString(ConstantHelper.RECEIVED_MESSAGES_FROM, extras.getString(ConstantHelper.RECEIVED_MESSAGES_FROM));
chatFragment.setArguments(chatExtras);
startFragment(chatFragment);
return;
}
}
public void startFragment(Fragment newFragment) {
startFragment(newFragment, true);
}
public void startFragment(Fragment newFragment, Boolean addToBackstack) {
if(addToBackstack) {
getFragmentManager().beginTransaction().replace(R.id.container, newFragment, newFragment.getClass().getName()).addToBackStack(newFragment.getClass().getName()).commit();
} else {
getFragmentManager().beginTransaction().replace(R.id.container, newFragment, newFragment.getClass().getName()).commit();
}
getFragmentManager().executePendingTransactions();
}
聊天适配器
public class ChatsAdapter extends BaseAdapter {
private List<Chat> chats;
private LayoutInflater inflater;
private String emptyLastMessageValue;
public ChatsAdapter(Context context, List<Chat> chats) {
this.chats = chats;
this.inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
emptyLastMessageValue = context.getText(R.string.fragment_chats_chat_created).toString();
}
@Override
public int getCount() {
return chats.size();
}
@Override
public Chat getItem(int position) {
return chats.get(position);
}
@Override
public long getItemId(int position) {
return chats.get(position).getId();
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View chatAdapterView = convertView;
if(convertView == null)
chatAdapterView = inflater.inflate(R.layout.adapter_chats, null);
TextView layout_fullname = (TextView) chatAdapterView.findViewById(R.id.fullname);
TextView layout_last_message = (TextView) chatAdapterView.findViewById(R.id.last_message);
TextView layout_unread_messages = (TextView) chatAdapterView.findViewById(R.id.unread_messages);
TextView layout_last_message_datetime = (TextView) chatAdapterView.findViewById(R.id.last_message_datetime);
Chat row = chats.get(position);
String firstname = row.getContact().getFirstname();
String fullname = row.getContact().getFullname();
if(firstname == null || firstname.equals(""))
fullname = StringHelper.ucfirst(row.getContact().getUsername());
layout_fullname.setText(fullname);
String last_message_value;
String last_message_datetime_value = "";
if(row.getLastMessage() == null) {
last_message_value = emptyLastMessageValue;
layout_last_message_datetime.setVisibility(TextView.GONE);
layout_unread_messages.setVisibility(TextView.GONE);
} else {
last_message_value = row.getLastMessage().getMessageBody();
last_message_datetime_value = DateHelper.toReadableDatetime(row.getLastMessage().getMessageDatetime());
layout_last_message_datetime.setText(last_message_datetime_value);
Integer unreadMessages = row.getUnreadMessages();
if(unreadMessages > 0) {
layout_unread_messages.setText(String.valueOf(unreadMessages));
layout_unread_messages.setVisibility(TextView.VISIBLE);
} else {
layout_unread_messages.setVisibility(TextView.GONE);
}
}
layout_last_message.setText(last_message_value);
return chatAdapterView;
}
}
刷新聊天列表功能
public void refreshChatsList() {
Log.d("DEBUG", "It does come here!");
chats.clear();
chats.addAll(((MainActivity) getActivity()).chatsDataSource.getAllChats());
chats_adapter.notifyDataSetChanged();
}
Logcat输出
07-06 20:12:43.892: D/SMACK(14948): 08:12:43 PM RCV (1106735848): <message id="3jRRg-24" to="tijme@192.168.137.1" type="chat" from="test@192.168.137.1/Smack"><body>Test</body></message>
07-06 20:12:43.962: D/DEBUG(14948): nl.test.messatch.fragments.ChatsFragment
07-06 20:12:43.962: D/DEBUG(14948): REFRESHING
07-06 20:12:43.962: D/DEBUG(14948): It does come here!
07-06 20:12:48.406: D/SMACK(14948): 08:12:48 PM RCV (1106735848): <message id="3jRRg-25" to="tijme@192.168.137.1" type="chat" from="test@192.168.137.1/Smack"><body>Test 2</body></message>
07-06 20:12:48.446: D/DEBUG(14948): nl.test.messatch.fragments.ChatsFragment
07-06 20:12:51.059: D/KUTZOOI(14948): HELEMAAL WÄCK
07-06 20:12:51.099: D/dalvikvm(14948): GC_FOR_ALLOC freed 161K, 3% free 9653K/9912K, paused 19ms, total 21ms
07-06 20:12:51.109: I/dalvikvm-heap(14948): Grow heap (frag case) to 13.272MB for 4000016-byte allocation
07-06 20:12:51.139: D/dalvikvm(14948): GC_FOR_ALLOC freed 1K, 2% free 13558K/13820K, paused 25ms, total 25ms
07-06 20:12:54.953: D/SMACK(14948): 08:12:54 PM RCV (1106735848): <message id="3jRRg-26" to="tijme@192.168.137.1" type="chat" from="test@192.168.137.1/Smack"><body>Test 3</body></message>
07-06 20:12:54.993: D/DEBUG(14948): nl.test.messatch.fragments.ChatsFragment
07-06 20:12:54.993: D/DEBUG(14948): REFRESHING
07-06 20:12:54.993: D/DEBUG(14948): It does come here!
聊天列表
通知
答案 0 :(得分:2)
通过单击通知(根据问题出现的方式判断)返回活动后,确保使用相同的片段。如果您没有持有对用户看到的同一实例的引用,那么任何聊天更新都将无声地失败,因为您只会更新背景片段(而不是可见的片段)。错误似乎在runDispatchMethod()
中,每次不检查ChatsFragment
的另一个实例是否已经可用时,您使用新片段进行事务处理(在这种情况下,您只需调用更新方法)那个例子。
答案 1 :(得分:1)
(如果可以,我会发表评论)
我认为问题是notifyingdatasetChanged();
将此添加到您的适配器
public void swapItems(List<Chat> chat) {
this.chats = chat;
notifyDataSetChanged();
}
将此名称称为新讯息
chats_adapter.swapItems(((MainActivity) getActivity()).chatsDataSource.getAllChats());