简体   繁体   English

从活动中更新片段列表视图

[英]Fragment listview update from activity

I am pretty new to Android (3 days), but I have a pretty good background in PHP (which may be the cause of my confusion in a Java based environment). 我刚接触Android(3天),但是我在PHP方面有很好的背景(这可能是我在基于Java的环境中感到困惑的原因)。 I started building an Android app using Android Studio (Beta). 我开始使用Android Studio(测试版)构建一个Android应用。 I created the default Android Studio activity with the Navigation Drawer Activity. 我使用导航抽屉活动创建了默认的Android Studio活动。 I edited the activity fragment part to look like this: 我编辑了活动片段部分,如下所示:

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

As you can see I am passing a Bundle to my Fragments called "messages" and "contacts" when an item is selected in the Navigation Drawer. 如您所见,当在导航抽屉中选择一个项目时,我会将一个捆绑包传递给称为“消息”和“联系人”的片段。 The "messages" bundle are XMPP messages received by the aSmack library from an OpenFire server. “邮件”捆绑包是aSmack库从OpenFire服务器接收的XMPP邮件。 So basically I'm trying to create a XMPP client. 所以基本上我正在尝试创建XMPP客户端。 When I run the app I can receive the messages in the "ChatsFragment". 当我运行该应用程序时,我可以在“ ChatsFragment”中接收消息。

Now my problem: I have to press the "ChatsFragment" item on the drawer to have my messages updated (re-receive the bundle) everytime I feel like there are new messages received from the server. 现在,我的问题是:每当我感觉到从服务器收到新消息时,都必须按抽屉上的“ ChatsFragment”项以更新我的消息(重新接收包)。 But I want this to be done automatically by the fragment. 但我希望通过片段自动完成此操作。

First I would like to know if my procedure is correct (Activity listens to server, creates bundle, send bundle to fragment, bundle updates messages on receive**) 首先,我想知道我的程序是否正确(活动监听服务器,创建捆绑包,将捆绑包发送到片段,捆绑包在接收时更新消息**)

** = This part I haven't been able to understand how to implement. ** =这部分我无法理解如何实现。

1- If the procedure is correct tell me how I should get the messages to be updated by the fragment through the activity? 1-如果程序正确,请告诉我如何通过活动通过片段更新消息?

2- If this is not the correct way to do things in Android, recommend me a way of doing it. 2-如果这不是在Android中执行操作的正确方法,请向我推荐一种执行方法。

My code for displaying the messages in fragment: 我用于显示消息片段的代码:

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

        }
    });

}

Thanks in advance. 提前致谢。

Typically for long running operations in the background, like listening to a server, incoming messages, etc, you need to use Services. 通常,对于在后台长时间运行的操作(例如侦听服务器,传入消息等),您需要使用服务。 You do so by subclassing the Service class in Android. 您可以通过在Android中子类化Service类来实现。

Now for your problem - the design approach should be that you have a background service listening to incoming messages. 现在解决您的问题-设计方法应该是您有一个后台服务来监听传入的消息。 Anytime a message is received (an input stream in your socket operator) you should send a "broadcast" an intent that a message was received. 每当接收到一条消息(套接字运算符中的输入流)时,您都应该向“广播”发送一条意图,即接收到一条消息。 A custom broadcast receiver that you create should wait for this broadcast. 您创建的自定义广播接收器应等待此广播。 Within the onReceive() method of this receiver, you should trigger the creation of the bundle and updating your message. 在此接收者的onReceive()方法中,您应该触发捆绑的创建并更新您的消息。

Remember you should always delegate your long running operations in Android to services. 请记住,您应该始终将Android中长期运行的操作委托给服务。 That is exactly what they are for. 那正是他们的目的。

So basically if you're already listening for new messages to come in your activity, then you must have some kind of callback like onMessageRecieved() or something like that. 因此,基本上,如果您已经在听新消息了,那么您必须具有某种回调,例如onMessageRecieved()或类似的回调。

If you do, you can then notify your fragment in this way. 如果这样做,则可以通过这种方式通知您的片段。 Create a field (goes under your class declaration) called curFrag, so something like this: 创建一个名为curFrag的字段(在类声明下),如下所示:

public class MyActivity extends Activity {

private Fragment curFrag; 

//other code...

}

then in the code you posted you would initialize the curFrag there, but you also need to set a tag for the current fragment. 然后在您发布的代码中,您将在那里初始化curFrag,但是您还需要为当前片段设置标签。 This will be based on your case statement. 这将基于您的案例陈述。 Make some final string variables as tags. 将一些最终的字符串变量作为标签。 ie

public static final String CHATSTAG = "chatstag";

@Override
public void onNavigationDrawerItemSelected(int position) {
    Bundle bundle = new Bundle();
    bundle.putStringArrayList("contacts", arr);
    bundle.putStringArrayList("messages", messages);
    Fragment fragment = null;
    String tag = null; 
    switch (position) {
        case 0:
            tag = FRIENDSTAG;
            fragment = new FriendsFragment();
            break;
        case 1:
            tag = CHATSTAG;... and so on through the switch statement. 
            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();
//remember to set the tag.
        if(tag != null) {
fragmentManager.beginTransaction()
                .replace(R.id.container, fragment, tag).addToBackStack(null).commit();
        } else {

fragmentManager.beginTransaction()
                .replace(R.id.container,fragment,DEFAULTTAG).addToBackStack(null).commit();
}
       //new code
        curFrag = fragment;
    }
}

Now in your activity when a new message comes in, check the tag of the fragment and then if it matches a certain fragment, notify the fragment that new data has come in and retrieve it in the fragment. 现在在您的活动中,当收到新消息时,检查片段的标签,然后如果它与某个片段匹配,则通知该片段有新数据进入并在片段中检索它。

public void onMessageRecieved() {

if(curFrag.getTag().equalsIgnoreCase(CHATSTAG)) {

ChatsFragment frag = (ChatsFragment) curFrag;
frag.notifyDataRecieved();
}
}

Once you have a reference to your fragment in the activity, you have access to any public methods in that fragment. 一旦在活动中引用了您的片段,就可以访问该片段中的任何公共方法。

If your fragment cannot access the data on its own, then you'll need to get a reference to the activity and create a method in the activity that returns the new data. 如果片段无法单独访问数据,则需要获取对活动的引用,并在活动中创建一个返回新数据的方法。

So in your activity: 因此,在您的活动中:

public String getMessageData() {

String newData = ...//get stuff from server;
return newData;
}

then in your fragment 然后在你的片段

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.
}

It's not necessarily pretty but it works pretty well. 它不一定漂亮,但效果很好。 You should also check to make sure your fragments are attached when you do this so that you avoid null exceptions. 执行此操作时,还应检查并确保碎片已连接,以免出现空异常。

Hope this helps! 希望这可以帮助!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM