Исключение NullPointerException при onFocusSearch в BrowseFragment?

#android #android-studio #android-fragments #android-tv #leanback

#Android #android-studio #android-фрагменты #android-tv #откат

Вопрос:

Я работаю в приложении для Android TV с MainFragment расширением BrowseFragment , и иногда оно выходит из строя в методе onFocusSearch(View focused, int direction) , определенном mOnFocusSearchListener в BrowseFragment :

 private final BrowseFrameLayout.OnFocusSearchListener mOnFocusSearchListener =
        new BrowseFrameLayout.OnFocusSearchListener() {
    @Override
    public View onFocusSearch(View focused, int direction) {
        // if headers is running transition,  focus stays
        if (mCanShowHeaders amp;amp; isInHeadersTransition()) {
            return focused;
        }
        if (DEBUG) Log.v(TAG, "onFocusSearch focused "   focused   "   direction "   direction);

        if (getTitleView() != null amp;amp; focused != getTitleView() amp;amp;
                direction == View.FOCUS_UP) {
            return getTitleView();
        }
        if (getTitleView() != null amp;amp; getTitleView().hasFocus() amp;amp;
                direction == View.FOCUS_DOWN) {
            return mCanShowHeaders amp;amp; mShowingHeaders ?
                    mHeadersFragment.getVerticalGridView() :
                   mMainFragment.getView();
        }

        boolean isRtl = ViewCompat.getLayoutDirection(focused) == View.LAYOUT_DIRECTION_RTL;
        int towardStart = isRtl ? View.FOCUS_RIGHT : View.FOCUS_LEFT;
        int towardEnd = isRtl ? View.FOCUS_LEFT : View.FOCUS_RIGHT;
        if (mCanShowHeaders amp;amp; direction == towardStart) {
            if (isVerticalScrolling() || mShowingHeaders) {
                return focused;
            }
            return mHeadersFragment.getVerticalGridView();
        } else if (direction == towardEnd) {
            if (isVerticalScrolling()) {
                return focused;
            }
            return mMainFragment.getView(); //*****CRASH******
        } else {
            return null;
        }
    }
};
  

Примечание: строка, в которой происходит сбой, отмечена знаком //*****CRASH****** .
Этот сбой появляется не всегда, но когда он появляется, говорит, что mMainFragment это null так…

Не удается найти проблему. Помогите!

Поможет ли обновление библиотеки leanback?

Комментарии:

1. Не сохраняйте ссылки на фрагменты, попробуйте получить их из FragmentManager .

Ответ №1:

Значение onFocusSearchListener должно быть установлено после onStart вызова BrowseFragment . Сбой, скорее mMainFragment всего, вызван тем, что значение равно null или представление, которое оно возвращает, равно null, поскольку оно фактически еще не добавлено. К моменту onStart mMainFragment вызова будут вызваны методы жизненного цикла (включая onCreateView ).

Похоже, они его устанавливают onCreate . Итак, что вы могли бы сделать, это захватить то, на BrowseFrameLayout что настроен этот прослушиватель, сохранить прослушиватель, который они установили на нем, обнулить прослушиватель, а затем установить его обратно onStart в свой подкласс of BrowseFragment .

В onCreateView вашем BrowseFragment подклассе:

     BrowseFrameLayout mBrowseFrame = (BrowseFrameLayout) v.findViewById(R.id.browse_frame);
    OnFocusSearchListener mOnFocusSearchListener = mBrowseFrame.getOnFocusSearchListener();
    mBrowseFrame.setOnFocusSearchListener(null);
  

Затем в onStart вашем BrowseFragment подклассе:

    mBrowseFrame.setOnFocusSearchListener(mOnFocusSearchListener);
  

Комментарии:

1. Как я могу получить доступ к onFocusSearchListener, чтобы я мог установить его в onStart методе в моем подклассе?

2. Я думаю, что есть много способов сделать это, чтобы попытаться решить проблему. Изначально я предполагал, что вы устанавливаете свои собственные OnFocusSearchListener . Один из вариантов — отключить фокусировку до onStart . Другой способ — написать оболочку, вокруг mOnFocusSearchListener которой вызывается только mOnFocusSearchListener if mMainFragment не null . Но опубликовал другое решение, более похожее на мое первое предложение выше. Пожалуйста, не стесняйтесь попробовать все эти варианты.