Предварительно загрузить все виды фрагментов?

Исходная ситуация:

Привет, в настоящее время я работаю над обновлением для существующего приложения, и у меня есть проблемы с одним конкретным действием. Он содержит 7 вкладок, и на этих вкладках есть несколько кнопок изображений и текстовых представлений для разных методов.

В исходной версии приложения я использовал tabhost и в основном имел весь необходимый контент в одном xml-файле и одном java-файле, но было невозможно смахнуть содержимое вкладки в сторону, чтобы изменить вкладки, поэтому я снова создал все это с фрагментами. .

Вызов:

В ActionBar у меня есть кнопка фильтра, которая должна скрывать определенные текстовые представления и кнопки изображений со ВСЕХ вкладок, проверяя флаг, а затем вызывая методы во всех 7 классах фрагментов, которые затем устанавливают представления в их rootView в GONE и при переключении опять же, на ВИДИМОЕ.

Проблема:

Эта кнопка ActionBar работает нормально, если пользователи сначала прокручивают все вкладки, но если щелкнуть при холодном запуске приложения, это приведет к сбою приложения с исключениями NullPointer. Я подозреваю, что это так, потому что еще не все фрагменты загружены.

Вопрос:

Должен ли я предварительно загружать все фрагменты в начале действия? Если да, то как мне это сделать и в каком файле это будет выполнено? Есть ли другой, может быть, лучший способ убедиться, что я могу манипулировать всеми вкладками/фрагментами из панели действий, даже если я не знаю, какие фрагменты были открыты раньше? Должен ли я смешать все эти методы в один глобальный? В каком файле это будет?

В настоящее время это работает только в том случае, если вы сначала прокрутите все вкладки, а затем я смогу переключать фильтр так часто, как захочу.

Код:

Это вызывается в классе активности:

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

Вот ошибка при нажатии кнопки фильтра на панели действий сразу после запуска действия:

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 также предварительно загружен.


person Marcel Ulbrich    schedule 27.10.2012    source источник
comment
Можете ли вы добавить больше информации о NullPointerException?   -  person Maxim Shoustin    schedule 27.10.2012
comment
Спасибо, что нашли время, чтобы структурировать / отформатировать ваш вопрос :)   -  person Alex Lockwood    schedule 27.10.2012


Ответы (1)


Пара предложений:

  1. Если вы работаете с 7 вкладками, вы можете вместо этого использовать ViewPager. Это поможет ускорить взаимодействие с пользователем. :)

  2. Убедитесь, что ваши Fragment не предполагают, что Activity был создан, пока не будет вызван onActivityCreated(). Возможно, поэтому вы получаете NullPointerException.

  3. Ваши Fragment должны служить независимыми компонентами пользовательского интерфейса. Если ваши Fragment взаимодействуют друг с другом, вы можете переосмыслить свой дизайн, так как это, вероятно, усложняет ситуацию.

  4. Если для создания/отображения ваших Fragment не требуется слишком много времени, я не уверен, что предварительная загрузка Fragment необходима. С 7 вкладками пользователь может не использовать все Fragment, поэтому загружать их все может быть расточительно. Предварительная загрузка избранных также не имеет смысла, поскольку вы никогда не можете знать, какую вкладку пользователь выберет следующей. Мне кажется, что лучшим решением было бы просто инициализировать новый Fragment и заполнить им представление вкладки, когда пользователь нажимает на вкладку.

person Alex Lockwood    schedule 27.10.2012
comment
1. Я использую такие вкладки для быстрой навигации, поэтому вверху видно несколько вкладок, панель вкладок можно прокручивать по горизонтали, поэтому можно легко перейти с вкладки 7 на вкладку 1, не смахивая содержимое вбок: picasaweb.google.com/1068428318649329 - person Marcel Ulbrich; 27.10.2012
comment
2. и 3. действие фильтра вызывается с помощью кнопки на панели действий и должно манипулировать всеми 7 фрагментами, я не хочу изменять содержимое другого фрагмента не из одного фрагмента. и 4. поскольку кнопка фильтра видна во всей активности, а ее значок меняется с фильтра, чтобы показать все, на мой взгляд, имеет смысл фильтровать все вкладки сразу, потому что после установки фильтра пользователи ожидают, когда они изменятся вкладку, чтобы найти там отфильтрованный контент. это поведение соответствует предыдущей версии приложения и версиям для устаревших ОС. - person Marcel Ulbrich; 27.10.2012
comment
эта активность вызывается только на устройствах, которые способны ее обрабатывать, только устройства ICS и jelly bean получают эту активность, и даже на эмуляторе она загружается мгновенно, поэтому не должно быть проблем с предварительной загрузкой фрагментов, тем не менее, я не знаю как это сделать. - person Marcel Ulbrich; 27.10.2012