片段列表视图从活动更新

时间:2014-09-08 00:47:04

标签: java android listview android-fragments

我对Android很新(3天),但我有很好的PHP背景(这可能是我在基于Java的环境中混淆的原因)。我开始使用Android Studio(Beta)构建Android应用。我使用Navigation Drawer Activity创建了默认的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();
    }
}

正如你所看到的,我正在将一个Bundle传递给我的碎片,叫做#34;消息"和"联系人"在导航抽屉中选择项目时。 "消息" bundle是aSmack库从OpenFire服务器接收的XMPP消息。 基本上我正在尝试创建一个XMPP客户端。当我运行应用程序时,我可以在" ChatsFragment"中收到消息。

现在我的问题: 我必须按下" ChatsFragment"每次我觉得从服务器收到新消息时,抽屉上的项目会更新我的消息(重新接收捆绑包)。但是我希望这个片段能够自动完成。

首先,我想知道我的程序是否正确(Activity监听服务器,创建bundle,将bundle发送到fragment,在收到时捆绑更新消息**)

** =这部分我还没有能够理解如何实施。

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

        }
    });

}

提前致谢。

2 个答案:

答案 0 :(得分:1)

通常,对于后台长时间运行的操作,例如收听服务器,传入消息等,您需要使用服务。您可以通过在Android中继承Service类来实现此目的。

现在针对您的问题 - 设计方法应该是您有一个后台服务来监听传入的消息。无论何时收到消息(套接字操作员中的输入流),您都应该发送&#34;广播&#34;收到消息的意图。您创建的自定义广播接收器应等待此广播。在此接收器的onReceive()方法中,您应该触发创建包并更新消息。

请记住,您应该始终将Android中长时间运行的操作委派给服务。这正是他们的目的。

答案 1 :(得分:1)

所以基本上如果你已经在监听你的活动中出现的新消息,那么你必须有某种回调,比如onMessageRecieved()或类似的东西。

如果这样做,您可以通过这种方式通知您的片段。 创建一个名为curFrag的字段(在你的类声明下),如下所示:

public class MyActivity extends Activity {

private Fragment curFrag; 

//other code...

}

然后在您发布的代码中,您将初始化curFrag,但您还需要为当前片段设置标记。这将基于您的案例陈述。将一些最终的字符串变量作为标记。 即

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

现在在您的活动中,当有新消息进入时,检查片段的标签,然后如果它与某个片段匹配,则通知片段新数据已进入并在片段中检索它。

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

它不一定漂亮,但效果很好。您还应该检查以确保在执行此操作时附加了片段,以避免出现空例外。

希望这有帮助!