预加载所有碎片的视图?

时间:2012-10-27 00:13:16

标签: android android-fragments android-tabs

初始状况:

您好,我目前正在处理现有应用的更新,并且遇到一项特定活动的问题。它包含7个选项卡,在这些选项卡中有不同方法的几个图像按钮和文本视图。

在应用程序的原始版本中,我使用了tabhost,并且基本上拥有了一个xml文件和一个java文件所需的所有内容,但是无法侧向滑动tabcontent来更改选项卡,所以我创建了整个事物再次用碎片。

挑战:

在ActionBar中,我有一个过滤器按钮,它应该隐藏所有选项卡中的某些文本视图和图像按钮,方法是检查一个标志,然后调用所有7个片段类中的方法,然后将它们的rootView中的视图设置为GONE如果再次切换,可见。

问题:

如果用户首先滚动浏览所有选项卡,则此ActionBar按钮可正常工作,但如果点击该应用程序的冷启动,则会使用NullPointer Exceptions使应用程序崩溃。 我怀疑这是因为并非所有片段都已加载。

问题:

我应该在活动开始时预加载所有片段吗? 如果是这样,我将如何做到这一点以及将在哪个文件中完成? 有没有另一种,也许更好的方法,以确保,我可以操纵ActionBar中的所有选项卡/片段,即使我不知道,之前打开了哪些片段? 我应该将这些方法混合在一个全球方法中吗?它将以什么文件出现?

目前,它只有在你首先滚动浏览所有标签时才有效,然后我可以根据需要随时切换过滤器。

代码:

这在活动类中调用:

    public void toggleintroonly() {
    MenuItem toggle = menu.findItem(R.id.mtoggle);

    if (visible == 1) {
        Fragments1.toggleintroonly();
        Fragments2.toggleintroonly();
        Fragments3.toggleintroonly();
        Fragments4.toggleintroonly();
        Fragments5.toggleintroonly();
        Fragments6.toggleintroonly();
        Fragments7.toggleintroonly();
        toggle.setTitle(getString(R.string.menu4toggled));
        toggle.setIcon(R.drawable.ic_action_showall);
        visible = 0;
    } else {
        Fragments1.showall();
        Fragments2.showall();
        Fragments3.showall();
        Fragments4.showall();
        Fragments5.showall();
        Fragments6.showall();
        Fragments7.showall();
        toggle.setTitle(getString(R.string.menu4));
        toggle.setIcon(R.drawable.ic_action_filter);
        visible = 1;
    }
}

这是来自Fragments1.toggleintroonly()的样本:

public static void toggleintroonly() {
    rootView.findViewById(R.id.tv1x02).setVisibility(View.GONE);
    rootView.findViewById(R.id.bplay1x02).setVisibility(View.GONE);
    rootView.findViewById(R.id.bshare1x02).setVisibility(View.GONE);
    rootView.findViewById(R.id.binfo1x02).setVisibility(View.GONE);
    rootView.findViewById(R.id.bring1x02).setVisibility(View.GONE);
}

在活动启动后立即点击ActionBar中的过滤器按钮时出现错误:

10-27 16:43:34.923: E/MediaPlayer(16946): mOnCompletionListener is null. Failed to send MEDIA_PLAYBACK_COMPLETE message.
10-27 16:43:49.433: D/AndroidRuntime(16946): Shutting down VM
10-27 16:43:49.433: W/dalvikvm(16946): threadid=1: thread exiting with uncaught exception (group=0x40c511f8)
10-27 16:43:49.448: E/AndroidRuntime(16946): FATAL EXCEPTION: main
10-27 16:43:49.448: E/AndroidRuntime(16946): java.lang.NullPointerException
10-27 16:43:49.448: E/AndroidRuntime(16946):    at com.cheftony.psychsoundboard.Fragments3.toggleintroonly(Fragments3.java:225)
10-27 16:43:49.448: E/AndroidRuntime(16946):    at com.cheftony.psychsoundboard.NicknamesNew.toggleintroonly(NicknamesNew.java:121)
10-27 16:43:49.448: E/AndroidRuntime(16946):    at com.cheftony.psychsoundboard.NicknamesNew.onOptionsItemSelected(NicknamesNew.java:90)
10-27 16:43:49.448: E/AndroidRuntime(16946):    at android.app.Activity.onMenuItemSelected(Activity.java)
10-27 16:43:49.448: E/AndroidRuntime(16946):    at android.support.v4.app.FragmentActivity.onMenuItemSelected(FragmentActivity.java:353)
10-27 16:43:49.448: E/AndroidRuntime(16946):    at com.android.internal.policy.impl.PhoneWindow.onMenuItemSelected(PhoneWindow.java)
10-27 16:43:49.448: E/AndroidRuntime(16946):    at com.android.internal.view.menu.MenuBuilder.dispatchMenuItemSelected(MenuBuilder.java)
10-27 16:43:49.448: E/AndroidRuntime(16946):    at com.android.internal.view.menu.MenuItemImpl.invoke(MenuItemImpl.java)
10-27 16:43:49.448: E/AndroidRuntime(16946):    at com.android.internal.view.menu.MenuBuilder.performItemAction(MenuBuilder.java)
10-27 16:43:49.448: E/AndroidRuntime(16946):    at com.android.internal.view.menu.ActionMenuView.invokeItem(ActionMenuView.java)
10-27 16:43:49.448: E/AndroidRuntime(16946):    at com.android.internal.view.menu.ActionMenuItemView.onClick(ActionMenuItemView.java)
10-27 16:43:49.448: E/AndroidRuntime(16946):    at android.view.View.performClick(View.java)
10-27 16:43:49.448: E/AndroidRuntime(16946):    at android.view.View$PerformClick.run(View.java)
10-27 16:43:49.448: E/AndroidRuntime(16946):    at android.os.Handler.handleCallback(Handler.java)
10-27 16:43:49.448: E/AndroidRuntime(16946):    at android.os.Handler.dispatchMessage(Handler.java)
10-27 16:43:49.448: E/AndroidRuntime(16946):    at android.os.Looper.loop(Looper.java)
10-27 16:43:49.448: E/AndroidRuntime(16946):    at android.app.ActivityThread.main(ActivityThread.java)
10-27 16:43:49.448: E/AndroidRuntime(16946):    at java.lang.reflect.Method.invokeNative(Native Method)
10-27 16:43:49.448: E/AndroidRuntime(16946):    at java.lang.reflect.Method.invoke(Method.java:511)
10-27 16:43:49.448: E/AndroidRuntime(16946):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java)
10-27 16:43:49.448: E/AndroidRuntime(16946):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java)
10-27 16:43:49.448: E/AndroidRuntime(16946):    at dalvik.system.NativeStart.main(Native Method)

错误似乎是在Fragments3类中引起的,因为在Activity启动时,Fragments1处于活动状态,并且它的直接邻居Fragments2也被预加载。

1 个答案:

答案 0 :(得分:2)

一些建议:

  1. 如果您使用的是7个标签页,则可以考虑使用ViewPager。它将有助于加快用户体验。 :)

  2. 确保Fragment在调用Activity之前不认为onActivityCreated()已创建。这可能是您获得NullPointerException

  3. 的原因
  4. 您的Fragment应该作为独立的UI组件。如果您的Fragment彼此互动,您可能需要重新考虑您的设计,因为它可能会让事情变得复杂。

  5. 除非您的Fragment花费很长时间才能创建/显示,否则我不确定是否需要预加载Fragment。使用7个选项卡时,用户可能不会使用所有Fragment,因此加载所有这些选项卡可能会造成浪费。预加载少数几个也没有意义,因为你永远不知道用户接下来会选择哪个标签。听起来我最好的解决方案就是初始化一个新的Fragment,并在用户点击标签时用它填充标签的视图。