Обнаружение, когда AppBarLayout/CollapsingToolbarLayout полностью расширен
У меня есть фрагмент, в котором используется новая парадигма CoordinatorLayout/AppBarLayout/CollapsingToolbarLayout, и я хотел бы иметь возможность обнаруживать, когда сворачиваемая панель инструментов полностью расширена, так что я могу выполнить операцию по всему ее фрагменту, например. выталкивая фрагмент из стека и переходя к новому, отбрасывая фрагмент. У меня есть код отклонения, я просто должен знать, когда и когда не использовать его.
Я немного экспериментировал с AppBarLayout.OnOffsetChangedListener, но не имел большой удачи. Есть ли способ использовать его, чтобы определить, когда вещи полностью расширены, или есть более предпочтительный метод, о котором кто-то знает?
Спасибо заранее!
EDIT:
Я также вижу, что есть несколько реализаций для AppBarLayout.setExpanded(...), но не AppBarLayout.getExpanded() или что-то подобное, поэтому я тоже там.
Ответы
Ответ 1
Это не похоже на что-либо в API, но, похоже, для меня это работает. Возможно, это потребует тестирования.
boolean fullyExpanded =
(appBarLayout.getHeight() - appBarLayout.getBottom()) == 0;
Изменить: вышеприведенное решение работает, но поскольку я хотел проверить это условие при прокрутке панели приложения, я закончил использование следующего решения с OnOffsetChangedListener
.
class Frag extends Fragment implements AppBarLayout.OnOffsetChangedListener {
private boolean appBarIsExpanded = true;
private AppBarLayout appBarLayout;
@Override
public void onActivityCreated(Bundle state) {
super.onActivityCreated(state);
appBarLayout = (AppBarLayout) getActivity().findViewById(R.id.app_bar);
}
@Override
public void onResume() {
super.onResume();
appBarLayout.addOnOffsetChangedListener(this);
}
@Override
public void onStop() {
super.onStop();
appBarLayout.removeOnOffsetChangedListener(this);
}
@Override
public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
appBarIsExpanded = (verticalOffset == 0);
}
}
Ответ 2
Мое решение основано на создании настраиваемого представления. Сначала создайте класс, расширяющий собственный AppBarLayout:
public class CustomAppBar extends AppBarLayout { ....
Затем внутри класса установите addOnOffsetChangedListener следующим образом:
this.addOnOffsetChangedListener...
Вы можете сделать это, установив в конструкторе или, возможно, вызов метод внутри конструктора. Таким образом, вам нужен конструктор, не забудьте использовать конструктор с 2 параметрами, чтобы можно было добавить его в xml:
public CustomAppBar(Context context, AttributeSet attrs) {
super(context, attrs);
//You can set the listener here or maybe call the method that set the listener
}
Затем мы должны получить доступ к состоянию представления, поэтому создадим приватное логическое значение в вашем пользовательском классе представления и установите его в true или false, если ваше представление начнется с расширением или свертыванием, в этом случае мое представление по умолчанию расширен:
private boolean isExpanded = true;
Теперь вам нужно обновить состояние этого логического значения:
this.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() {
@Override
public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
if (verticalOffset == 0) {
isExpanded = true;
} else {
isExpanded = false;
}
}
});
Следующий шаг - получить состояние логического значения, используя геттер внутри класса CustomAppBar
public boolean isExpanded() {
return isExpanded;
}
Далее перейдите к вашему xml, используйте свой собственный вид там, затем в Acivity или Fragment получите представление и используйте метод, чтобы узнать статус AppBar
Ответ 3
Я знаю, что это может быть немного поздно, но, изучая исходный код AppBArLayout, я обнаружил, что AppBarLayout.OnOffsetChangedListener просто преобразует значение int getTopAndBottomOffset() поведения AppBar.
Поэтому в любой момент вы можете просто использовать этот код для определения расширения AppBarLayout или нет:
public boolean isAppBArExpanded(AppBarLayout abl) {
final CoordinatorLayout.Behavior behavior = ((CoordinatorLayout.LayoutParams) abl.getLayoutParams()).getBehavior();
return (behavior instanceof AppBarLayout.Behavior) ? (((AppBarLayout.Behavior) behavior).getTopAndBottomOffset() == 0) : false;
}