web-dev-qa-db-fra.com

Le bouton d'action flottant ne s'affiche pas complètement à l'intérieur d'un fragment

J'utilise le bouton FAB avec RecyclerView dans un fragment. Ce fragment est une instance d'un TabViewPager. J'ai un problème avec le bouton FAB. J'ai placé le RecyclerView et le bouton fab dans un FrameLayout, où le bouton FAB est placé en bas à droite. Maintenant, le problème auquel je suis confronté est que le bouton FAB n'est pas complètement visible. Sa moitié de la partie est cachée comme indiqué dans la capture d'écran ci-dessous. Quelqu'un peut-il m'aider à résoudre ce problème? Merci d'avance. 

FAB with RecyclerView inside FrameLayout

Remarque: Le FAB s'aligne correctement une fois défilé. Le problème ne se pose que s'il est idéal (avant le défilement effectué). 

fragment.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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.support.v7.widget.RecyclerView
        Android:id="@+id/recyclerView"
        Android:layout_width="match_parent"
        Android:layout_height="match_parent"/>

    <Android.support.design.widget.FloatingActionButton
        Android:id="@+id/fab"
        Android:layout_width="wrap_content"
        Android:layout_height="wrap_content"
        Android:layout_gravity="end|bottom"
        Android:layout_margin="10dp"
        app:backgroundTint="@color/red"
        Android:src="@drawable/ic_done"/>
</FrameLayout>

tabviewpagerlayout.xml

<?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/main_content"
    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:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">


        <Android.support.v7.widget.Toolbar
            Android:id="@+id/toolbar"
            Android:layout_width="match_parent"
            Android:layout_height="?attr/actionBarSize"
            Android:background="?attr/colorPrimary"
            app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
            app:layout_scrollFlags="scroll|enterAlways" />


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

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

    <Android.support.v4.view.ViewPager
        Android:id="@+id/viewpager"
        Android:layout_width="match_parent"
        Android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior" />

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

Vous devriez déplacer votre FAB à l'intérieur de la CoordinatorLayout.

<Android.support.design.widget.CoordinatorLayout>

    <Android.support.design.widget.AppBarLayout>

        <Android.support.v7.widget.Toolbar
            app:layout_scrollFlags="scroll|enterAlways" />

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

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

    <Android.support.v4.view.ViewPager
        app:layout_behavior="@string/appbar_scrolling_view_behavior" />

    <Android.support.design.widget.FloatingActionButton
        Android:id="@+id/fab"
        Android:layout_gravity="end|bottom"/>

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

Vous pouvez ensuite ajouter RecyclerView à l’intérieur du viewPager de la manière suivante:

Adapter adapter = new Adapter(getSupportFragmentManager());
adapter.addFragment(new RecyclerViewFragment(), "Tab1");
viewPager.setAdapter(adapter);

où la disposition RecyclerViewFragment est:

 <Android.support.v7.widget.RecyclerView
        xmlns:Android="http://schemas.Android.com/apk/res/Android"
        Android:id="@+id/recyclerView"
        Android:layout_width="match_parent"
        Android:layout_height="match_parent"/>
10
Gabriele Mariotti

Ce n'est pas une solution acceptable d'avoir à afficher/masquer le FAB quel que soit l'onglet sélectionné. J'ai essayé toutes les combinaisons de mise en page, mais déplacer la FAB vers la mise en page de l'activité était la seule solution qui fonctionnait. Mais que faire si vous n’avez besoin du bouton que dans un seul onglet? C’est le seul moyen qui fonctionne à présent, mais j’attends une mise à jour de la bibliothèque de conception car cette version est trop boguée. Quoi qu'il en soit, le FAB doit être un descendant direct de CoordinatorLayout, afin qu'il ne soit pas enfoncé par la barre d'outils en train de s'effondrer ...

17
Bojan Ilievski
  1. J'ai eu le même problème que le FloatingActionButton était complètement invisible, et il était hors de l'écran en bas. Quand je défile vers le bas, il apparaît. 
  2. De plus, les onglets étaient cachés lors du défilement, mais je voulais qu'ils soient toujours visibles, donc je l'ai corrigé en supprimant app:layout_scrollFlags="scroll|enterAlways". Crédits à JDev à comment éviter de cacher les onglets lors du défilement?
    Ceci a résolu le problème de FloatingActionButton également, il est visible maintenant.
6
cgr

Je viens de rencontrer le même problème. Malheureusement, je n'ai pas de réponse pour vous, mais quelques remarques supplémentaires.

Ce n'est pas que le bouton soit enfoncé, c'est tout le fragment qui a été enfoncé. Je ne l'ai pas encore testée, mais j'imagine que s'il existe un moyen de voir la taille de la page de fragment, vous verrez que cela ne se termine pas au bas de l'écran, comme il se doit. 

pour une solution possible, je pense à ajouter un rembourrage de taille "? attr/actionBarSize" en bas. 

Je vais tester cela et poster à la fin

update: Comme j'ai utilisé une bordure de 80 dp, obtenez un capture d'écran (je n'ai pas 10 réputation pour poster une capture d'écran, avec)

solution de contournement:

<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/rootLayout"
        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"
            Android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

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

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

        <FrameLayout
            Android:id="@+id/fragment_root"
            Android:layout_width="match_parent"
            Android:layout_height="match_parent"
            Android:background="@drawable/border"
            Android:layout_marginTop="?attr/actionBarSize"
            >
            <!--Android:paddingBottom="?attr/actionBarSize"-->
            <!--app:layout_behavior="@string/appbar_scrolling_view_behavior"-->
            <LinearLayout
                Android:layout_width="match_parent"
                Android:layout_height="match_parent"
                Android:background="@drawable/border"></LinearLayout>
            <fragment
                Android:layout_width="match_parent"
                Android:layout_height="match_parent"
                Android:name="com.derek.hianthy.mydiary.ui.BaseFragment"
                tools:layout="@layout/layout"
                Android:background="@drawable/border"
                />

        </FrameLayout>
        <Android.support.design.widget.FloatingActionButton
            Android:id="@+id/fabBtn"
            Android:layout_width="wrap_content"
            Android:layout_height="wrap_content"
            Android:layout_gravity="bottom|right"
            Android:layout_marginBottom="@dimen/fab_margin_bottom"
            Android:layout_marginRight="@dimen/fab_margin_right"
            Android:src="@drawable/ic_action_add"
            app:borderWidth="0dp"
            app:fabSize="normal"
            Android:layout_alignParentBottom="true"
            Android:layout_alignParentRight="true"
            Android:layout_alignParentTop="false"
            Android:layout_alignParentLeft="false" />

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

notic app: layout_behavior = "@ string/appbar_scrolling_view_behavior" été supprimé . résultat

4
Derek Zhu

J'ai en quelque sorte fait ce que Gabriele a suggéré en déplaçant le FAB vers l'activité contenante. De plus, vous devrez mettre à jour la couleur/clickListener de la FAB dans onTabSelected:

public class MainActivity extends AppCompatActivity implements TabLayout.OnTabSelectedListener {

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        ...

        setFloatingActionButtonForImagesTab();

    }

    ...

    @Override
    public void onTabSelected(final TabLayout.Tab tab) {
    switch (tab.getPosition()) {
        case 0:
            setFloatingActionButtonForImagesTab();
            break;
        case 1:
            setFloatingActionButtonForMusicTab();
            break;
        case 2:
            setFloatingActionButtonForVideoTab();
            break;
        }
    }

    ...

}

puis, dans la fonction de configuration, définissez simplement la couleur et cliquez sur le programme d'écoute:

private void setFloatingActionButtonForImagesTab() {
    myViewPager.setCurrentItem(0);
    floatingActionButton.setBackgroundTintList(getResources().getColorStateList(R.color.purple));
    floatingActionButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            Snackbar.make(coordinatorLayout, "images", Snackbar.LENGTH_LONG)
                .show();
        }
    });
}

Prenez note de l'appel à setCurrentItem ci-dessus. Il est maintenant nécessaire que vous implémentiez TabLayout.OnTabSelectedListener.

4
Adam Johns

C'est peut-être un peu tard, mais la meilleure option semblait être de créer un autre fragment contenant le fragment avec votre contenu et le bouton flottant. Ce code fonctionne très bien dans mon application:

<FrameLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
    xmlns:tools="http://schemas.Android.com/tools"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    tools:context="domain.ItemsFragment">


    <fragment
        Android:layout_width="wrap_content"
        Android:layout_height="wrap_content"
        Android:name="com.lucyapp.client.ItemFragment"
        Android:id="@+id/fragment"
        tools:layout="@layout/fragment_item_list" />

    <Android.support.design.widget.FloatingActionButton
        Android:id="@+id/fab"
        Android:layout_width="wrap_content"
        Android:layout_height="wrap_content"
        Android:layout_gravity="bottom|end"
        Android:layout_margin="@dimen/fab_margin"
        Android:src="@Android:drawable/ic_dialog_email" />

</FrameLayout>
3
speedingdeer

Cette solution a fonctionné pour moi. Créez une nouvelle classe appelée CustomBehavior avec le code suivant:

public class CustomBehavior extends CoordinatorLayout.Behavior<ViewPager> {

private int mActionBarHeight;

public CustomBehavior(Context context, AttributeSet attributeSet) {
    super(context, attributeSet);
    init(context);
}

public CustomBehavior(Context context) {
    init(context);
}

private void init(Context context) {
    TypedValue tv = new TypedValue();
    if (context.getTheme().resolveAttribute(Android.R.attr.actionBarSize, tv, true)) {
        mActionBarHeight = TypedValue.complexToDimensionPixelSize(tv.data, context.getResources().getDisplayMetrics());
    }
}

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

public boolean onDependentViewChanged(CoordinatorLayout parent, ViewPager child, View dependency) {
    offsetChildAsNeeded(parent, child, dependency);
    return false;
}

private void offsetChildAsNeeded(CoordinatorLayout parent, View child, View dependency) {
    if (child instanceof ViewPager) {
        ViewPager viewPager = (ViewPager) child;
        View list = viewPager.findViewById(R.id.recycler_view);
        if (list != null) {
            final CoordinatorLayout.Behavior behavior =
                    ((CoordinatorLayout.LayoutParams) dependency.getLayoutParams()).getBehavior();
            if (behavior instanceof AppBarLayout.Behavior) {
                final AppBarLayout.Behavior ablBehavior = (AppBarLayout.Behavior) behavior;
                AppBarLayout appBarLayout = (AppBarLayout) dependency;
                ViewCompat.setTranslationY(list, ablBehavior.getTopAndBottomOffset()
                        + appBarLayout.getTotalScrollRange()
                        + mActionBarHeight);
            }
        }
    }
}

}

Maintenant, attribuez la classe de comportement personnalisé au widget viewpager dans le fichier xml

<Android.support.v4.view.ViewPager
    Android:id="@+id/viewpager"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    app:layout_behavior="yourpackage.CustomBehavior"
    />
1
ignacio_gs

Je suis confronté aux mêmes problèmes avec les boutons View Fragment FAB du paginateur en vue qui s'affichent sous l'écran et qui défilent dans son émission .

app:layout_behavior="@string/appbar_scrolling_view_behavior"

dans ViewPager dans CoordinatorLayout. Ainsi, après la suppression de ce comportement de défilement, les problèmes de position FAB sont résolus.

Veuillez vérifier que mon implémentation fonctionne correctement:

<?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/main_content"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent">

    <Android.support.design.widget.AppBarLayout
        Android:id="@+id/appbar"
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content"
        Android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">


        <Android.support.v7.widget.Toolbar
            Android:id="@+id/toolbar"
            Android:layout_width="match_parent"
            Android:layout_height="?attr/actionBarSize"
            Android:background="?attr/colorPrimary"
            app:layout_scrollFlags="scroll|enterAlways"
            app:popupTheme="@style/AppTheme.PopupOverlay">

            <LinearLayout
                Android:layout_width="match_parent"
                Android:layout_height="wrap_content"
                Android:orientation="vertical">

                <TextView
                    Android:layout_width="match_parent"
                    Android:layout_height="wrap_content"
                    Android:gravity="center_horizontal"
                    Android:text="@string/app_name"
                    Android:textColor="@color/textPrimary"
                    Android:textSize="18sp" />

                <TextView
                    Android:layout_width="match_parent"
                    Android:layout_height="wrap_content"
                    Android:gravity="center_horizontal"
                    Android:text="@string/str_toolbar_subtittle"
                    Android:textColor="@color/textPrimary"
                    Android:textSize="14sp" />
            </LinearLayout>
        </Android.support.v7.widget.Toolbar>

        <Android.support.design.widget.TabLayout
            Android:id="@+id/tabs"
            Android:layout_width="match_parent"
            Android:layout_height="wrap_content"
            Android:layout_gravity="bottom"
            Android:background="?attr/colorPrimary"
            app:tabGravity="fill"
            app:tabIndicatorColor="@color/colorAccent"
            app:tabSelectedTextColor="@color/errorColor"
            app:tabTextColor="@color/white" />

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

    <Android.support.v4.view.ViewPager
        Android:id="@+id/viewpager"
        Android:layout_width="match_parent"
        Android:layout_height="match_parent"
        Android:layout_below="@+id/app_bar" />

</Android.support.design.widget.CoordinatorLayout>
1
Nikhil Jogdand

J'avais le même problème où l'exigence était de montrer FAB dans un fragment. Ce que j'ai fait est juste de supprimer la ligne de la barre d'outils 

app:layout_scrollFlags="scroll|enterAlways"

Vous pouvez vérifier ma mise en page

<?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"
    xmlns:tools="http://schemas.Android.com/tools"
    Android:id="@+id/main_content"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    Android:fitsSystemWindows="true"
    tools:context=".MainActivity">

    <Android.support.design.widget.AppBarLayout
        Android:id="@+id/appbar"
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content"
        Android:paddingTop="@dimen/appbar_padding_top"
        Android:background="@color/white"
        app:elevation="0dp"
        Android:elevation="0dp"
        >

        <Android.support.v7.widget.Toolbar
            Android:id="@+id/toolbar_main"
            Android:layout_width="match_parent"
            Android:layout_height="?attr/actionBarSize"
            Android:layout_weight="1"
            Android:background="@color/white"
            app:title="@string/app_name">

        </Android.support.v7.widget.Toolbar>

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


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

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

    <Android.support.v4.view.ViewPager
        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>
0
Shantanu Patil