Программно свернуть или развернуть CollapsingToolbarLayout

159

Простой вопрос, но я не могу найти ответ. Как я могу свернуть или расширить CollapsingToolbarLayoutпрограммно?

свернутая панель инструментов

↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓

расширенная панель инструментов

Tomas
источник
1
Я думал о том же самом. Также может быть интересно расширить панель инструментов до полноэкранного режима, когда пользователь нажимает на встроенный макет (например, изображение).
Мориц

Ответы:

322

Используя библиотеку поддержки v23, вы можете позвонить appBarLayout.setExpanded(true/false).

Дальнейшее чтение: AppBarLayout.setExpanded (логическое)

jaxvy
источник
2
Хорошо, спасибо за совет, но поддержка libs v23 очень глючная, поэтому я не могу проверить это сейчас, потому что мне нужно остаться на 22.2.1 ....
Tomas
Теперь у вас есть 23.0.1 с некоторыми исправлениями
Марио Веласко
6
Можно ли определить собственную анимацию с помощью библиотек поддержки 23.1.1? setExpanded (логическое, правда) имеет очень медленную анимацию ...
Nifhel
У меня была проблема, когда у меня есть раскладка со складной панелью инструментов и под ней обзор переработчика. При удалении элементов из окна повторного просмотра панель инструментов не работала должным образом, поэтому я бы расширил макет панели приложения, и она работала правильно. В итоге я использовал appBarLayout.setExpanded (true, true) для анимации.
Рэй Хантер
48

Я использую этот код для сворачивания панели инструментов. До сих пор не могу найти способ расширить его.

public void collapseToolbar(){
    CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) appbarLayout.getLayoutParams();
    behavior = (AppBarLayout.Behavior) params.getBehavior();
    if(behavior!=null) {
        behavior.onNestedFling(rootLayout, appbarLayout, null, 0, 10000, true);
    }
}

Редактировать 1: та же функция с отрицательной скоростью Y, но панель инструментов не развернута на 100% и значение false для последнего параметра должно работать

public void expandToolbar(){
    CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) appbarLayout.getLayoutParams();
    behavior = (AppBarLayout.Behavior) params.getBehavior();
    if(behavior!=null) {
        behavior.onNestedFling(rootLayout, appbarLayout, null, 0, -10000, false);
    }
}

Редактировать 2: этот код для меня

public void expandToolbar(){
    CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) appbarLayout.getLayoutParams();
    behavior = (AppBarLayout.Behavior) params.getBehavior();
    if(behavior!=null) {
        behavior.setTopAndBottomOffset(0);
        behavior.onNestedPreScroll(rootLayout, appbarLayout, null, 0, 1, new int[2]);
    }
}
  • setTopAndBottomOffset действительно расширить панель инструментов
  • onNestedPreScroll показывает содержимое внутри расширенной панели инструментов

Постараюсь реализовать поведение самостоятельно.

Tuấn Trần Anh
источник
2
Редактирование 1 также будет работать, если вы установите последний параметр onNestedFlingв false.
Рики Ли
2
params.getBehavior () возвращает ноль. В xml тег layout_behaviour устанавливается на одноуровневом элементе NestedScrollView, а не на AppBarLayout. Вы можете помочь мне?
User31689
Спасибо. Правка 1 работает правильно, если последний параметр неверен. :)
Sirelon
@ GobletSky Я столкнулся с той же проблемой. Я имел NestedScrollView в моем фрагменте и пытался вызвать, onNestedFling прежде чем установить фрагмент. После установки фрагмента я смог успешно вызвать метод.
usp
@usp На самом деле, моя проблема была совсем другой (несколько нубийская ошибка). Смотрите это: stackoverflow.com/questions/31067082/…
User31689
27

Вы можете определить, насколько он расширяется или сворачивается с вашим пользовательским аниматором. Просто используйте setTopAndBottomOffset(int).

Вот пример:

CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) appBar.getLayoutParams();
final AppBarLayout.Behavior behavior = (AppBarLayout.Behavior) params.getBehavior();
if (behavior != null) {
    ValueAnimator valueAnimator = ValueAnimator.ofInt();
    valueAnimator.setInterpolator(new DecelerateInterpolator());
    valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
        @Override
        public void onAnimationUpdate(ValueAnimator animation) {
            behavior.setTopAndBottomOffset((Integer) animation.getAnimatedValue());
            appBar.requestLayout();
        }
    });
    valueAnimator.setIntValues(0, -900);
    valueAnimator.setDuration(400);
    valueAnimator.start();
}
герхард
источник
2
Это единственный ответ, который на самом деле позволяет анимировать пользовательское смещение. Большое спасибо!
Гильерме Торрес Кастро
2
appBar.setExpanded (false, true); (открыть / закрыть, анимировать) Вам не нужно писать все эти строки
Puni
2
в @Puni, если вы хотите развернуть / свернуть до «нестандартного» смещения (например, выполнить многоэтапное свертывание), вам это понадобится.
威 其 威
Это лучшее решение для анимации смещения AppBar в случае, если вы не хотите писать пользовательское поведение. Одним обновлением фрагмента кода является вызов метода valueAnimator.setIntValues ​​() со стартовым значением поведения.topAndBottomOffset вместо 0, чтобы начать анимацию с текущего смещения панели приложения.
ролик
Чтобы использовать настраиваемую переменную ( -900 )для установки, valueAnimator.setIntValues- ( appBar.getTotalScrollRange() )
лучше
12

Я написал небольшое расширение для AppBarLayout. Это позволяет расширять и сворачивать CollapsibleToolbarLayoutкак с, так и без анимации. Кажется, делает это совершенно правильно.

Не стесняйтесь попробовать это.

Просто используйте его вместо своего AppBarLayout, и вы можете вызывать методы, отвечающие за расширение или свертывание CollapsingToolbarLayout.

Он работает точно так, как и ожидалось в моем проекте, но вам может понадобиться настроить значения fling / scroll в perform...методах (особенно в performExpandingWithAnimation()), чтобы они идеально подходили к вашему CollapsibleToolbarLayout.

Бартек Липински
источник
@ssdeno, пожалуйста, прочитайте Readme.md из Github. Это устарело начиная с v23 библиотеки поддержки. Начиная с версии v23 поддержки (переходя к AndroidX), setExpandedв AppBarLayout.
Бартек Липински
6

Используйте, mAppBarLayout.setExpanded(true)чтобы развернуть панель инструментов и использовать, mAppBarLayout.setExpanded(false)чтобы свернуть панель инструментов.

Если вы хотите программно изменить высоту CollapsingToolbarLayout, просто используйте mAppBarLayout.setLayoutParams(params);

Expand:

CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) mAppBarLayout.getLayoutParams();
params.height = 3*200; // HEIGHT

mAppBarLayout.setLayoutParams(params);
mAppBarLayout.setExpanded(true);

Collapse:

CoordinatorLayout.LayoutParams params =(CoordinatorLayout.LayoutParams) mAppBarLayout.getLayoutParams();
params.height = 3*80; // HEIGHT

mAppBarLayout.setLayoutParams(params);
mAppBarLayout.setExpanded(false);
Железный ахамед
источник
1
Это мне очень помогло.
NoName
1
Это так полезно. Спасибо!
sunlover3
5

для тех, кто хочет работать с onNestedPreScroll и получить ошибку, как я. я получаю NullPointerException в onCreate без этой строки

    CoordinatorLayout coordinator =(CoordinatorLayout)findViewById(R.id.tab_maincontent);
    CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) appBarLayout.getLayoutParams();
    //below line
    params.setBehavior(new AppBarLayout.Behavior() {});

и не работает должным образом с этим. но я работаю над этой проблемой

в onCreate:

        scrollToolbarOnDelay();

и...

    public void scrollToolbarOnDelay() {
            final Handler handler = new Handler();
            handler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    AppBarLayout appBarLayout = (AppBarLayout) findViewById(R.id.tab_appbar);
                    CoordinatorLayout coordinator = (CoordinatorLayout) findViewById(R.id.tab_maincontent);
                    CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) appBarLayout.getLayoutParams();
                    AppBarLayout.Behavior behavior = (AppBarLayout.Behavior) params.getBehavior();
         if(behavior!=null)
                    behavior.onNestedPreScroll(coordinator, appBarLayout, null, 0, 100, new int[]{0, 0});
         else
            scrollToolbarOnDelay()
                }
            }, 100);


        }
Сепер Нозарян
источник
1

Попробуй это...

расширять

appBarLayout.setExpanded(true, true);

Перезвонить

appBarLayout.setExpanded(false, true);
Виктор Сам В.С.
источник
0

Это может помочь расширить или свернуть:

appBarLayout.setActivated(true);
appBarLayout.setExpanded(true, true);
ROHIT LIEN
источник
0

я использую это

 private fun collapseAppbar() {
        scrollView.postDelayed(Runnable {
            scrollView?.smoothScrollTo(50, 50)
        }, 400)
    }
denizs
источник
0

Чтобы развернуть / свернуть AppBarLayout программно:

fun expandAppBarLayout(expand: Boolean, isAnimationEnabled: Boolean){
    appBarLayout.setExpanded(expand, isAnimationEnabled);
}
avisper
источник