Програмно згортати або розгортати CollapsingToolbarLayout


158

Просте запитання, але я не можу знайти відповіді. Як я можу програмно згортати чи розширювати CollapsingToolbarLayout?

згорнута панель інструментів

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

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


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

Відповіді:


321

За допомогою бібліотеки підтримки v23 ви можете зателефонувати appBarLayout.setExpanded(true/false).

Подальше читання: AppBarLayout.setExpanded (булева)


2
Добре, дякую за підказку, але підтримка libs v23 дуже баггі, тому я не можу перевірити її зараз, тому що мені потрібно зупинитися на 22.2.1 ....
Томаш

Тепер у вас 23.0.1 з деякими виправленнями
Mario Velasco

6
Чи можливо визначити власну анімацію за допомогою lib-служб підтримки 23.1.1? setExpanded (boolean, правда) hav по-справжньому повільна анімація ...
Nifhel

У мене виникла проблема, коли у мене є макет із збірною панеллю інструментів та переглядом рециркулятора під нею. Під час видалення елементів із перегляду рециркуляторів панель інструментів не вела себе належним чином, тому я розширив макет панелі додатків, і він працював належним чином. Я в кінцевому підсумку використовував appBarLayout.setExpanded (правда, правда) для анімації.
Рей Хантер

49

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

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%, і помилка для останньої парами повинна працювати

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 дійсно показує вміст на розширеній панелі інструментів

Спробую реалізувати Поведінку власноруч.


2
Правка 1 також буде працювати, якщо ви встановите останній параметр onNestedFlingдо false.
Рікі Лі

2
params.getBehavior () повертається до нуля. У xml тег layout_behaviour встановлений у сибсте NestedScrollView, а не в AppBarLayout. Можеш допомогти мені?
Користувач31689

Дякую. Відредагуйте 1 роботу належним чином, якщо останній парам неправдивий. :)
Сирелон

@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 (помилково, правда); (відкрити / закрити, оживити) Не потрібно писати всі ці рядки
Пуні

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.
Bartek Lipinski

6

Використовуйте mAppBarLayout.setExpanded(true)для розширення Панелі інструментів і використовуйте mAppBarLayout.setExpanded(false)для згортання Панелі інструментів.

Якщо ви хочете програмно змінити висоту CollapsingToolbarLayout, просто використовуйте mAppBarLayout.setLayoutParams(params);

Розгорнути:

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

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

Згорнути:

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);


        }


0

Це може допомогти розширити чи згортати:

appBarLayout.setActivated(true);
appBarLayout.setExpanded(true, true);

0

я використовую це

 private fun collapseAppbar() {
        scrollView.postDelayed(Runnable {
            scrollView?.smoothScrollTo(50, 50)
        }, 400)
    }

0

Для програмного розширення / згортання AppBarLayout:

fun expandAppBarLayout(expand: Boolean, isAnimationEnabled: Boolean){
    appBarLayout.setExpanded(expand, isAnimationEnabled);
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.