33

Ho cercato di riprodurre il modo in cui l'app Contatti sulla versione 5.0 comprime la barra degli strumenti quando scorre la visualizzazione elenco.In che modo l'app per contatti Android L riduce la barra degli strumenti?

Gallery of screenshots demonstrating the desired interaction nota il crollo della barra degli strumenti in più fasi, in cui viene visualizzato ricerca + ultimo contatto, svanisce ultimo contatto, crolla ultimo contatto, crolla di ricerca, lasciando solo le linguette.

Finora, ho una barra degli strumenti posta sopra una panoramica di riciclo in un LinearLayout e la barra degli strumenti è utilizzata come barra di azione, non autonoma.

Non riesco a capire come intercettare l'evento di tocco sul recyclerview e farlo restringere la barra degli strumenti, quindi restituire l'evento di scorrimento a recyclerview. Ho provato a mettere l'intera cosa in una scrollview, ma poi il recyclerview non ha potuto calcolare correttamente l'altezza e non ha mostrato alcun contenuto. Ho provato a sovrascrivere onscroll sul recyclerview e ho scoperto che mi avviserà solo quando un evento di scorrimento è iniziato e mi fornirà il primo ID visibile della carta.

Il modo in cui guarda a destra, ma non riesco a lavorare per la vita di me, è questo:

getSupportActionBar().setHideOnContentScrollEnabled(true); 

che restituisce:

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

Utilizzando un ActionBar tradizionali, mettendo un barra degli strumenti sotto di esso, e l'impostazione hideoncontentscrollenabled anche non ha funzionato, lo scorrimento non ha mai attivato il metodo Nascondi sulla barra di azione.

- edit - Sono stato in grado di ottenere hideOnContentScrollEnabled lavorando su un listview con una barra di azione tradizionale, ma il comportamento non è lo stesso dell'app Contatti. Questo non è chiaramente il metodo che hanno usato, ma semplicemente fa scattare .hide() sulla barra di azione quando si verifica un evento di fling su un listview, che è notevolmente diverso dall'app dei contatti, che trascina la barra degli strumenti insieme all'evento di scorrimento. -/modifica -

Così ho abbandonato questa strada, e mettere fill_parent dall'altezza CardView, e animato un crollo sulla barra degli strumenti. Ma come faccio a farlo in modo che segua l'evento touch e poi restituisca l'evento tattile al recyclerview?

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

L'app [Google I/O 2014] (https://github.com/google/iosched) ha una funzionalità simile nella sua vista sessione. Potresti trovare alcune idee lì. –

+0

Grazie, ho esaminato il codice sorgente e l'effetto, ma l'app iosched ha un diverso tipo di effetto e viene raggiunta in un modo diverso. In pratica, anima un tipo di effetto "nascondi" sulla barra di azione quando viene chiamato onScroll, che prende solo il primo blocco di elementi e non può tracciare realmente il dito. Lo stesso effetto può essere applicato tramite setHideOnContentScrollEnabled(). L'app contatti sembra invece scorrere verso l'alto l'intera finestra prima di riportare l'evento di scorrimento alla vista scorrevole. – Preston

+0

Fuori dalla mia testa - cosa succede se non provi ad intercettare gli eventi touch di ListView/RecyclerView, ma sovrapponi la vista con GestureDetector e instradi gli eventi spostati mentre si toccano i widget giusti per ridurli/scorrerli in modo appropriato? Solo un'idea, non ho provato affatto. –

risposta

17

Non ho ancora studiato il codice sorgente, ma questo ragazzo sembra aver reso la vita semplice ma illuminante.

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

EDIT

Google ha appena rilasciato Android Design Library. Si prega di dare un'occhiata in quanto contiene tutti gli effetti di barre degli strumenti di compressione e molto altro ancora.

+0

potresti volerlo sovvertire in quel caso :) – humblerookie

+0

Ovviamente, ho appena fatto :) – Sandra

+1

Esempio ufficiale: https://github.com/chrisbanes/cheesesquare – Roel

1

Ho trovato questa libreria che sembra fare quello che stai cercando: https://github.com/kmshack/Android-ParallaxHeaderViewPager e questo https://github.com/flavienlaurent/NotBoringActionBar

È possibile riprodurre il video per vedere il comportamento: https://www.youtube.com/watch?v=sCP-b0a1x5Y

non Potrebbe essere il "nuovo" modo standard di farlo con ToolBar, ma potrebbe darti un'idea controllando il codice. Sembra collegare un OnScrollListener al contenuto scorrevole e quindi attivare le modifiche sulla dimensione della barra.

3

Beh, non ho idea di come lo fanno, ma ... perché non dare un'occhiata al codice sorgente? Fortunatamente per noi, l'app Contatti è ancora open source su Android L (altri non erano fortunati come Contatti, come Mail, che non funziona più su L o Keyboard, che hanno smesso di aggiornare dal momento del lancio del loro propietary Google Keyboard).

Ad ogni modo, ecco il codice sorgente Credo che si dovrebbe guardare: https://github.com/android/platform_packages_apps_contacts/blob/master/src%2Fcom%2Fandroid%2Fcontacts%2Factivities%2FActionBarAdapter.java

Nota il metodo update(boolean skipAnimation) in linea 311, che chiama animateTabHeightChange(int start, int end) (linea 437).

La mia ipotesi è tutta la magia accade lì ;-)

2

A partire da giugno 2015, l'effetto desiderato può essere ottenuto tramite il cosiddetto CollapsingToolbarLayout della nuova libreria di supporto di progettazione.

Sulla base del codice di esempio here, sto immaginando che:

  • il CardView ricerca è figlio della barra degli strumenti
  • il CardView chiamata persa appartiene alla collapsingtoolbar con l'attributo collapseMode impostato al 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> 

+0

la mia domanda è qui puoi capire qual è il problema: http: // StackOverflow.com/domande/30913211/barra degli strumenti-non-scrolling-quando-con-collasso-barra-effetto –

2

Nessuna libreria di terze parti è necessaria ora! Android sta ufficialmente fornendo una libreria. Puoi comprimere la barra degli strumenti e fare molti altri aggiustamenti.

Scegli questa android-developer's blog

E non dimenticate di aggiungere questa dipendenza nel file build.gradle.

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

0

Per me https://mzgreen.github.io/2015/06/23/How-to-hideshow-Toolbar-when-list-is-scrolling%28part3%29/ ha aiutato. Un codice sorgente si trova qui: https://github.com/mzgreen/HideOnScrollExample/tree/master/app/src/main.

Un RecycleView nel layout dovrebbe essere simile:

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

Nota che, dopo l'avvio di un'applicazione compaiono 2 barre degli strumenti (ActionBar e barra degli strumenti). Quindi nel tuo activity.java si dovrebbe scrivere in modo:

@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 barra degli strumenti è personalizzato come mostrato di seguito: https://stackoverflow.com/a/26548766/2914140. Voglio dire, appare senza titolo e nessun altro elemento, quindi puoi aggiungerli in un layout.

0

L'app Contatti di Android non ha una soluzione plug-and-play facile da utilizzare nella propria app.

Fa un'implementazione completa, essenzialmente come se lo si stesse implementando da zero. Per il contesto, prima di guardare il codice, tenere a mente come le viste sono disposti:

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

Il MultiShrinkScroller è un FrameLayout che di tramite il comportamento di scorrimento, ma la roba principale è in un LinearLayout, riducendo così l'altezza delle viste più alte "scorrerà" verso l'alto le viste inferiori.

Il file chiave per l'attuazione è questa:

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(); e updateHeaderTextSizeAndMargin(); gestire il cambiamento di tonalità e di testo, come si arriva è crollato in modo che si trasforma nel look and feel di una normale barra d'azione/barra degli strumenti.

Si può prendere il file MultiShrinkScroller e adattarlo per proprio uso, ma ci sono probabilmente implementazioni più facili al giorno d'oggi (compresi quelli dalla libreria di progettazione di Android).

Problemi correlati