Android设计支持库FAB在ViewPager片段与协调布局 [英] Android Design Support Library FAB in a ViewPager Fragment with Coordinator Layout

本文介绍了Android设计支持库FAB在ViewPager片段与协调布局的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想获得一个片段,它是一个ViewPager内内从Android设计支持库浮动操作按钮。我有4个标签,我想在FAB中只有一个选项卡。我的布局如下:


  

main_layout.xml


 < android.support.design.widget.CoordinatorLayout的xmlns:机器人=htt​​p://schemas.android.com/apk/res/android
的xmlns:程序=htt​​p://schemas.android.com/apk/res-auto
机器人:ID =@ + ID / main_content
机器人:layout_width =match_parent
机器人:layout_height =match_parent>< android.support.design.widget.AppBarLayout
    机器人:ID =@ + ID / appbar
    机器人:layout_width =match_parent
    机器人:layout_height =WRAP_CONTENT
    机器人:主题=@风格/ ThemeOverlay.AppCompat.Dark.ActionBar>    < android.support.v7.widget.Toolbar
        机器人:ID =@ + ID /工具栏
        机器人:layout_width =match_parent
        机器人:layout_height =?ATTR / actionBarSize
        机器人:ATTR / colorPrimary背景=
        应用:popupTheme =@风格/ ThemeOverlay.AppCompat.Light
        应用:layout_scrollFlags =滚动| enterAlways/>    < android.support.design.widget.TabLayout
        机器人:ID =@ + ID /标签
        应用:tabIndicatorHeight =3DP
        机器人:layout_width =match_parent
        机器人:layout_height =WRAP_CONTENT/>< /android.support.design.widget.AppBarLayout>< android.support.v4.view.ViewPager
    机器人:ID =@ + ID / viewpager
    机器人:layout_width =match_parent
    机器人:layout_height =match_parent
 应用:layout_behavior =@字符串/ appbar_scrolling_view_behavior/>


  

list_fragment_with_fab.xml


 <的FrameLayout的xmlns:机器人=htt​​p://schemas.android.com/apk/res/android
的xmlns:程序=htt​​p://schemas.android.com/apk/res-auto
机器人:方向=垂直
机器人:填充=5dip
机器人:背景=@彩色/ Transparent_White
机器人:fitsSystemWindows =假
机器人:layout_width =match_parent
机器人:layout_height =match_parent>< org.lucasr.twowayview.widget.TwoWayView
    机器人:ID =@ + ID / clip_recycler_view
    机器人:layout_width =match_parent
    机器人:layout_height =match_parent
    应用:twowayview_layoutManager =ListLayoutManager/>< android.support.design.widget.FloatingActionButton
    机器人:ID =@ + ID / add_list_button
    机器人:layout_width =WRAP_CONTENT
    机器人:layout_height =WRAP_CONTENT
    机器人:layout_gravity =底部|权
    机器人:layout_margin =16DP
    机器人:SRC =@绘制/ ic_list_add
    应用:layout_anchor =@ + ID / clip_recycler_view
    应用:layout_anchorGravity =底部|右|结束/>

现在的问题是,在FAB不按照设计规格工作。即隐藏与FAB的表现不起作用。此外,FAB是不是在它的当片段被激活初始位置。我已经把它贴在下面的截图,以使其更清晰。

在左边的图像中,你可以看到,在FAB是关闭屏幕。当我滚动,工具栏将隐藏(想想Play商店应用)和标签仍然存在,那个时候FAB将向上滚动。

这是在设计支持库中的缺陷?或者是我的布局不正确的?另外,我想FAB仅在片段中的一个,因此添加在main_layout.xml还挺失败的目的。


解决方案

这不是严格意义上的错误,只是他们已经实现的方式。

这是因为这一点:

 应用:layout_behavior =@字符串/ appbar_scrolling_view_behavior

此行​​为不操纵ViewPager的大小,它只是推动它关闭时AppBarLayout扩展屏幕的底部。

您片段填充ViewPager的整个尺寸等正确对齐FAB到ViewPager容器的右下角;但由于ViewPager容器偏移,右下角的屏幕外。

在这种情况下使用FloatingActionButton的正确的方法是通过活动表现出来 - 是这样的:

 <?XML版本=1.0编码=UTF-8&GT?;
< android.support.design.widget.CoordinatorLayout的xmlns:机器人=htt​​p://schemas.android.com/apk/res/android
    的xmlns:程序=htt​​p://schemas.android.com/apk/res-auto
    的xmlns:工具=htt​​p://schemas.android.com/tool​​s
    机器人:ID =@ + ID / main_content
    机器人:layout_width =match_parent
    机器人:layout_height =match_parent
    机器人:fitsSystemWindows =真
    工具:上下文=bubblebearapps.co.uk.nfcapi.MainActivity>    < android.support.design.widget.AppBarLayout
        机器人:ID =@ + ID / appbar
        机器人:layout_width =match_parent
        机器人:layout_height =WRAP_CONTENT
        机器人:paddingTop =@扪/ appbar_padding_top
        机器人:主题=@风格/ AppTheme.AppBarOverlay>        < android.support.v7.widget.Toolbar
            机器人:ID =@ + ID /工具栏
            机器人:layout_width =match_parent
            机器人:layout_height =?ATTR / actionBarSize
            机器人:ATTR / colorPrimary背景=
            应用:layout_scrollFlags =滚动| enterAlways
            应用:popupTheme =@风格/ AppTheme.PopupOverlay>
        < /android.support.v7.widget.Toolbar>        < android.support.design.widget.TabLayout
            机器人:ID =@ + ID /标签
            机器人:layout_width =match_parent
            机器人:layout_height =WRAP_CONTENT/>    < /android.support.design.widget.AppBarLayout>    < android.support.v4.view.ViewPager
        机器人:ID =@ + ID /容器
        机器人:layout_width =match_parent
        机器人:layout_height =match_parent
        应用:layout_behavior =@字符串/ appbar_scrolling_view_behavior/>    < android.support.design.widget.FloatingActionButton
        机器人:ID =@ + ID / FAB
        机器人:layout_width =WRAP_CONTENT
        机器人:layout_height =WRAP_CONTENT
        机器人:layout_gravity =结束|底
        机器人:layout_margin =@扪/ fab_margin
        机器人:SRC =@机器人:可绘制/ ic_dialog_email/>< /android.support.design.widget.CoordinatorLayout>

您再根据使用<一个在ViewPager显示的页面改变FloatingActionButton的大小,图标和onClickBehaviour href=\"http://developer.android.com/reference/android/support/v4/view/ViewPager.html#setOnPageChangeListener(android.support.v4.view.ViewPager.OnPageChangeListener)\"相对=nofollow> OnPageChangeListener 接口。

为了使FloatingActionButton翻屏当你scolling的RecyclerView底部,你必须创建一个行为!这是一个我在不同的项目中使用的:

 公共类ScrollOffBottomBehaviour扩展CoordinatorLayout.Behavior&LT;视图&gt; {    私人诠释mViewHeight;
    私人ObjectAnimator mAnimator;    公共ScrollOffBottomBehaviour(上下文的背景下,ATTRS的AttributeSet){
        超();
    }    @覆盖
    公共布尔onLayoutChild(CoordinatorLayout父母,子女观,诠释的layoutDirection){        mViewHeight = child.getHeight();        返回super.onLayoutChild(父母,子女,的layoutDirection);
    }    @覆盖
    公共无效onNestedScroll(CoordinatorLayout coordinatorLayout,查看孩子,
            查看目标,诠释dxConsumed,诠释dyConsumed,诠释dxUnconsumed,诠释dyUnconsumed){
        如果(mAnimator == NULL ||!mAnimator.isRunning()){
            INT totalScroll =(dyConsumed + dyUnconsumed);            INT targetTranslation = totalScroll&GT; 0? mViewHeight:0;            mAnimator = ObjectAnimator.ofFloat(孩子,translationY,targetTranslation);
            mAnimator.start();
        }
    }    @覆盖
    公共布尔onStartNestedScroll(CoordinatorLayout coordinatorLayout,查看孩子,查看directTargetChild,查看目标,诠释nestedScrollAxes){        返回nestedScrollAxes == ViewCompat.SCROLL_AXIS_VERTICAL;
    }
}

此设置到您的FloatingActionButton与应用:layout_behaviour,所有应该很好...

I'm trying to get a Floating Action Button from the Android Design Support Library inside a Fragment which is inside a ViewPager. I've 4 tabs and I want the FAB in only one of the Tabs. My layout are as follows:

main_layout.xml

<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:popupTheme="@style/ThemeOverlay.AppCompat.Light"
        app:layout_scrollFlags="scroll|enterAlways" />

    <android.support.design.widget.TabLayout
        android:id="@+id/tabs"
        app:tabIndicatorHeight="3dp"
        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" />

list_fragment_with_fab.xml

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:padding="5dip"
android:background="@color/Transparent_White"
android:fitsSystemWindows="false"
android:layout_width="match_parent"
android:layout_height="match_parent">

<org.lucasr.twowayview.widget.TwoWayView
    android:id="@+id/clip_recycler_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:twowayview_layoutManager="ListLayoutManager" />

<android.support.design.widget.FloatingActionButton
    android:id="@+id/add_list_button"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="bottom|right"
    android:layout_margin="16dp"
    android:src="@drawable/ic_list_add"
    app:layout_anchor="@+id/clip_recycler_view"
    app:layout_anchorGravity="bottom|right|end" />

Now the problem is, the FAB does not work as per the design specs. i.e the hiding and showing of the fab doesn't work. Also, the FAB is not at it's initial place when the fragment is activated. I've attached screenshots below to make it more clear.

The in the left image, as you can see, the FAB is off the screen. When I scroll, the Toolbar will hide (think Play Store App) and the tabs remain, that time the FAB will scroll up.

Is this a bug in the Design Support library? Or is my layout incorrect? Also, I want the FAB in only one of the fragments, so adding in the main_layout.xml kinda defeats that purpose.

解决方案

It's not strictly a bug, but just the way they've implemented it.

It's because of this:

app:layout_behavior="@string/appbar_scrolling_view_behavior"

This behavior doesn't manipulate the size of the ViewPager, it just pushes it off the bottom of the screen when the AppBarLayout is expanded.

Your fragment is filling the entire size of the ViewPager and so correctly aligns the FAB to the bottom right of the ViewPager container; but because the ViewPager container is offset, the bottom right is offscreen.

The "proper" way of using a FloatingActionButton in this context is by having the activity show it - like this:

<?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="bubblebearapps.co.uk.nfcapi.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:theme="@style/AppTheme.AppBarOverlay">

        <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">
        </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.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.FloatingActionButton
        android:id="@+id/fab"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="end|bottom"
        android:layout_margin="@dimen/fab_margin"
        android:src="@android:drawable/ic_dialog_email" />

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

You then change the FloatingActionButton's size, icon and onClickBehaviour based on what page is shown in the ViewPager using the OnPageChangeListener interface.

To make the FloatingActionButton scroll off the bottom when you're scolling the RecyclerView, you must create a Behaviour! This is one I used in a different project:

public class ScrollOffBottomBehaviour extends CoordinatorLayout.Behavior<View> {

    private int mViewHeight;
    private ObjectAnimator mAnimator;

    public ScrollOffBottomBehaviour(Context context, AttributeSet attrs) {
        super();
    }

    @Override
    public boolean onLayoutChild(CoordinatorLayout parent, View child, int layoutDirection) {

        mViewHeight = child.getHeight();

        return super.onLayoutChild(parent, child, layoutDirection);
    }

    @Override
    public void onNestedScroll(CoordinatorLayout coordinatorLayout, View child,
            View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed) {


        if(mAnimator == null || !mAnimator.isRunning()){
            int totalScroll = (dyConsumed + dyUnconsumed);

            int targetTranslation = totalScroll > 0 ? mViewHeight : 0;

            mAnimator = ObjectAnimator.ofFloat(child, "translationY", targetTranslation);
            mAnimator.start();
        }
    }

    @Override
    public boolean onStartNestedScroll(CoordinatorLayout coordinatorLayout, View child, View directTargetChild, View target, int nestedScrollAxes) {

        return nestedScrollAxes == ViewCompat.SCROLL_AXIS_VERTICAL;


    }


}

Set this onto your FloatingActionButton with app:layout_behaviour and all should be well...

这篇关于Android设计支持库FAB在ViewPager片段与协调布局的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆