web-dev-qa-db-fra.com

AppBarLayout avec le conteneur FrameLayout, le contenu défilant ne fonctionnant pas

J'essaie d'utiliser la bibliothèque de conception la plus récente pour que ma barre d'outils soit masquée/affichée au défilement. Mon problème est que le contenu de défilement que j'ai est dans le fragment, je l'injecte simplement dans le conteneur FrameLayout et cela ne fonctionne pas. Voici mon activité:

<Android.support.v4.widget.DrawerLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:tools="http://schemas.Android.com/tools"
xmlns:app="http://schemas.Android.com/apk/res-auto"
Android:id="@+id/drawer_layout"
Android:layout_width="match_parent"
Android:layout_height="match_parent">

<Android.support.design.widget.CoordinatorLayout
    Android:id="@+id/main_content"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent">

    <Android.support.design.widget.AppBarLayout
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content">

        <include layout="@layout/layout_toolbar" />

    </Android.support.design.widget.AppBarLayout>

    <FrameLayout
        Android:id="@+id/container"
        Android:layout_width="match_parent"
        Android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior" />

</Android.support.design.widget.CoordinatorLayout>

<FrameLayout
    Android:id="@+id/navigation_drawer_container"
    Android:layout_width="@dimen/navigation_drawer_width"
    Android:layout_height="match_parent"
    Android:layout_gravity="start"
    tools:layout="@layout/fragment_nav_drawer_anon" />

et mon fragment:

<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:orientation="vertical">

<Android.support.v4.widget.SwipeRefreshLayout
    Android:id="@+id/pull_to_refresh"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent">

    <ListView
        Android:id="@Android:id/list"
        Android:layout_width="match_parent"
        Android:layout_height="match_parent"/>
</Android.support.v4.widget.SwipeRefreshLayout>

<TextView
    Android:id="@Android:id/empty"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    Android:textSize="18sp"
    Android:fontFamily="sans-serif"
    Android:color="@color/dark_grey"
    Android:padding="60dp"/>

et barre d'outils:

<Android.support.v7.widget.Toolbar xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:app="http://schemas.Android.com/apk/res-auto"
Android:id="@+id/toolbar"
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:background="?attr/colorPrimary"
Android:minHeight="?attr/actionBarSize"
app:layout_scrollFlags="scroll|enterAlways"
style="@style/Widget.MyApp.ActionBar" />

Je suis officiel doc et ceci démo , et je ne comprends toujours pas comment le faire fonctionner.

40
wwang

Remplacez votre FrameLayout par Android.support.v4.widget.NestedScrollView

NestedScrollView est semblable à ScrollView, mais il prend en charge le rôle de parent et d'enfant de défilement imbriqué sur les versions nouvelles et anciennes d'Android. Le défilement imbriqué est activé par défaut.

Lien vers la doc

21
Sergio

La raison de ce comportement est que Framelayout ne spécifie pas de comportement. CoordinatorLayout s'appuie sur la vue enfant pour gérer le comportement.

Vous pouvez lire au bas ici

http://Android-developers.blogspot.in/2015/05/Android-design-support-library.html

Il déclare que

CoordinatorLayout et vues personnalisées

Une chose importante à noter est que CoordinatorLayout n'a aucune compréhension innée du travail FloatingActionButton ou AppBarLayout. Il fournit simplement une API supplémentaire sous la forme d'un Coordinator.Behavior, qui permet aux vues enfants de mieux contrôler les événements tactiles et les gestes. Vous pouvez également déclarer des dépendances entre elles et recevoir des rappels via onDependentViewChanged ().

Les vues peuvent déclarer un comportement par défaut à l'aide de l'annotation CoordinatorLayout.DefaultBehavior (YourView.Behavior.class) ou le définir dans vos fichiers de présentation à l'aide de l'attribut app: layout_behavior = "com.example.app.YourView $ Behavior". Ce cadre permet à n'importe quelle vue de s'intégrer à CoordinatorLayout.

Éditer: Bien que FrameLayout ne soit pas une vue personnalisée, il ne spécifie pas le comportement recherché par CoordinateLayout.

12
user3426273

Utiliser FrameLayout en tant qu'enfant de CoordinatorLayout fonctionne assez bien. La barre d'outils est réduite comme prévu. J'ai eu un problème au début, quand j'ai utilisé des bibliothèques obsolètes.

Voici les dépendances que j'utilise actuellement:

compile 'com.Android.support:appcompat-v7:22.2.1'
compile 'com.Android.support:cardview-v7:22.2.0'
compile 'com.Android.support:recyclerview-v7:22.2.0'
compile 'com.Android.support:design:22.2.0'

J'utilise FrameLayout avec l'attribut app:layout_behavior="@string/appbar_scrolling_view_behavior" en tant qu'enfant de CoordinatorLayout dans la présentation d'une activité. Le FrameLayout sert de conteneur pour les fragments. Les éléments racines de mes mises en page de fragments sont soit un RecyclerView, soit un NestedScrollView.

Voici la mise en page de l'activité:

    <Android.support.design.widget.CoordinatorLayout
        Android:layout_width="match_parent"
        Android:layout_height="match_parent"
        >

    <FrameLayout
            Android:id="@+id/..."
            Android:layout_width="match_parent"
            Android:layout_height="match_parent"
            app:layout_behavior="@string/appbar_scrolling_view_behavior"
            />

    <Android.support.design.widget.AppBarLayout
            Android:layout_height="192dp"
            Android:layout_width="match_parent"
            >
        <Android.support.design.widget.CollapsingToolbarLayout
                Android:layout_width="match_parent"
                Android:layout_height="match_parent"
                app:layout_scrollFlags="scroll|exitUntilCollapsed"
                >
            <ImageView
                    Android:id="@+id/.."
                    Android:layout_width="match_parent"
                    Android:layout_height="match_parent"
                    Android:fitsSystemWindows="true"
                    Android:scaleType="centerCrop"
                    Android:src="@drawable/..."
                    app:layout_collapseMode="parallax"/>
            <Android.support.v7.widget.Toolbar
                    Android:id="@+id/toolbar_sessions"
                    Android:layout_height="?attr/actionBarSize"
                    Android:layout_width="match_parent"
                    app:layout_collapseMode="pin"
                    />
        </Android.support.design.widget.CollapsingToolbarLayout>
    </Android.support.design.widget.AppBarLayout>

</Android.support.design.widget.CoordinatorLayout>

La disposition de mon premier fragment ressemble à ceci:

<Android.support.v7.widget.RecyclerView
    xmlns:Android="http://schemas.Android.com/apk/res/Android"
    xmlns:tools="http://schemas.Android.com/tools"
    Android:scrollbars="vertical"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    tools:context="..."
    />

La disposition de mon deuxième fragment ressemble à ceci:

<Android.support.v4.widget.NestedScrollView
    xmlns:Android="http://schemas.Android.com/apk/res/Android"
    xmlns:tools="http://schemas.Android.com/tools"
    Android:id="..."
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    tools:context="..."
    >
...
</Android.support.v4.widget.NestedScrollView>
11
Emanuel Seidinger

Dans mon application, cela ne fonctionne qu'avec RecyclerView. Peut-être devriez-vous utiliser RecyclerView au lieu de ListView.

4
sergeybe

Vous pouvez réaliser le défilement avec Framelayout dans votre coordinateur Layout. Pour cela, vous devez utiliser app:layout_behavior="@string/appbar_scrolling_view_behavior" dans votre frameLayout ainsi que dans la vue défilante avec laquelle vous souhaitez cet effet de réduction.

Par exemple, si vous gonflez RecyclerView dans votre frameLayout, vous devez utiliser app:layout_behavior="@string/appbar_scrolling_view_behavior" à l'intérieur de votre recyclerrView également.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"

    Android:orientation="vertical">
<Android.support.v7.widget.RecyclerView
    Android:id="@+id/list"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
    />
</Relativelayout>

ou,

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"

    Android:orientation="vertical">
 <Android.support.v4.widget.NestedScrollView
           Android:layout_width="match_parent"
           Android:layout_height="fill_parent"
        Android:layout_above="@+id/bNext"
        Android:fillViewport="true"
           Android:scrollbars="none"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">
<!--  your content -->
</Android.support.v4.widget.NestedScrollView>
</Relativelayout>

Ainsi, en utilisant ce processus, vous pouvez réaliser un défilement avec frameLayout, qu’il contienne recycler ou nestedScrollview.

3
Anupriya

C'est une bonne question. Moi aussi j'avais le même.

Votre conteneur FrameLayout est défini correctement. Le problème réside dans le Fragment. Le Fragment devrait avoir RecyclerView & pas ListView car il est maintenant obsolète.

Exemple:

<Android.support.v7.widget.RecyclerView
    Android:id="@+id/list"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    Android:clipToPadding="false"
    Android:paddingTop="@dimen/activity_vertical_margin"/>

J'utilise la même structure dans mon application et cela fonctionne parfaitement.

2
Akshay Chordiya

Il vous suffit de remplacer

FrameLayout

à

Android.support.v4.widget.NestedScrollView

de cette façon:

<Android.support.design.widget.CoordinatorLayout
    Android:id="@+id/root_coordinator"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent">

    <Android.support.design.widget.AppBarLayout
        Android:id="@+id/app_bar_layout"
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content">

        <Android.support.design.widget.CollapsingToolbarLayout
            Android:id="@+id/collapsing_toolbar_layout"
            Android:layout_width="match_parent"
            Android:layout_height="wrap_content"
            app:contentScrim="?attr/colorPrimary"
            app:layout_scrollFlags="scroll|enterAlways">

            <ImageView
                Android:layout_width="match_parent"
                Android:layout_height="192dp"
                Android:scaleType="centerCrop"
                Android:src="@drawable/header"
                app:layout_collapseMode="parallax" />

            <Android.support.v7.widget.Toolbar
                Android:id="@+id/app_bar"
                Android:layout_width="match_parent"
                Android:layout_height="?attr/actionBarSize"
                Android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
                app:layout_collapseMode="pin" />

        </Android.support.design.widget.CollapsingToolbarLayout>

    </Android.support.design.widget.AppBarLayout>

    <!-- This was before FrameLayout -->
    <Android.support.v4.widget.NestedScrollView
        Android:id="@+id/content_frame"
        Android:layout_width="match_parent"
        Android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">
    </Android.support.v4.widget.NestedScrollView>

    <Android.support.design.widget.FloatingActionButton
        Android:id="@+id/fab"
        Android:layout_width="wrap_content"
        Android:layout_height="wrap_content"
        Android:layout_gravity="bottom|right"
        Android:layout_margin="16dp"
        Android:src="@drawable/ic_drawer_alertas"
        app:borderWidth="0dp"
        app:fabSize="mini" />
</Android.support.design.widget.CoordinatorLayout>


<Android.support.design.widget.NavigationView
    Android:id="@+id/navigation_drawer"
    Android:layout_width="wrap_content"
    Android:layout_height="match_parent"
    Android:layout_gravity="start"
    app:headerLayout="@layout/drawer_header"
    app:itemIconTint="@color/colorAccent"
    app:itemTextColor="@color/colorSecondaryText"
    app:menu="@menu/menu_main" />
1
Jorge Casariego

Bouge le app:layout_scrollFlags="scroll|enterAlways" de la barre d’outils au Framelayout. Désolé d'être en retard.

1
Mohammad Abdullah

ListView n'implémente pas NestedScrollingChild, il ne fonctionne donc pas.

RecyclerView le fait, donc il peut propager le défilement au NestedScrollingParent (le CoordinatorLayout).

1
Rafi Panoyan

Vous devez ajouter un comportement à la vue de défilement:

<Android.support.v4.widget.SwipeRefreshLayout
    Android:layout_marginTop="5dp"
    Android:id="@+id/swipe_main"
    Android:enabled="false"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    app:layout_behavior="@string/appbar_scrolling_view_behavior">
<com.marshalchen.ultimaterecyclerview.UltimateRecyclerView
    Android:id="@+id/rvUserProfile"
    app:recyclerviewEmptyView ="@layout/ev_home"
    app:recyclerviewClipToPadding="false"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"></com.marshalchen.ultimaterecyclerview.UltimateRecyclerView>
</Android.support.v4.widget.SwipeRefreshLayout>
0
tiny sunlight