web-dev-qa-db-fra.com

Comment l'application Android L contacts réduit-elle sa barre d'outils?

J'ai essayé de reproduire la façon dont l'application Contacts de la version 5.0 réduit la barre d'outils lorsque la vue liste défile.

_ { Galerie de captures d'écran illustrant l'interaction souhaitée } _ Notez la réduction de la barre d'outils par étapes. Elle affiche la recherche + le dernier contact, le dernier contact fondu, réduit le dernier contact, réduit la recherche et ne laisse que les onglets.

Jusqu'à présent, j'ai une barre d'outils située au-dessus d'une table de recyclage dans un LinearLayout, et la barre d'outils est utilisée comme une barre d'action, pas autonome.

Je n'arrive pas à comprendre comment intercepter l'événement tactile sur la vue recyclée et le réduire ainsi que la barre d'outils, puis renvoyer l'événement de défilement à la vue recyclée. J'ai essayé de tout mettre dans un scrollview, mais ensuite, recyclerview ne pouvait pas calculer correctement sa hauteur et n'affichait aucun contenu. J'ai essayé de contourner onscroll sur recyclerview et j'ai constaté qu'il ne m'avertirait que lorsqu'un événement de défilement commencerait et me fournissait le premier identifiant de carte visible. 

Voici ce qui semble bien, mais je ne peux pas travailler pendant toute ma vie, est la suivante:

getSupportActionBar().setHideOnContentScrollEnabled(true);

Qui retourne:

 Caused by: Java.lang.UnsupportedOperationException: Hide on content scroll is not supported in this action bar configuration.

L'utilisation d'une barre d'actions traditionnelle, placer une barre d'outils en dessous et définir les liens masqués ne fonctionnaient pas. Le défilement n'a jamais déclenché la méthode de masquage de la barre d'actions.

- edit -- J'ai pu obtenir hideOnContentScrollEnabled sur une liste avec une barre d’actions traditionnelle, mais le comportement n’est pas le même que celui de l’application Contacts. Ce n'est clairement pas la méthode qu'ils ont utilisée - cela déclenche simplement .hide () dans la barre d'actions lorsqu'un événement fling se produit dans une liste, ce qui est sensiblement différent de l'application Contacts, qui entraîne la barre d'outils avec l'événement de défilement .-- /modifier --

J'ai donc abandonné cette route, mis fill_parent sur la hauteur de la vue de la carte et animé une réduction dans la barre d'outils. Mais comment puis-je le déclencher pour qu'il suive l'événement tactile, puis le renvoie à la vue de recyclage?

activity_main.xml

<LinearLayout
    xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:layout_width="match_parent"
    Android:layout_height="wrap_content"
    Android:orientation="vertical"
    >

    <Android.support.v7.widget.Toolbar
        xmlns:Android="http://schemas.Android.com/apk/res/Android"
        Android:id="@+id/toolbar"
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content"
        Android:minHeight="?android:attr/actionBarSize"
        Android:background="@color/colorPrimary"
        />

    <fragment Android:name="me.myapplication.FragmentTab"
          Android:id="@+id/tab_fragment"
          Android:layout_width="match_parent"
          Android:layout_height="wrap_content" />
</LinearLayout>

fragment_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    Android:gravity="center_horizontal"
    Android:orientation="vertical"
    Android:padding="8dp"
    Android:background="#eeeeee"
    >

    <Android.support.v7.widget.RecyclerView
        Android:id="@+id/recycler_view"
        Android:layout_width="match_parent"
        Android:layout_height="fill_parent"
        />

</LinearLayout>

styles.xml

...
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
...

MainActivity.Java

Toolbar toolbar = (Toolbar)findViewById(R.id.toolbar);

// Disable the logo in the actionbar, as per material guidelines
toolbar.getMenu().clear();
toolbar.setTitle("My toolbar");
setSupportActionBar(toolbar);
33
Preston

Je n'ai pas encore enquêté sur le code source, mais ce gars semble avoir rendu la vie facile mais éclairante.

https://github.com/ksoichiro/Android-ObservableScrollView

MODIFIER

Google vient de publier Android Design Library . S'il vous plaît jetez un oeil car il contient tous les effets de la réduction des barres d'outils et bien plus encore.

17
humblerookie

Aucune bibliothèque tierce n'est requise maintenant! Android fournit officiellement une bibliothèque. Vous pouvez réduire la barre d’outils et effectuer de nombreux autres réglages.

Check this Blog du développeur Android

Et n'oubliez pas d'ajouter cette dépendance dans votre fichier build.gradle.

compile 'com.Android.support:design:22.2.0'

2
Apurva

À compter de juin 2015, l'effet souhaité peut être obtenu via le fichier CollapsingToolbarLayout de la nouvelle bibliothèque de support de conception. 

Basé sur l'exemple de code ici , je suppose que: 

  • la recherche cardview est l'enfant de la barre d'outils
  • la vue d'appel manquée cardview appartient à la barre d'outils déroulante avec l'attribut collapseMode défini sur pin

<Android.support.design.widget.AppBarLayout
    Android:id="@+id/appbar"
    Android:layout_width="match_parent"
    Android:layout_height="112dp"
    Android:fitsSystemWindows="true"
    Android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

    <Android.support.design.widget.CollapsingToolbarLayout
        Android:layout_width="match_parent"
        Android:layout_height="match_parent"
        Android:minHeight="?attr/actionBarSize"
        Android:fitsSystemWindows="true"
        app:layout_scrollFlags="scroll|enterAlwaysCollapsed|enterAlways">

        <Android.support.v7.widget.Toolbar
            Android:id="@+id/toolbar"
            Android:layout_width="match_parent"
            Android:layout_height="?attr/actionBarSize"
            Android:background="?attr/colorPrimary"
            Android:fitsSystemWindows="false"
            app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
            app:layout_collapseMode="pin"
            app:layout_scrollFlags="scroll|enterAlways">

            <!-- Search layout -->
            <Android.support.v7.widget.CardView   
            </Android.support.v7.widget.CardView>

        </Android.support.v7.widget.Toolbar>

        <!-- Last call card view-->
        <Android.support.v7.widget.CardView
            app:layout_collapseMode="pin">               
        </Android.support.v7.widget.CardView>

    </Android.support.design.widget.CollapsingToolbarLayout>

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

<LinearLayout
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    Android:orientation="vertical"
    app:layout_behavior="@string/appbar_scrolling_view_behavior">

    <Android.support.design.widget.TabLayout
        Android:id="@+id/tabs"
        Android:layout_width="match_parent"
        Android:layout_height="48dp"
        Android:background="@color/primary_color"
        app:layout_scrollFlags="scroll"/>

    <Android.support.v4.view.ViewPager
        Android:id="@+id/viewpager"
        Android:layout_width="match_parent"
        Android:layout_height="match_parent" />

</LinearLayout>

2
appoll

J'ai trouvé cette bibliothèque qui semble faire ce que vous cherchez: https://github.com/kmshack/Android-ParallaxHeaderViewPager and this https://github.com/flavienlaurent/NotBoringActionBar

Vous pouvez lire la vidéo pour voir le comportement suivant: https://www.youtube.com/watch?v=sCP-b0a1x5Y

Ce n'est peut-être pas la "nouvelle" méthode standard de le faire avec ToolBar, mais cela peut vous donner une idée en inspectant le code. Il semble attacher un OnScrollListener au contenu défilant puis déclencher des changements sur la taille de la barre.

1
Alécio Carvalho

L'application Contact d'Android ne propose pas de solution plug-and-play facile à utiliser dans votre propre application.

Il effectue une mise en œuvre complète, essentiellement de la même manière que si vous l'implémentiez à partir de zéro. Pour le contexte, avant de regarder le code, gardez à l’esprit la manière dont les vues sont présentées:

https://github.com/Android/platform_packages_apps_contacts/blob/Lollipop-release/res/layout/quickcontact_activity.xml

MultiShrinkScroller est un FrameLayout qui modifie le comportement de défilement, mais le principal élément est un LinearLayout. Par conséquent, réduire la hauteur des vues les plus hautes fera "défiler" les vues les plus basses. 

Le fichier clé pour l'implémentation est celui-ci:

https://github.com/Android/platform_packages_apps_contacts/blob/Lollipop-release/src/com/Android/contacts/widget/MultiShrinkScroller.Java

public void scrollTo(int x, int y) {
    final int delta = y - getScroll();
    boolean wasFullscreen = getScrollNeededToBeFullScreen() <= 0;
    if (delta > 0) {
        scrollUp(delta);
    } else {
        scrollDown(delta);
    }
    updatePhotoTintAndDropShadow();
    updateHeaderTextSizeAndMargin();
    //... other stuff
}

private void scrollUp(int delta) {

    // Collapse higher views first
    if (getTransparentViewHeight() != 0) {
        final int originalValue = getTransparentViewHeight();
        setTransparentViewHeight(getTransparentViewHeight() - delta);
        setTransparentViewHeight(Math.max(0, getTransparentViewHeight()));
        delta -= originalValue - getTransparentViewHeight();
    }

    // Shrink toolbar as needed
    final ViewGroup.LayoutParams toolbarLayoutParams
            = mToolbar.getLayoutParams();
    if (toolbarLayoutParams.height > getFullyCompressedHeaderHeight()) {
        final int originalValue = toolbarLayoutParams.height;
        toolbarLayoutParams.height -= delta;
        toolbarLayoutParams.height = Math.max(toolbarLayoutParams.height,
                getFullyCompressedHeaderHeight());
        mToolbar.setLayoutParams(toolbarLayoutParams);
        delta -= originalValue - toolbarLayoutParams.height;
    }

    // Finally, scroll content if nothing left to shrink
    mScrollView.scrollBy(0, delta);
}

updatePhotoTintAndDropShadow(); et updateHeaderTextSizeAndMargin(); gèrent le changement de nuance et de texte au fur et à mesure qu'il se réduit, de sorte qu'il se transforme en l'apparence d'une ActionBar/ToolBar normale.

Vous pouvez récupérer le fichier MultiShrinkScroller lui-même et l'adapter à votre usage personnel, mais il existe probablement des implémentations plus simples de nos jours (y compris celles de la bibliothèque de conception d'Android).

0
David Liu

Pour moi https://mzgreen.github.io/2015/06/23/How-to-hideshow-Toolbar-when-list-is-scrolling%28part3%29/ a aidé. Un code source se trouve ici: https://github.com/mzgreen/HideOnScrollExample/tree/master/app/src/main .

Un RecycleView dans votre mise en page doit ressembler à:

<Android.support.v7.widget.RecyclerView
    Android:id="@+id/recyclerView"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    Android:layout_gravity="fill_vertical"
    app:layout_behavior="@string/appbar_scrolling_view_behavior" />

Notez qu'après le démarrage d'une application, 2 barres d'outils apparaissent (barre d'actions et barre d'outils). Donc, dans votre activité.Java, vous devriez écrire ainsi:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // Hide ActionBar.
    supportRequestWindowFeature(WindowCompat.FEATURE_ACTION_BAR);
    getSupportActionBar().hide();
    setContentView(R.layout.your_activity_layout);
    ...

La barre d’outils est personnalisée comme indiqué ci-dessous: https://stackoverflow.com/a/26548766/2914140 . Je veux dire, il apparaît sans titre et aucun autre élément, vous pouvez donc les ajouter dans une mise en page.

0
CoolMind