15

У меня есть фрагмент, в котором используется новая парадигма CoordinatorLayout/AppBarLayout/CollapsingToolbarLayout, и я хотел бы иметь возможность обнаруживать, когда сворачиваемая панель инструментов полностью расширена, чтобы я мог выполнять операцию на весь фрагмент, в котором он находится, например выталкивая фрагмент из стека и переходя к новому, отбрасывая фрагмент. У меня работает код отклонения, мне просто нужно знать, когда и когда не использовать его.Обнаружение, когда AppBarLayout/CollapsingToolbarLayout полностью развернуто

Я немного экспериментировал с AppBarLayout.OnOffsetChangedListener, но не имел большой удачи. Есть ли способ использовать его, чтобы определить, когда вещи полностью расширены, или есть более предпочтительный метод, о котором кто-то знает?

Заранее благодарен!

EDIT: Я также вижу, что есть несколько реализаций для AppBarLayout.setExpanded(...), но не AppBarLayout.getExpanded() или что-то подобное, поэтому я тоже там тоже.

+0

возможно appBarLayout.addOnOffsetChangedListener может помочь, но я нашел, что это глючит Propably я не выполнил его правильно. – mstrengis

+0

Вы нашли решение для этого? Я столкнулся с той же проблемой, пытаясь предотвратить обновление ScrollRefreshLayout, когда панель инструментов частично рухнула. – Jimeux

ответ

26

Не похоже, что в API есть что-то, но, похоже, для меня работает. Возможно, это потребует тестирования.

boolean fullyExpanded = 
    (appBarLayout.getHeight() - appBarLayout.getBottom()) == 0; 

Edit: Вышеуказанное решение, похоже на работу, но так как я хотел, чтобы проверить это состояние, когда AppBar было прокручивать, я закончил с использованием следующего раствора с 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); 
    } 

} 
+0

Я закончил тем, что отказался от концепции, почему я хотел сделать это в первую очередь, но я приму свой ответ, поскольку вы говорите, что он работает на вас. Благодаря! –

+0

этот не работает для меня тоже. добавлена ​​реализация интерфейса, но он, похоже, не вызван –

+1

@ user1232726 Вам необходимо прикрепить слушателя к AppBarLayout. Я обновил код, чтобы сделать это. Если вам не нужны потенциальные утечки, просто используйте 'appBarLayout.setOnScrollChangeListener (this)' выполнит эту работу. – Jimeux

6

Мое решение основано на создании пользовательского вида. Сначала нужно создать класс, расширяющий родной AppBarLayout:

public class CustomAppBar extends AppBarLayout { .... 

Тогда в классе установить addOnOffsetChangedListener так:

this.addOnOffsetChangedListener... 

Вы можете сделать выше, установив в конструкторе или, возможно, путем вызова метода внутри конструктор. Так что вам нужно конструктор, не забывайте использовать конструктор с 2 Params, чтобы иметь возможность добавлен к 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 
} 

Тогда мы должны получить доступ к состоянию зрения, таким образом, создать личную логический внутри пользовательского класса представления, и установить его истинный или ложный, если ваш взгляд начинает развернутый или свернутые, в этом случае на моем взгляд, по умолчанию расширено:

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 или фрагмент получить вид и использовать метод, чтобы знать состояние AppBar

+0

Это кажется излишним, когда вы можете просто добавить 'OnOffsetChangedListener' непосредственно к экземпляру' AppBarLayout'. –

+0

Если вы только собираетесь использовать этот AppBarLayout один раз: да, это так. Но если более одного действия нужно знать о состоянии AppBarLayout, тогда: это СУХОЕ решение – cutiko

0

Я знаю, что это, возможно, немного поздно, но изучение исходного кода AppBArLayout я обнаружил, что AppBarLayout.OnOffsetChangedListener просто переводит значение из int getTopAndBottomOffset() of Ap Поведение pBar.

Так что в любое время вы можете просто использовать этот код, чтобы определить, расширить ли 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; 
} 
Смежные вопросы