33

Ich habe versucht, die Art und Weise zu reproduzieren, in der die App "Kontakte" in Version 5.0 die Symbolleiste zusammenklappt, wenn die Listenansicht gescrollt wird.Wie kollidiert die Android L Kontakte App ihre Symbolleiste?

Gallery of screenshots demonstrating the desired interaction Beachten Sie den Kollaps der Symbolleiste in Stufen, wo sie Suche + letzten Kontakt anzeigt, letzten Kontakt blendet, letzten Kontakt zusammenbricht, Suche einbricht und nur die Registerkarten übrig lässt.

Bis jetzt habe ich eine Symbolleiste oberhalb einer Recyclerview in einem LinearLayout, und die Symbolleiste wird als Aktionsleiste, nicht Standalone verwendet.

Ich kann nicht herausfinden, wie Sie das Touch-Ereignis in der Recycler-Ansicht abfangen und die Symbolleiste schrumpfen lassen und dann das Scroll-Ereignis an die Recycler-Ansicht zurückgeben. Ich habe versucht, das Ganze in eine Scrollview zu stellen, aber dann konnte die Recyclerview ihre Höhe nicht richtig berechnen und zeigte keinen Inhalt. Ich habe versucht, onscroll auf der Recycler-Ansicht zu übergehen und festgestellt, dass es mich nur benachrichtigt, wenn ein Scroll-Ereignis gestartet wird, und mir die erste sichtbare Karten-ID zur Verfügung stellen.

Die Art und Weise, die gut aussieht, aber ich kann für das Leben von mir nicht bekommen arbeiten, ist dies:

getSupportActionBar().setHideOnContentScrollEnabled(true); 

Welche zurück:

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

ein traditionelles ActionBar Verwendung, ein Putting Toolbar darunter, und die Einstellung hideoncontentscrollenabled hat ebenfalls nicht funktioniert, das Scrollen hat nie die Methode hide in der Aktionsleiste ausgelöst.

- bearbeiten - Ich konnte HideOnContentScrollEnabled arbeiten auf einer Listview mit einer traditionellen Aktionsleiste, aber das Verhalten ist nicht das gleiche wie die Kontakte App. Dies ist eindeutig nicht die Methode, die sie verwendet haben - es löst einfach .Hide() auf der Aktionsleiste aus, wenn ein Flingereignis in einer Listenansicht auftritt, was sich deutlich von der Kontaktanwendung unterscheidet, die die Symbolleiste zusammen mit dem Bildlaufereignis zieht. -/edit -

Also habe ich diese Route aufgegeben, fill_parent auf die cardview height gesetzt und einen Kollaps auf der Symbolleiste animiert. Aber wie trigge ich es so an, dass es dem Touch-Ereignis folgt und dann das Touch-Ereignis an die Recycler-Ansicht 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"> 
... 

Hauptaktivität. 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); 
+0

Die App [Google I/O 2014] (https://github.com/google/iosched) verfügt über eine ähnliche Funktion in der Sitzungsansicht. Sie könnten dort einige Ideen finden. –

+0

Danke, ich habe mir den Quellcode und den Effekt angeschaut, aber die iosched-App ist eine andere Art von Effekt und wird auf andere Weise erreicht. Im Grunde animiert es einen 'Verstecken'-Effekt auf der Aktionsleiste, wenn onScroll aufgerufen wird, der nur den ersten Block von Elementen aufnimmt und den Finger nicht wirklich verfolgen kann. Derselbe Effekt kann über setHideOnContentScrollEnabled() angewendet werden. Die Kontakt-App scheint jedoch das gesamte Ansichtsfenster nach oben zu verschieben, bevor das Bildlaufereignis in die Bildlaufansicht zurückkehrt. – Preston

+0

Aus meinem Kopf - was wäre, wenn Sie nicht versuchen würden, die ListView/RecyclerView-Touch-Ereignisse abzufangen, sondern Ihre Ansicht mit einem GestureDetector überlagern und seine bewegten Ereignisse an die rechten Widgets weiterleiten, um sie entsprechend zu verkleinern/zu scrollen? Nur eine Idee, habe das überhaupt nicht ausprobiert. –

Antwort

17

;-) ich den Quellcode noch nicht untersucht haben, aber dieser Kerl scheint gemacht zu haben das Leben einfach noch erhellend.

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

EDIT

Google hat Android Design Library gerade freigegeben. Bitte werfen Sie einen Blick darauf, wie es alle Effekte von kollabierenden Symbolleisten und vieles mehr enthält.

+0

Sie könnten es in diesem Fall upvote :) – humblerookie

+0

Natürlich, nur tat :) – Sandra

+1

Offizielles Beispiel: https://github.com/chrisbanes/cheesquare – Roel

1

ich diese Bibliothek gefunden, die zu tun scheint, was Sie suchen: https://github.com/kmshack/Android-ParallaxHeaderViewPager und diese https://github.com/flavienlaurent/NotBoringActionBar

Sie das Video, das Verhalten zu sehen, spielen kann: https://www.youtube.com/watch?v=sCP-b0a1x5Y

Es könnte nicht Dies ist die "neue" Standardmethode, die mit ToolBar ausgeführt wird. Sie erhalten jedoch möglicherweise eine Idee, indem Sie den Code überprüfen. Es scheint einen OnScrollListener an den Scroll-Inhalt anzuhängen und dann Änderungen an der Größe des Balkens auszulösen.

3

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

Wie auch immer, hier ist der Quellcode Ich glaube, Sie sehen sollten: https://github.com/android/platform_packages_apps_contacts/blob/master/src%2Fcom%2Fandroid%2Fcontacts%2Factivities%2FActionBarAdapter.java

Notiere die Methode update(boolean skipAnimation) in Zeile 311, die animateTabHeightChange(int start, int end) nennt (Linie 437).

Meine Vermutung ist, alles geht wie es

2

Ab Juni 2015 kann Ihr gewünschter Effekt über die so genannte CollapsingToolbarLayout der neuen Design-Support-Bibliothek erreicht werden.

Basierend auf dem Beispielcode here, mich herauszufinden, dass:

  • die Suche cardview Kind der Symbolleiste
  • ist
  • der verpasste Anruf cardview mit dem collapseMode Attribute auf die collapsingtoolbar gehört gesetzt
  • zu

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

+0

meine Frage ist hier können Sie herausfinden, was das Problem ist: http: // Stackoverflow.com/questions/30913211/toolbar-nicht-scrollen-wenn-verwenden-collapsing-toolbar-effect –

2

Es ist keine externe Bibliothek erforderlich! Android stellt offiziell eine Bibliothek zur Verfügung. Sie können die Symbolleiste minimieren und viele andere Optimierungen vornehmen.

prüfen diese android-developer's blog

Und vergessen Sie nicht, diese Abhängigkeit in Ihrer build.gradle Datei hinzuzufügen.

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

0

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

A 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 eine Anwendung 2 Symbolleiste angezeigt (ActionBar und Symbolleiste) nach dem Start. Also in Ihrem activity.java sollten Sie schreiben so:

@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 angepasst wird, wie hier gezeigt: https://stackoverflow.com/a/26548766/2914140. Ich meine, es erscheint ohne Titel und andere Elemente, so dass Sie sie in einem Layout hinzufügen können.

0

Die Android Contact App hat keine einfache Plug-and-Play-Lösung, die Sie für Ihre eigene App verwenden können.

Es macht eine vollständige Implementierung, im Wesentlichen so, wie Sie es tun würden, wenn Sie es von Grund auf neu implementieren würden. Für Kontext, bevor Blick auf dem Code, denken Sie daran, wie die Ansichten sind gelegt:

https://github.com/android/platform_packages_apps_contacts/blob/lollipop-release/res/layout/quickcontact_activity.xml

Der MultiShrinkScroller ein FrameLayout ist, die das Scrollen Verhalten Zwischenprodukte, aber das Haupt Zeug ist in einem Linearlayout, so reduziert Die Höhe der höheren Ansichten "scrollt" die unteren Ansichten nach oben.

Die Schlüsseldatei für die Implementierung ist diese:

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(); die Änderung in der Tönung und Text handhaben, da es so zusammengebrochen wird, dass es in das Aussehen und das Gefühl verwandelt sich von eine reguläre ActionBar/ToolBar.

Sie könnten die MultiShrinkScroller-Datei selbst abrufen und für Ihre eigenen Zwecke anpassen, aber es gibt heutzutage wahrscheinlich einfachere Implementierungen (einschließlich der aus der Designbibliothek von Android).

Verwandte Themen