#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
ifmMainFragment
не null . Но опубликовал другое решение, более похожее на мое первое предложение выше. Пожалуйста, не стесняйтесь попробовать все эти варианты.