在Pre-Lollipop上添加自定义协调器行为后,FAB有一些奇怪的差距

时间:2015-10-04 13:30:29

标签: android android-coordinatorlayout floating-action-button

我在设计支持库中使用新的FloatingActionButton和CoordinatorLayout。当我尝试在FloatActionButton上添加自定义协调器行为时,它在Lollipop +上工作得很好,但在Pre-Lollipop上,FloatActionButton上有一些奇怪的差距。

我的主要活动布局

<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:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    tools:context=".MainActivity">

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

        <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" />
    </android.support.design.widget.AppBarLayout>

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:paddingLeft="16dp"
        android:paddingRight="16dp"
        android:paddingTop="16dp"
        android:paddingBottom="16dp"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Hello World!" />
    </RelativeLayout>

    <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="16dp"
        android:src="@android:drawable/ic_dialog_email"
        app:layout_behavior="com.test.fabdemo.FloatingActionButtonBehavior" />
</android.support.design.widget.CoordinatorLayout>

使用自定义CoordinatorLayout行为

public class FloatingActionButtonBehavior extends CoordinatorLayout.Behavior<FloatingActionButton> {

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

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

    @Override
    public boolean onDependentViewChanged(CoordinatorLayout parent, FloatingActionButton floatingActionButton, View dependency) {
        if (dependency instanceof AppBarLayout) {
            AppBarLayout appBarLayout = (AppBarLayout) dependency;
            CoordinatorLayout.LayoutParams lp = (CoordinatorLayout.LayoutParams) floatingActionButton.getLayoutParams();
            int bottomMargin = lp.bottomMargin;
            int distanceToScroll = floatingActionButton.getHeight() + bottomMargin;
            float ratio = ViewCompat.getY(appBarLayout) / (float) appBarLayout.getTotalScrollRange();
            ViewCompat.setTranslationY(floatingActionButton, -distanceToScroll * ratio);
            return true;
        }
        return false;
    }
}

带有和不带有行为的模拟器4.0.3的结果

enter image description here enter image description here

1 个答案:

答案 0 :(得分:1)

经过一番研究后我发现FAB的边距是默认行为管理的,所以自定义行为继承自FloatActionButton.Behavior将解决问题

public class FloatingActionButtonBehavior extends FloatingActionButton.Behavior {

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

    @Override
    public boolean layoutDependsOn(CoordinatorLayout parent, FloatingActionButton button, View dependency) {
        return dependency instanceof AppBarLayout || super.layoutDependsOn(parent, button, dependency);
    }

    @Override
    public boolean onDependentViewChanged(CoordinatorLayout parent, FloatingActionButton floatingActionButton, View dependency) {
        if (dependency instanceof AppBarLayout) {
            AppBarLayout appBarLayout = (AppBarLayout) dependency;
            CoordinatorLayout.LayoutParams lp = (CoordinatorLayout.LayoutParams) floatingActionButton.getLayoutParams();
            int bottomMargin = lp.bottomMargin;
            int distanceToScroll = floatingActionButton.getHeight() + bottomMargin;
            float ratio = ViewCompat.getY(appBarLayout) / (float) appBarLayout.getTotalScrollRange();
            ViewCompat.setTranslationY(floatingActionButton, -distanceToScroll * ratio);
            return true;
        }
        return super.onDependentViewChanged(parent, floatingActionButton, dependency);
    }
}