wake-up-neo.net

Wie bricht die Android L Kontakte-App ihre Symbolleiste zusammen?

Ich habe versucht zu reproduzieren, wie die Kontakte-App in Version 5.0 die Symbolleiste reduziert, wenn die Listenansicht gescrollt wird.

Galerie von Screenshots, die die gewünschte Interaktion demonstrieren .__: Beachten Sie, dass die Symbolleiste in Schritten eingeblendet wird, in denen die Suche + letzter Kontakt angezeigt wird, der letzte Kontakt ausgeblendet wird, der letzte Kontakt minimiert wird, die Suche minimiert wird und nur die Registerkarten übrig bleiben.

Bisher habe ich eine Symbolleiste, die über einer Recyclingübersicht in einem LinearLayout steht, und die Symbolleiste wird als Aktionsleiste verwendet, nicht als eigenständiges Element.

Ich kann nicht herausfinden, wie das Berührungsereignis in der Recyclingübersicht abgefangen wird, die Symbolleiste verkleinert werden und das Scrollereignis dann zur Recyclingübersicht zurückkehren kann. Ich habe versucht, die gesamte Sache in eine Scrollansicht zu setzen, aber dann konnte die Recyclingansicht die Höhe nicht richtig berechnen und es wurde kein Inhalt angezeigt. Ich habe versucht, onscroll im Recycling-Fenster zu überschreiben, und habe festgestellt, dass es mich nur beim Start eines Scroll-Ereignisses benachrichtigt und mir die erste sichtbare Karten-ID liefert. 

Der Weg, der richtig aussieht, aber ich kann nicht für mein Leben arbeiten, ist folgende:

getSupportActionBar().setHideOnContentScrollEnabled(true);

Welche gibt zurück:

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

Die Verwendung einer herkömmlichen Aktionsleiste, das Einfügen einer Werkzeugleiste darunter und das Setzen von verdeckten Inhalten, die aktiviert wurden, funktionierte ebenfalls nicht. Durch das Scrollen wurde nie die Ausblendmethode in der Aktionsleiste ausgelöst.

- edit -- Ich konnte hideOnContentScrollEnabled an einer Listenansicht mit einer herkömmlichen Aktionsleiste arbeiten lassen, aber das Verhalten ist nicht dasselbe wie bei der Kontakt-App. Dies ist eindeutig nicht die Methode, die sie verwendet haben. Sie löst einfach .hide () auf der Aktionsleiste aus, wenn ein Fling-Ereignis in einer Listenansicht auftritt. Dies unterscheidet sich deutlich von der Kontakt-App, die die Symbolleiste zusammen mit dem Scroll-Ereignis zieht. .--/bearbeiten -

Also habe ich diese Route aufgegeben, fill_parent auf die Kartenansichtshöhe gestellt und einen Kollaps in der Symbolleiste animiert. Aber wie löse ich es aus, so dass es dem Berührungsereignis folgt und das Berührungsereignis dann an die Recyclingübersicht zurückgibt?

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

Ich habe den Quellcode noch nicht untersucht, aber dieser Kerl scheint das Leben leicht gemacht zu haben und gleichzeitig aufschlussreich zu sein.

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

EDIT

Google hat gerade Android Design Library veröffentlicht. Bitte werfen Sie einen Blick darauf, denn es enthält alle Auswirkungen von reduzierten Symbolleisten und vieles mehr.

17
humblerookie

Nun, ich habe keine Ahnung, wie sie das machen, aber ... warum werfen Sie einen Blick auf den Quellcode? Glücklicherweise ist die Kontakte-App für Android L immer noch Open Source (andere hatten nicht so viel Glück wie Kontakte, wie Mail, was auf L nicht mehr funktioniert, oder Keyboard, das seit dem Start ihres Besitzers nicht mehr aktualisiert wird) Google-Tastatur).

Wie auch immer, hier ist der Quellcode, den Sie sich ansehen sollten: https://github.com/Android/platform_packs_apps_contacts/blob/master/src%2Fcom%2Fandroid%2Fcontacts%2Factivities%2FActionBarAdapter.Java

Beachten Sie die Methode update(boolean skipAnimation) in Zeile 311, die animateTabHeightChange(int start, int end) (Zeile 437) aufruft.

Meine Vermutung ist, dass die ganze Magie dort passiert ;-)

3
jrub

Keine Drittanbieter-Bibliothek ist jetzt erforderlich! Android bietet offiziell eine Bibliothek an. Sie können die Symbolleiste ausblenden und viele andere Verbesserungen vornehmen.

Überprüfen Sie diese Android-Entwickler-Blog

Vergessen Sie nicht, diese Abhängigkeit in Ihre build.gradle-Datei aufzunehmen.

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

2
Apurva

Ab Juni 2015 kann der gewünschte Effekt über das sogenannte CollapsingToolbarLayout der neuen Design-Support-Bibliothek erzielt werden. 

Basierend auf dem Beispielcode hier stelle ich mir Folgendes vor: 

  • die Suchkartenansicht ist der Symbolleiste untergeordnet
  • die Karte für den entgangenen Anruf gehört zur collapsingtoolbar, wobei das collapseMode-Attribut auf Pin gesetzt ist

<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

Ich habe diese Bibliothek gefunden, die genau das zu tun hat, was Sie suchen: https://github.com/kmshack/Android-ParallaxHeaderViewPager und das https://github.com/flavienlaurent/NotBoringActionBar

Sie können das Video abspielen, um das Verhalten zu sehen: https://www.youtube.com/watch?v=sCP-b0a1x5Y

Dies ist möglicherweise nicht die "neue" Standardmethode für ToolBar, aber es kann Ihnen eine Idee geben, indem Sie den Code untersuchen. Es scheint, einen OnScrollListener an den Bildlaufinhalt anzuhängen und dann Änderungen an der Größe der Leiste auszulösen.

1

Die Kontakt-App von Android verfügt nicht über eine einfache Plug-and-Play-Lösung, die Sie in Ihrer eigenen App verwenden können.

Es führt eine vollständige Implementierung durch, und zwar im Wesentlichen auf die gleiche Weise wie bei einer vollständigen Implementierung. Beachten Sie vor dem Blick auf den Code, wie die Ansichten angeordnet sind:

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

Der MultiShrinkScroller ist ein FrameLayout, das das Bildlaufverhalten vermittelt. Der Hauptbestandteil ist jedoch ein LinearLayout. Wenn Sie also die Höhe der höheren Ansichten reduzieren, scrollen Sie die unteren Ansichten nach oben. 

Die Schlüsseldatei für die Implementierung lautet:

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(); und updateHeaderTextSizeAndMargin(); behandeln die Änderung von Farbton und Text, wenn sie zusammengeklappt werden, sodass sie sich in das Aussehen und Verhalten einer normalen ActionBar/ToolBar verwandelt.

Sie können sich die MultiShrinkScroller-Datei selbst holen und für Ihre eigene Verwendung anpassen. Heutzutage gibt es wahrscheinlich einfachere Implementierungen (einschließlich derjenigen aus der Design-Bibliothek von Android).

0
David Liu

Für mich https://mzgreen.github.io/2015/06/23/How-to-hideshow-Toolbar-when-list-is-scrolling%28part3%29/ hat geholfen. Einen Quellcode finden Sie hier: https://github.com/mzgreen/HideOnScrollExample/tree/master/app/src/main .

Eine RecycleView in Ihrem Layout sollte folgendermaßen aussehen:

<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" />

Beachten Sie, dass nach dem Starten einer Anwendung 2 Symbolleisten (Aktionsleiste und Symbolleiste) angezeigt werden. Also in deiner Aktivität. Java solltest du so schreiben:

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

Die Symbolleiste wird wie folgt angepasst: https://stackoverflow.com/a/26548766/2914140 . Ich meine, es erscheint ohne Titel und alle anderen Elemente, sodass Sie sie in ein Layout einfügen können.

0
CoolMind