在 Pre-Lollipop 上添加自定义协调器行为后,FAB 有奇怪的差距
FAB has weird gap after add custom Coordinator Behavior on Pre-Lollipop
我正在设计支持库中使用新的 FloatingActionButton 和 CoordinatorLayout。当我尝试在 FloatActionButton 上添加自定义协调器行为时,它在 Lollipop+ 上运行完美,但在 Pre-Lollipop 上,FloatActionButton
上有一些奇怪的间隙边距
我的主要activity布局
<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 中有和没有行为的结果
经过一些研究,我发现 FAB 的边距是由默认 Behavior 管理的,因此使自定义 Behavior 继承自 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);
}
}
我正在设计支持库中使用新的 FloatingActionButton 和 CoordinatorLayout。当我尝试在 FloatActionButton 上添加自定义协调器行为时,它在 Lollipop+ 上运行完美,但在 Pre-Lollipop 上,FloatActionButton
上有一些奇怪的间隙边距我的主要activity布局
<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 中有和没有行为的结果
经过一些研究,我发现 FAB 的边距是由默认 Behavior 管理的,因此使自定义 Behavior 继承自 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);
}
}