-1

I'm working in an Android TV app with a MainFragment that extends BrowseFragment and sometimes it crashes in the method onFocusSearch(View focused, int direction) defined for mOnFocusSearchListener in the 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 && isInHeadersTransition()) {
            return focused;
        }
        if (DEBUG) Log.v(TAG, "onFocusSearch focused " + focused + " + direction " + direction);

        if (getTitleView() != null && focused != getTitleView() &&
                direction == View.FOCUS_UP) {
            return getTitleView();
        }
        if (getTitleView() != null && getTitleView().hasFocus() &&
                direction == View.FOCUS_DOWN) {
            return mCanShowHeaders && 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 && 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;
        }
    }
};

Note: The line where crash happens is marked with //*****CRASH******. This crash doesn't always appears,but when it does says that mMainFragment is null...

Can't find the problem. Help!

Updating leanback library, would help?

reflective_mind
  • 1,475
  • 3
  • 15
  • 28

1 Answers1

0

The onFocusSearchListener should be set after onStart is called in BrowseFragment. The crash is most likely because mMainFragment is null or the view it is returning is null since it hasn't actually been added yet. By the time onStart is called, the mMainFragment life cycle methods will have been called (including onCreateView).

It looks like they're setting it in onCreate. So what you could do is grab the BrowseFrameLayout that this listener is being set on, save the listener they set on it, null out the listener, and then set it back in onStart in your subclass of BrowseFragment.

In onCreateView of your BrowseFragment subclass:

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

Then in onStart of your BrowseFragment subclass:

   mBrowseFrame.setOnFocusSearchListener(mOnFocusSearchListener);
Kyle Venn
  • 4,597
  • 27
  • 41
  • How can I access onFocusSearchListener so I can set it in `onStart` method in my subclass? – whynottodayhum Oct 03 '16 at 07:59
  • I think there are many ways to go about this to try and solve the issue. I originally assumed you were setting your own `OnFocusSearchListener`. One option is to disable focus until `onStart`. Another is to write a wrapper around `mOnFocusSearchListener` which only calls `mOnFocusSearchListener` if `mMainFragment` isn't null. But posted another solution more similar to my first suggestion above. Please feel free to try all of those options out. – Kyle Venn Oct 03 '16 at 15:50