2015-07-30 19 views
23

In primo luogo, vorrei premettere questo con la mia mancanza di conoscenza del layout del coordinatore. Sto semplicemente seguendo i tutorial che ho trovato online e sono curioso del perché il mio comportamento non funzioni.Layout del coordinatore layout di layout personalizzato mai chiamato

La vista secondaria all'interno del layout del coordinatore deve essere il layout della barra delle applicazioni? O sei in grado di mettere qualsiasi vista lì dentro.

Inoltre, quando definisco lo spazio dei nomi res-auto non mi dà l'opzione per layout_behavior. Di solito Android Studio si auto-completa se una funzione è disponibile e non lo ha fatto. Sebbene, se scrivo layout_behavior, non si lamenta. Quindi forse sta funzionando ...?

Indipendentemente da ciò, ho definito il mio comportamento di layout personalizzato e sto provando ad applicarlo ma non sembra funzionare. Qualsiasi intuizione sarebbe molto apprezzata.

Ecco il layout. Sto provando ad applicare il mio comportamento personalizzato al primo LinearLayout (search_polls_toolbar) e farlo scorrere verso l'alto quando la visualizzazione verticale del riciclo si alza. (Come fa attualmente la barra degli strumenti.) Vorrei anche menzionare, questo xml è per un frammento in un viewpager. E l'attività di hosting ha un layout coordinatore ad esso collegato che fa scorrere la barra degli strumenti. (Potrebbe essere in conflitto a causa di questo?)

<?xml version="1.0" encoding="utf-8"?> 
<android.support.design.widget.CoordinatorLayout 
    android:id="@+id/root" 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:app="http://schemas.android.com/apk/res-auto" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent"> 
<RelativeLayout 
    android:id="@+id/container" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:orientation="vertical" 
    > 
    <LinearLayout 
     android:id="@+id/search_polls_toolbar" 
     android:layout_width="match_parent" 
     android:layout_height="?android:actionBarSize" 
     android:background="@color/icitizen_toolbar_orange" 
     android:weightSum="1" 
     app:layout_behavior="com.example.chrisjohnson.icitizenv2.CustomBehaviors.ToolbarBehavior" 
     > 

     <EditText 
      android:id="@+id/search_polls" 
      android:layout_width="0dp" 
      android:layout_height="wrap_content" 
      android:hint="@string/search_polls" 
      android:gravity="center_horizontal" 
      android:layout_weight=".5" 
      android:drawableLeft="@drawable/magnifying_glass" 
      android:drawableStart="@drawable/magnifying_glass" 
      android:layout_marginTop="5dp" 
      android:layout_marginLeft="15dp" 
      android:drawablePadding="-50dp" 
      android:paddingLeft="5dp" 
      android:paddingTop="5dp" 
      android:paddingBottom="10dp" 
      android:cursorVisible="false" 
      android:textSize="20sp" 
      android:background="@color/icitizen_light_orange" 
      /> 

    </LinearLayout> 

    <android.support.v7.widget.RecyclerView 
     android:id="@+id/poll_horizontal_recycler_view" 
     android:layout_width="match_parent" 
     android:layout_height="75dp" 
     android:layout_below="@id/search_polls_toolbar" 
     android:layout_marginLeft="10dp" 
     android:layout_marginTop="5dp" 
     android:scrollbars="none" 
     > 

    </android.support.v7.widget.RecyclerView> 

    <android.support.v7.widget.RecyclerView 
     android:id="@+id/poll_recycler_view" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     android:layout_marginTop="10dp" 
     android:layout_below="@id/poll_horizontal_recycler_view" 
     app:layout_scrollFlags="scroll|enterAlways" 
     android:scrollbars="vertical" /> 

</RelativeLayout> 

<android.support.design.widget.FloatingActionButton 
    android:id="@+id/polls_fab" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:src="@drawable/white_plus_icon" 
    android:layout_marginBottom="70dp" 
    app:backgroundTint="@color/icitizen_orange" 
    app:layout_anchor="@id/container" 
    app:layout_anchorGravity="bottom|right|end" 
    app:borderWidth="0dp" 
    android:layout_marginRight="15dp" 
    android:layout_marginEnd="15dp"/> 

Ed ecco il comportamento personalizzato:

public class ToolbarBehavior extends CoordinatorLayout.Behavior<Toolbar> { 
    public ToolbarBehavior(Context context, AttributeSet attrs) { 
     super(context, attrs); 
     Toast.makeText(context, "AJSJA", Toast.LENGTH_LONG).show(); 
    } 

    @Override 
    public boolean layoutDependsOn(CoordinatorLayout parent, Toolbar child, View dependency) { 
     return dependency instanceof RecyclerView; 
    } 

    @Override 
    public boolean onDependentViewChanged(CoordinatorLayout parent, Toolbar child, View dependency) { 
     child.setTranslationY(child.getY()); 
     return true; 
    } 
} 

Ed ecco il layout dei activies di hosting.

<?xml version="1.0" encoding="utf-8"?> 
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:app="http://schemas.android.com/apk/res-auto" 
    android:id="@+id/coordinatorLayout" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent"> 
    <android.support.design.widget.AppBarLayout 
     android:id="@+id/appBarLayout" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content"> 
     <android.support.v7.widget.Toolbar 
      android:id="@+id/toolbar" 
      android:layout_width="match_parent" 
      android:layout_height="?android:attr/actionBarSize" 
      android:background="?attr/colorPrimary" 
      app:layout_scrollFlags="scroll|enterAlways" 
      /> 
    </android.support.design.widget.AppBarLayout> 
    <android.support.v4.view.ViewPager 
     android:id="@+id/home_viewpager" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     app:layout_behavior="@string/appbar_scrolling_view_behavior" 
     /> 
</android.support.design.widget.CoordinatorLayout> 

Se qualcuno vorrebbe che io inserissi più del mio codice, per favore fatemelo sapere! Grazie :)

risposta

68

Il motivo per cui non funziona è che la vista con Behavior deve essere una figlia diretta di CoordinatorLayout. Nel tuo caso, la gerarchia è: CoordinatorLayout ->RelativeLayout ->LinearLayout (con Behavior).

+68

A volte Google mi fa piangere –

+3

Ciao, Sapete qualsiasi soluzione per risolvere questo problema? –

+1

Punto molto ben spiegato! – rgv

2

Ho un layout come questo. Ci sono alcune cose che si trovano nelle regioni superiori, ma il fondo contiene solo un FAB che è profondamente annidato.

<android.support.design.widget.CoordinatorLayout 
    android:id="@+id/your_coordinator_id"> 

    <android.support.constraint.ConstraintLayout 
     app:layout_behavior="com.yourpackage.YourBehavior"> 

     <ScrollView> 
      ... 
     </ScrollView> 

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

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

     <!-- 
      Everything "around" the FAB needs to be moved. 
     --> 
     <RelativeLayout 
      android:id="@+id/your_view_id"> 

      <com.github.jorgecastilloprz.FABProgressCircle> 

       <!-- 
        This is the actual FAB. 
       --> 
       <android.support.design.widget.FloatingActionButton/> 
      </com.github.jorgecastilloprz.FABProgressCircle> 
     </RelativeLayout> 
    </android.support.constraint.ConstraintLayout> 
</android.support.design.widget.CoordinatorLayout> 

Il FAB è profondamente annidato.

CoordinatorLayout > ConstraintLayout > RelativeLayout > FABProgressCircle > FAB

Tuttavia le RelativeLayout bisogno di essere spinto dalla CoordinatorLayout quando è mostrato il Snackbar.

Il comportamento che lo farà è semplice come segue.

package com.yourpackage; 

... 

public class YourBehavior extends CoordinatorLayout.Behavior<ConstraintLayout> { 

    public YourBehavior(Context context, AttributeSet attrs) { 
    } 

    @Override 
    public boolean onDependentViewChanged(CoordinatorLayout parent, ConstraintLayout child, View dependency) { 
     float translationY = Math.min(0, dependency.getTranslationY() - dependency.getHeight()); 
     // Note that the RelativeLayout gets translated. 
     child.findViewById(R.id.your_view_id).setTranslationY(translationY); 
     return true; 
    } 

    @Override 
    public void onDependentViewRemoved(CoordinatorLayout parent, ConstraintLayout child, View dependency) { 
     child.findViewById(R.id.your_view_id).setTranslationY(0.0f); 
    } 

    @Override 
    public boolean layoutDependsOn(CoordinatorLayout parent, ConstraintLayout child, View dependency) { 
     return dependency instanceof Snackbar.SnackbarLayout; 
    } 
} 

Mostra il Snackbar come questo.

Snackbar.make(findViewById(R.id.your_coordinator_id), "Message", Snackbar.LENGTH_SHORT).show(); 

onDependentViewRemoved deve essere ignorato, perché quando respingendo manualmente una Snackbar il CoordinatorLayout non farà scattare spostando la tradotto View (la FloatingActionButton e la sua RelativeLayout) torna alla sua posizione originale. Sovrascrivendo il metodo possiamo tradurlo nel punto in cui era.

+0

Funziona perfettamente, hai appena salvato la mia giornata: D – Blablablabli

+1

@Blablablabli Ho aggiornato il mio snippet di codice Java, potresti essere interessato alla modifica. –

+0

Anzi, non sapevo che questo caso doveva essere gestito, sei l'MVP :) – Blablablabli

Problemi correlati