Java 来自活动的片段listview更新
我对Android相当陌生(3天),但我在PHP方面有相当好的背景(这可能是我在基于Java的环境中感到困惑的原因)。我开始使用Android Studio(测试版)构建Android应用程序。我使用导航抽屉活动创建了默认的Android Studio活动。我将活动片段部分编辑为如下所示:Java 来自活动的片段listview更新,java,android,listview,android-fragments,Java,Android,Listview,Android Fragments,我对Android相当陌生(3天),但我在PHP方面有相当好的背景(这可能是我在基于Java的环境中感到困惑的原因)。我开始使用Android Studio(测试版)构建Android应用程序。我使用导航抽屉活动创建了默认的Android Studio活动。我将活动片段部分编辑为如下所示: @Override public void onNavigationDrawerItemSelected(int position) { Bundle bundle = new Bundle();
@Override
public void onNavigationDrawerItemSelected(int position) {
Bundle bundle = new Bundle();
bundle.putStringArrayList("contacts", arr);
bundle.putStringArrayList("messages", messages);
Fragment fragment = null;
switch (position) {
case 0:
fragment = new FriendsFragment();
break;
case 1:
fragment = new ChatsFragment();
break;
case 2:
fragment = new GroupsFragment();
break;
case 3:
fragment = new LogoutFragment();
break;
default:
break;
}
if (fragment != null) {
fragment.setArguments(bundle);
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.container, fragment).addToBackStack(null).commit();
}
}
public class MyActivity extends Activity {
private Fragment curFrag;
//other code...
}
如您所见,当在导航抽屉中选择一个项目时,我正在将一个名为“messages”和“contacts”的包传递给我的片段。“消息”包是aSmack库从OpenFire服务器接收的XMPP消息因此,基本上我正在尝试创建一个XMPP客户端。当我运行应用程序时,我可以在“ChatsFragment”中接收消息
现在我的问题是:
每当我感觉有新的邮件从服务器接收时,我必须按抽屉上的“ChatsFragment”项更新邮件(重新接收捆绑包)。但我希望这是由片段自动完成的
public void onMessageRecieved() {
if(curFrag.getTag().equalsIgnoreCase(CHATSTAG)) {
ChatsFragment frag = (ChatsFragment) curFrag;
frag.notifyDataRecieved();
}
}
首先,我想知道我的过程是否正确(Activity侦听服务器,创建bundle,将bundle发送到fragment,bundle在接收时更新消息**)
**=这部分我还不知道如何实现
1-如果过程正确,请告诉我如何通过活动获取片段更新的消息
2-如果这不是在Android中做事情的正确方法,请向我推荐一种方法
我在片段中显示消息的代码:
private void displayListView() {
// Messages array list
List<String> contacts = getArguments().getStringArrayList("messages");
//System.out.println("arr: " + contacts);
//create an ArrayAdaptar from the String Array
ArrayAdapter<String> dataAdapter = new ArrayAdapter<String>(getActivity(),
R.layout.url_list, contacts);
ListView listView = (ListView) getView().findViewById(R.id.listView);
// Assign adapter to ListView
listView.setAdapter(dataAdapter);
//enables filtering for the contents of the given ListView
listView.setTextFilterEnabled(true);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
// Send the URL to the host activity
//mListener.onURLSelected(((TextView) view).getText().toString());
}
});
}
private void displayListView(){
//消息数组列表
列出联系人=getArguments().getStringArrayList(“消息”);
//系统输出打印项次(“arr:+触点);
//从字符串数组创建ArrayAdaptar
ArrayAdapter dataAdapter=新的ArrayAdapter(getActivity(),
R.layout.url(列表、联系人);
ListView ListView=(ListView)getView().findViewById(R.id.ListView);
//将适配器分配给ListView
setAdapter(dataAdapter);
//启用对给定ListView内容的筛选
setTextFilterEnabled(true);
setOnItemClickListener(新的AdapterView.OnItemClickListener(){
public void onItemClick(AdapterView父级、视图、,
内部位置,长id){
//将URL发送到主机活动
//mListener.onURLSelected(((TextView)视图).getText().toString());
}
});
}
提前感谢。通常对于后台长时间运行的操作,如侦听服务器、传入消息等,您需要使用服务。您可以通过在Android中对服务类进行子类化来实现这一点 现在解决您的问题-设计方法应该是让后台服务监听传入的消息。无论何时收到消息(套接字操作符中的输入流),您都应该发送一个“广播”,表明收到消息的意图。您创建的自定义广播接收器应等待此广播。在此接收器的onReceive()方法中,您应该触发包的创建并更新消息
请记住,您应该始终将Android中长期运行的操作委托给服务。这正是它们的用途。因此,基本上,如果您已经在监听活动中的新消息,那么您必须有类似onMessageRecieved()之类的回调 如果你这样做了,你可以用这种方式通知你的片段。 创建一个名为curFrag的字段(位于类声明下),如下所示:
@Override
public void onNavigationDrawerItemSelected(int position) {
Bundle bundle = new Bundle();
bundle.putStringArrayList("contacts", arr);
bundle.putStringArrayList("messages", messages);
Fragment fragment = null;
switch (position) {
case 0:
fragment = new FriendsFragment();
break;
case 1:
fragment = new ChatsFragment();
break;
case 2:
fragment = new GroupsFragment();
break;
case 3:
fragment = new LogoutFragment();
break;
default:
break;
}
if (fragment != null) {
fragment.setArguments(bundle);
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.container, fragment).addToBackStack(null).commit();
}
}
public class MyActivity extends Activity {
private Fragment curFrag;
//other code...
}
然后在您发布的代码中,您将在那里初始化curFrag,但是您还需要为当前片段设置一个标记。这将基于您的案例陈述。将一些最终字符串变量作为标记。
i、 e
现在,在您的活动中,当新消息传入时,检查片段的标记,然后如果它与某个片段匹配,则通知片段新数据已传入,并在片段中检索它
public void onMessageRecieved() {
if(curFrag.getTag().equalsIgnoreCase(CHATSTAG)) {
ChatsFragment frag = (ChatsFragment) curFrag;
frag.notifyDataRecieved();
}
}
一旦在活动中引用了片段,就可以访问该片段中的任何公共方法
public void onMessageRecieved() {
if(curFrag.getTag().equalsIgnoreCase(CHATSTAG)) {
ChatsFragment frag = (ChatsFragment) curFrag;
frag.notifyDataRecieved();
}
}
如果片段本身无法访问数据,则需要获取对活动的引用,并在活动中创建一个返回新数据的方法
因此,在您的活动中:
public String getMessageData() {
String newData = ...//get stuff from server;
return newData;
}
然后在你的碎片里
public void notifyNewMessage() {
try {
MyActivity activity = (MyActivity) getActivity();
} catch (ClassCastException e) {
e.printStackTrace();
} catch (NullPointerException e) {
e.printStackTrace();
}
String message = activity.getMessageData();
//do something with the message.
}
它不一定很漂亮,但效果很好。您还应该检查以确保在执行此操作时附加了片段,从而避免出现空异常
希望这有帮助 在我实现此设计方法并在收到消息时创建包之后,我如何通知片段在片段显示(活动)和未显示时更新自身?您的广播将由保存片段的活动中的BroadcastReceiver对象接收。如果片段处于活动状态,则可以直接传递Bundle对象。如果不是,那么你可以设置一个类似于标志的东西,这样片段就知道它需要在下次启动时更新。谢谢你的建议,我仔细阅读了它,我认为这是一个很好的方法。我必须实现它并测试它。你知道什么时候不显示片段吗?我想在片段显示时用收到的消息更新它?你可能需要有一个backbackback的引用,或者像前面的片段一样。或者,您可以在片段的onResume()方法中执行一些操作,以刷新消息列表,类似于我上面概述的内容。顺便说一句,sunil在上述服务方面的回答是正确的