Как правильно скрыть и показать панель действий с помощью нового API библиотеки дизайна?

Фон

Предположим, у меня есть эти элементы в действии:

  • панель действий (на самом деле панель инструментов)
  • вкладки (используя TabLayout )
  • ViewPager с фрагментами.
  • каждый фрагмент имеет ListVIew/RecyclerView.

Я хочу иметь такое же поведение, как и во многих приложениях, чтобы при прокрутке панель действий скрывалась или отображалась.

Прекрасным примером является то, как работает прокрутка Play Store.

Что-то вроде этого (но с ListView во фрагментах, конечно):

введите описание изображения здесь

Эта проблема

Я нашел библиотеку "Android-ObservableScrollView", которая показывает, как сделать это для многих типов прокручиваемых представлений, но он не обрабатывает случай использования нового TabLayout (плюс у него есть проблемы), как показано в более новых примерах, таких как cheesesquare.

В новом API библиотеки дизайна (показанном на примере «cheesesquare») он более автоматизирован, поэтому вам не нужно создавать столько шаблонов для обработки прокрутки и того, что с ней делать.

Что-то подобное:

<android.support.v4.widget.DrawerLayout

  <android.support.design.widget.CoordinatorLayout>

    <android.support.design.widget.AppBarLayout>

      <android.support.v7.widget.Toolbar
       app:layout_scrollFlags="scroll|enterAlways"/>

      <android.support.design.widget.TabLayout/>

    </android.support.design.widget.AppBarLayout>

    <android.support.v4.view.ViewPager
     app:layout_behavior="@string/appbar_scrolling_view_behavior" />

    <android.support.design.widget.FloatingActionButton/>

  </android.support.design.widget.CoordinatorLayout>

  <android.support.design.widget.NavigationView/>

</android.support.v4.widget.DrawerLayout>

Эта иерархия обещает, что закусочные будут ниже FAB, и что панель действий будет автоматически анимирована (показана/скрыта) на основе внутреннего RecyclerView фрагментов.

Дело в том, что это работает только с RecyclerView, а не с ListView.

Поскольку они довольно сложные, их будет очень сложно преобразовать в RecyclverViews.

Вопрос

Что нужно сделать, чтобы описанный выше механизм работал и для ListView?

Есть ли способ сделать это? Если да, то как?


РЕДАКТИРОВАТЬ: к сожалению, похоже, что Google не будет поддерживать такое поведение для ListView, а только для RecyclerView и NestedScrollView (написано о здесь).

Поэтому я попытался использовать библиотеку "Android-ObservableScrollView". , но у него много проблем с прокруткой, в том числе с прокруткой.

Теперь я решил предоставить Android-ParallaxHeaderViewPager . Может ли кто-нибудь сказать мне, как заставить его работать в текущем сценарии? Это вообще возможно?


РЕДАКТИРОВАТЬ: я все-таки решил перейти на RecyclerView. Тем не менее, все образцы, которые я пробовал, показывают проблему: при остановке прокрутки панель действий (и, возможно, даже FAB) может оставаться усеченной, в отличие от магазина игр, где она будет анимирована либо скрыта, либо показана.

РЕДАКТИРОВАТЬ: кажется, мне нужно использовать setExpanded при наличии IDLE для onScrollStateChanged . вопрос в том, как решить, когда расширяться, а когда сворачиваться.


person android developer    schedule 13.08.2015    source источник
comment
Я не вижу, где вы могли бы использовать ListView, глядя на анимацию. Вы хотите использовать ScrollView вместо этого для прокрутки вверх/вниз? Хотя это была бы другая проблема.   -  person The Original Android    schedule 14.08.2015
comment
@TheOriginalAndroid Внутри фрагментов ViewPager есть ListView. Анимированный gif - это просто пример. Вы можете посмотреть в игровом магазине, если хотите увидеть эту комбинацию.   -  person android developer    schedule 14.08.2015
comment
Я не знаю Android-ObservableScrollView. Для ваших нужд вы можете просто использовать ListView в пейджере? И обнаруживайте события прокрутки в ListView. Когда они обнаружены, вы можете изменить видимость панели действий на GONE. Я полагал, что вы хорошо знаете Android и уже имеете мнение по этому поводу.   -  person The Original Android    schedule 15.08.2015
comment
@TheOriginalAndroid Именно так я делал это раньше, но у него есть проблемы: он не перемещает панель действий при прокрутке, а ListView должен увеличиваться и уменьшаться в зависимости от панели действий, но когда вы это делаете, это мешает сенсорные события тоже (потому что координаты меняются). Возможное решение состояло в том, чтобы иметь пустой заголовок для ListView, но это может отображаться в некоторых случаях, плюс это не будет работать, когда есть также представление вкладок.   -  person android developer    schedule 15.08.2015


Ответы (3)


это хороший обходной путь, но он все еще сильно отличается от того, что показывает Play Store:

для каждого фрагмента вызовите что-то вроде этого:

    recyclerView.addOnScrollListener(new OnScrollListener() {
        @Override
        public void onScrollStateChanged(final RecyclerView recyclerView, final int newState) {
            super.onScrollStateChanged(recyclerView, newState);
            ((MainActivity) getActivity()).onScrollStateChanged(recyclerView, newState);
        }

        @Override
        public void onScrolled(final RecyclerView recyclerView, final int dx, final int dy) {
            super.onScrolled(recyclerView, dx, dy);
            ((MainActivity) getActivity()).onScrolled(recyclerView, dx,dy);
        }
    });

для хостинговой деятельности:

public void onScrollStateChanged(final RecyclerView recyclerView, final int newState) {
    switch (newState) {
        case RecyclerView.SCROLL_STATE_IDLE:
            mAppBarLayout.setExpanded(mLastDy <= 0, true);
            mLastDy = 0;
            break;
    }
}

public void onScrolled(final RecyclerView recyclerView, final int dx, final int dy) {
    mLastDy = dy == 0 ? mLastDy : dy;
}

Тем не менее, если кто-то знает, как заставить его работать хорошо (используя ListView или RecyclerView для фрагментов), как в Play-Store и других приложениях, напишите, пожалуйста.

person android developer    schedule 19.08.2015
comment
он по-прежнему использует recyclerview вместо списка. Чем он вам пригодился? - person Shreyash Mahajan; 19.08.2015
comment
К сожалению, после всего времени, которое я потратил на ListView, я зашел в тупик, так как все, что я пробовал, имело ошибки, поэтому я изменил вопрос и теперь пытаюсь использовать RecyclerView. Это не так хорошо, как в Play Store, но пока я буду использовать этот обходной путь, так как я не нашел там хорошего образца. - person android developer; 19.08.2015
comment
В Google Play есть recyclerview. Так что лучше пойти с этим. Также вы можете проверить приведенный мной пример, чтобы он отлично работал с recyclerview. Теперь дело за вами, как двигаться дальше. - person Shreyash Mahajan; 19.08.2015
comment
@iDroidExplorer Я вернусь к этому через несколько недель, так как мне не удалось сделать все это за один день (как я уже писал, у нас очень сложные listViews). Извините и спасибо за попытку помочь. - person android developer; 26.08.2015
comment
нет проблем друг. Я уже сделал то же самое для одного из моих приложений. Это также работает нормально, поэтому предлагаю вам пойти с этим. Да, вам, возможно, придется обновить часть кода, чтобы справиться с упомянутой вами проблемой. Но он работает нормально. Вы должны установить это приложение и проверить начальный экран стены этого приложения. play.google.com/store/apps/details?id= com.thefancy.app - person Shreyash Mahajan; 27.08.2015

API нового дизайна предназначен только для новых компонентов. Если этот компонент будет поддерживать более старые версии, он должен работать и для более старых версий.

Относительно вашей проблемы: я не знаю, использовали ли вы предложенный библиотека или нет. Но в моем случае это работает хорошо. Я знаю, что это очень старая библиотека, и вам, должно быть, придется использовать с ней список. Вы не можете реализовать recyclerview с этим. Но так как я хочу иметь очень гибкий и плавный эффект, я попробовал его, и он работает очень хорошо.

Вы также можете сделать плавную прокрутку панели инструментов с прокруткой Listview, а также сделать эффект паралакса, как вы видели в примере.

Посмотрите на эти изображения для эффекта, который я реализовал для своего приложения. Отметка красным цветом — это моя панель инструментов приложения.

Изображение в развернутом виде:

введите здесь описание изображения

Изображение в свернутом виде:

введите здесь описание изображения

Я предлагаю попробовать эту библиотеку для вашей проблемы, связанной с панелью действий, если вы не думаете изменить свой список на recyclerview. Но если вы хотите изменить свой список на recyclerview, вы можете использовать новый API дизайна для такого эффекта.

Дайте мне знать, если я могу помочь вам больше в этом случае.

Искренне,

Шреяш

Обновленный ответ

Я предполагаю, что вам нужно что-то вроде ЭТО.

Если это то, что вы хотите, вам следует обратиться к этому библиотека и реализовать так.

Пожалуйста, обратитесь к части 1, части 2 и части 3 для аналогичного эффекта.

Позвольте мне знать, если вам нужно что-нибудь еще.

person Shreyash Mahajan    schedule 18.08.2015
comment
Я пробую это сейчас, но ему не хватает очень важной вещи: анимации панели действий, когда прокрутка простаивает. Мне нужно, чтобы он вел себя как в Play Маркете: не может быть ситуации, что вы не касаетесь экрана, а показывается только половина заголовка. Отображаются либо вкладки, либо панель вкладок и действий. Только при прокрутке он должен показывать их полупрокручивающиеся состояния. Я попытался сейчас добавить onScrollStateChanged и добавить туда анимацию, но onScroll пытается начать с неправильной позиции из-за того, как он вычисляет позицию прокрутки (что также неправильно) - person android developer; 18.08.2015
comment
Кроме того, еще одна проблема заключается в том, что POC не изменяет размер панели действий, когда вы не находитесь в верхней части списка. Мне нужно решить эти 2 проблемы... :( - person android developer; 18.08.2015
comment
И даже у самого образца есть проблема: при прокрутке между фрагментами прокрутка сбрасывается и может даже показывать пустую область вверху. - person android developer; 18.08.2015
comment
@androiddeveloper Пожалуйста, загрузите свой проект на github и дайте мне доступ к нему для форка и обновления. Это не так, я могу это сделать. На самом деле, здесь у меня нет доступа к дропбоксу или гугл диску. Я могу получить его с github, если хотите, а также обновить его. - person Shreyash Mahajan; 19.08.2015
comment
Уфф, ладно. Я понял, что ты хочешь. - person Shreyash Mahajan; 19.08.2015
comment
@androiddeveloper, проверьте мой обновленный ответ. Я надеюсь, вам понравится. - person Shreyash Mahajan; 19.08.2015
comment
Пример, который вы показали, использует RecyclerView, а я спросил о ListView. Кроме того, это не работает, как в магазине игр, так как я могу легко сделать панель действий наполовину показанной (усеченной), как в магазине игр, она либо скрыта, либо отображается, когда вы прекращаете прокрутку. - person android developer; 19.08.2015
comment
Даже если он поддерживает ListView (чего нет), у него все еще есть проблема: github.com/ mzgreen/HideOnScrollExample/issues/9 . Я думаю, что он должен использовать onScrollStateChanged и setExpanded на основе информации о прокрутке. - person android developer; 19.08.2015
comment
@androiddeveloper похоже, что вы не просмотрели механизм, который автор использует для создания этого эффекта. Вы должны попробовать это. И поделитесь своими баллами, если вы столкнулись с какой-либо проблемой в любой строке. - person Shreyash Mahajan; 19.08.2015
comment
Извините, пожалуйста, используйте часть 2 для того же - person Shreyash Mahajan; 19.08.2015
comment
Часть 2 тоже глючит. Опять же, я хочу, чтобы у меня было такое же поведение, как в Play Store, без проблем. - person android developer; 19.08.2015
comment
@androiddeveloper Я только что проверил. Вроде нормально работает. Я не знаю, с какой проблемой вы столкнулись. В любом случае, я уверен, что это сработает для вас, но все же, если вы обнаружите, что решение не работает для вас, вам придется сделать свое собственное. Вот что я могу сказать. - person Shreyash Mahajan; 19.08.2015
comment
Проверьте здесь: github.com/mzgreen/HideOnScrollExample/issues/9 . Он может показывать пустое пространство. - person android developer; 19.08.2015
comment
хммм, я думаю, вам нужно потренироваться на нем. Я уже решил эту проблему в моем случае, и она отлично работает, как я хочу. Вы можете проверить модное приложение для той же ссылки. Вы должны попытаться обновить код и решить его. - person Shreyash Mahajan; 19.08.2015
comment
К сожалению, похоже, мне придется преобразовать все в RecyclerView, так как мы отказались от идеи использовать для этого ListView. - person android developer; 28.08.2015

Основываясь на решении разработчика @android, которое иногда расширяет панель приложения, когда список полностью прокручен, я внес небольшое изменение, расширяя или сворачивая список в зависимости от прокручиваемой суммы (если он больше высоты заголовка, расширьте его).

mHeaderHeight = getResources().getDimensionPixelSize(R.dimen.appbar_height);

mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
    @Override
    public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
        super.onScrollStateChanged(recyclerView, newState);
        switch (newState) {
            case RecyclerView.SCROLL_STATE_IDLE:
                mAppBar.setExpanded(mScrolledAmount < mHeaderHeight , true);
                break;
        }
    }

    @Override
    public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
        super.onScrolled(recyclerView, dx, dy);
        mScrolledAmount += dy;
    }
});

РЕДАКТИРОВАТЬ: Что работает еще лучше для меня, так это иметь разные пороги для расширения и свертывания

     switch (newState) {
            case RecyclerView.SCROLL_STATE_IDLE:
                if (mScrolledAmount < 50){
                    mAppBar.setExpanded(true , true);
                }
                if (mScrolledAmount > mHeaderHeight) {
                    mAppBar.setExpanded(false, true);
                }
                break;
        }
person AntPachon    schedule 26.08.2015
comment
Выглядит лучше, но мне пришлось перейти в другую тему. Мне нужно будет проверить это снова, когда я вернусь к этому вопросу. А пока поставьте +1 за усилия. - person android developer; 26.08.2015