2015-07-30 2 views
23

Tout d'abord, je voudrais commencer par le manque de connaissances sur la mise en page du coordinateur. Je suis simplement en suivant des tutoriels que j'ai trouvés en ligne et je suis curieux de savoir pourquoi mon comportement ne fonctionne pas.Comportement de mise en page personnalisée de mise en page de coordinateur ne se fait jamais appeler

L'affichage de l'enfant à l'intérieur de la disposition du coordinateur doit-il être configuré en barre d'application? Ou êtes-vous en mesure de mettre une vue à l'intérieur là.

En outre, lorsque je définis l'espace de noms res-auto, il ne me donne pas l'option pour layout_behavior. Habituellement studio android se complètera automatiquement si une fonction est disponible et ce n'est pas le cas. Bien que, si je tape layout_behavior, il ne se plaint pas. Alors peut-être que ça marche ...? Quoiqu'il en soit, j'ai défini mon propre comportement de mise en page personnalisée et j'essaie de l'appliquer, mais cela ne semble pas fonctionner. Toute idée serait grandement apprécié.

Voici la disposition. J'essaie d'appliquer mon comportement personnalisé au premier LinearLayout (search_polls_toolbar) et le faire défiler vers le haut lorsque le recyclerview vertical défile vers le haut. (Comme la barre d'outils fait actuellement.) Je devrais également mentionner, ce xml est pour un fragment dans un viewpager. Et l'activité d'hébergement est associée à une disposition de coordinateur qui fait défiler la barre d'outils. (Pourrait-il en conflit à cause de cela?)

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

Et voici le comportement personnalisé:

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

Et voici la disposition des activies d'hébergement.

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

Si quelqu'un souhaite que je poste plus de mon code, s'il vous plaît faites le moi savoir! Merci :)

Répondre

68

La raison pour laquelle cela ne fonctionne pas est que la vue avec Behavior doit être un enfant direct de CoordinatorLayout. Dans votre cas, la hiérarchie est la suivante: CoordinatorLayout ->RelativeLayout ->LinearLayout (avec Behavior).

+68

Parfois, Google me fait pleurer –

+3

Salut, savez-vous une solution de contournement pour résoudre ce problème? –

+1

Point très bien expliqué! – rgv

2

J'ai une disposition comme celle-ci. Il y a quelques choses situées dans les régions supérieures, mais le fond contient seulement un FAB qui est profondément imbriqué.

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

Le FAB est profondément imbriqué.

CoordinatorLayout > ConstraintLayout > RelativeLayout > FABProgressCircle > FAB

Cependant, les RelativeLayout doit être poussé par le CoordinatorLayout lorsque le Snackbar est représentée.

Le comportement qui va le faire est aussi simple que suit.

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

Afficher le Snackbar comme ceci.

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

onDependentViewRemoved doit être ignoré, car en rejetant manuellement un Snackbar la CoordinatorLayout ne se déclenche pas déplacer la traduction View (le FloatingActionButton et son RelativeLayout) revenir à sa place d'origine. En surpassant la méthode, nous pouvons la traduire là où elle était.

+0

Fonctionne parfaitement, vous venez d'enregistrer ma journée: D – Blablablabli

+1

@Blablablabli J'ai mis à jour mon extrait de code Java, vous pourriez être intéressé par le changement. –

+0

En effet, je ne savais pas que cette affaire devait être traitée, vous êtes le MVP :) – Blablablabli