Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/331.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/234.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 来自活动的片段listview更新_Java_Android_Listview_Android Fragments - Fatal编程技术网

Java 来自活动的片段listview更新

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();

我对Android相当陌生(3天),但我在PHP方面有相当好的背景(这可能是我在基于Java的环境中感到困惑的原因)。我开始使用Android Studio(测试版)构建Android应用程序。我使用导航抽屉活动创建了默认的Android Studio活动。我将活动片段部分编辑为如下所示:

@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在上述服务方面的回答是正确的