Обнаружение, когда 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;
}