FloatingActionButton的位置可以通过FloatingActionButtonLocation来设定,
FloatingActionButtonLocation只有7个值这大大不能够满足我们需求。
比如:我们在iPhoneX 以上的屏幕设置为 FloatingActionButtonLocation.centerDocked
会自动给我们底部按钮添加安全区域、在安卓上展示直接沉入底部 这并不是我们所需要的结果。
通过查看 FloatingActionButtonLocation 源码如下:
abstract class FloatingActionButtonLocation {
/// Abstract const constructor. This constructor enables subclasses to provide
/// const constructors so that they can be used in const expressions.
const FloatingActionButtonLocation();
/// Start-aligned [FloatingActionButton], floating over the transition between
/// the [Scaffold.appBar] and the [Scaffold.body].
///
/// To align a floating action button with [CircleAvatar]s in the
/// [ListTile.leading] slots of [ListTile]s in a [ListView] in the [Scaffold.body],
/// use [miniStartTop] and set [FloatingActionButton.mini] to true.
///
/// This is unlikely to be a useful location for apps that lack a top [AppBar]
/// or that use a [SliverAppBar] in the scaffold body itself.
///
/// 
static const FloatingActionButtonLocation startTop = _StartTopFabLocation();
/// Start-aligned [FloatingActionButton], floating over the transition between
/// the [Scaffold.appBar] and the [Scaffold.body], optimized for mini floating
/// action buttons.
///
/// This is intended to be used with [FloatingActionButton.mini] set to true,
/// so that the floating action button appears to align with [CircleAvatar]s
/// in the [ListTile.leading] slot of a [ListTile] in a [ListView] in the
/// [Scaffold.body].
///
/// This is unlikely to be a useful location for apps that lack a top [AppBar]
/// or that use a [SliverAppBar] in the scaffold body itself.
///
/// 
static const FloatingActionButtonLocation miniStartTop = _MiniStartTopFabLocation();
/// Centered [FloatingActionButton], floating over the transition between
/// the [Scaffold.appBar] and the [Scaffold.body].
///
/// This is unlikely to be a useful location for apps that lack a top [AppBar]
/// or that use a [SliverAppBar] in the scaffold body itself.
///
/// 
static const FloatingActionButtonLocation centerTop = _CenterTopFabLocation();
/// Centered [FloatingActionButton], floating over the transition between
/// the [Scaffold.appBar] and the [Scaffold.body], intended to be used with
/// [FloatingActionButton.mini] set to true.
///
/// This is unlikely to be a useful location for apps that lack a top [AppBar]
/// or that use a [SliverAppBar] in the scaffold body itself.
///
/// 
static const FloatingActionButtonLocation miniCenterTop = _MiniCenterTopFabLocation();
/// End-aligned [FloatingActionButton], floating over the transition between
/// the [Scaffold.appBar] and the [Scaffold.body].
///
/// To align a floating action button with [CircleAvatar]s in the
/// [ListTile.trailing] slots of [ListTile]s in a [ListView] in the [Scaffold.body],
/// use [miniEndTop] and set [FloatingActionButton.mini] to true.
///
/// This is unlikely to be a useful location for apps that lack a top [AppBar]
/// or that use a [SliverAppBar] in the scaffold body itself.
///
/// 
static const FloatingActionButtonLocation endTop = _EndTopFabLocation();
/// End-aligned [FloatingActionButton], floating over the transition between
/// the [Scaffold.appBar] and the [Scaffold.body], optimized for mini floating
/// action buttons.
///
/// This is intended to be used with [FloatingActionButton.mini] set to true,
/// so that the floating action button appears to align with [CircleAvatar]s
/// in the [ListTile.trailing] slot of a [ListTile] in a [ListView] in the
/// [Scaffold.body].
///
/// This is unlikely to be a useful location for apps that lack a top [AppBar]
/// or that use a [SliverAppBar] in the scaffold body itself.
///
/// 
static const FloatingActionButtonLocation miniEndTop = _MiniEndTopFabLocation();
/// Start-aligned [FloatingActionButton], floating at the bottom of the screen.
///
/// To align a floating action button with [CircleAvatar]s in the
/// [ListTile.leading] slots of [ListTile]s in a [ListView] in the [Scaffold.body],
/// use [miniStartFloat] and set [FloatingActionButton.mini] to true.
///
/// 
static const FloatingActionButtonLocation startFloat = _StartFloatFabLocation();
/// Start-aligned [FloatingActionButton], floating at the bottom of the screen,
/// optimized for mini floating action buttons.
///
/// This is intended to be used with [FloatingActionButton.mini] set to true,
/// so that the floating action button appears to align with [CircleAvatar]s
/// in the [ListTile.leading] slot of a [ListTile] in a [ListView] in the
/// [Scaffold.body].
///
/// Compared to [FloatingActionButtonLocation.startFloat], floating action
/// buttons using this location will move horizontally _and_ vertically
/// closer to the edges, by [kMiniButtonOffsetAdjustment] each.
///
/// 
static const FloatingActionButtonLocation miniStartFloat = _MiniStartFloatFabLocation();
/// Centered [FloatingActionButton], floating at the bottom of the screen.
///
/// To position a mini floating action button, use [miniCenterFloat] and
/// set [FloatingActionButton.mini] to true.
///
/// 
static const FloatingActionButtonLocation centerFloat = _CenterFloatFabLocation();
/// Centered [FloatingActionButton], floating at the bottom of the screen,
/// optimized for mini floating action buttons.
///
/// This is intended to be used with [FloatingActionButton.mini] set to true,
/// so that the floating action button appears to align horizontally with
/// the locations [FloatingActionButtonLocation.miniStartFloat]
/// and [FloatingActionButtonLocation.miniEndFloat].
///
/// Compared to [FloatingActionButtonLocation.centerFloat], floating action
/// buttons using this location will move vertically down
/// by [kMiniButtonOffsetAdjustment].
///
/// 
static const FloatingActionButtonLocation miniCenterFloat = _MiniCenterFloatFabLocation();
/// End-aligned [FloatingActionButton], floating at the bottom of the screen.
///
/// This is the default alignment of [FloatingActionButton]s in Material applications.
///
/// To align a floating action button with [CircleAvatar]s in the
/// [ListTile.trailing] slots of [ListTile]s in a [ListView] in the [Scaffold.body],
/// use [miniEndFloat] and set [FloatingActionButton.mini] to true.
///
/// 
static const FloatingActionButtonLocation endFloat = _EndFloatFabLocation();
/// End-aligned [FloatingActionButton], floating at the bottom of the screen,
/// optimized for mini floating action buttons.
///
/// This is intended to be used with [FloatingActionButton.mini] set to true,
/// so that the floating action button appears to align with [CircleAvatar]s
/// in the [ListTile.trailing] slot of a [ListTile] in a [ListView] in the
/// [Scaffold.body].
///
/// Compared to [FloatingActionButtonLocation.endFloat], floating action
/// buttons using this location will move horizontally _and_ vertically
/// closer to the edges, by [kMiniButtonOffsetAdjustment] each.
///
/// 
static const FloatingActionButtonLocation miniEndFloat = _MiniEndFloatFabLocation();
/// Start-aligned [FloatingActionButton], floating over the
/// [Scaffold.bottomNavigationBar] so that the center of the floating
/// action button lines up with the top of the bottom navigation bar.
///
/// To align a floating action button with [CircleAvatar]s in the
/// [ListTile.leading] slots of [ListTile]s in a [ListView] in the [Scaffold.body],
/// use [miniStartDocked] and set [FloatingActionButton.mini] to true.
///
/// If the value of [Scaffold.bottomNavigationBar] is a [BottomAppBar],
/// the bottom app bar can include a "notch" in its shape that accommodates
/// the overlapping floating action button.
///
/// This is unlikely to be a useful location for apps that lack a bottom
/// navigation bar.
///
/// 
static const FloatingActionButtonLocation startDocked = _StartDockedFabLocation();
/// Start-aligned [FloatingActionButton], floating over the
/// [Scaffold.bottomNavigationBar] so that the center of the floating
/// action button lines up with the top of the bottom navigation bar,
/// optimized for mini floating action buttons.
///
/// If the value of [Scaffold.bottomNavigationBar] is a [BottomAppBar],
/// the bottom app bar can include a "notch" in its shape that accommodates
/// the overlapping floating action button.
///
/// This is intended to be used with [FloatingActionButton.mini] set to true,
/// so that the floating action button appears to align with [CircleAvatar]s
/// in the [ListTile.leading] slot of a [ListTile] in a [ListView] in the
/// [Scaffold.body].
///
/// This is unlikely to be a useful location for apps that lack a bottom
/// navigation bar.
///
/// 
static const FloatingActionButtonLocation miniStartDocked = _MiniStartDockedFabLocation();
/// Centered [FloatingActionButton], floating over the
/// [Scaffold.bottomNavigationBar] so that the center of the floating
/// action button lines up with the top of the bottom navigation bar.
///
/// If the value of [Scaffold.bottomNavigationBar] is a [BottomAppBar],
/// the bottom app bar can include a "notch" in its shape that accommodates
/// the overlapping floating action button.
///
/// This is unlikely to be a useful location for apps that lack a bottom
/// navigation bar.
///
/// 
static const FloatingActionButtonLocation centerDocked = _CenterDockedFabLocation();
/// Centered [FloatingActionButton], floating over the
/// [Scaffold.bottomNavigationBar] so that the center of the floating
/// action button lines up with the top of the bottom navigation bar;
/// intended to be used with [FloatingActionButton.mini] set to true.
///
/// If the value of [Scaffold.bottomNavigationBar] is a [BottomAppBar],
/// the bottom app bar can include a "notch" in its shape that accommodates
/// the overlapping floating action button.
///
/// This is unlikely to be a useful location for apps that lack a bottom
/// navigation bar.
///
/// 
static const FloatingActionButtonLocation miniCenterDocked = _MiniCenterDockedFabLocation();
/// End-aligned [FloatingActionButton], floating over the
/// [Scaffold.bottomNavigationBar] so that the center of the floating
/// action button lines up with the top of the bottom navigation bar.
///
/// If the value of [Scaffold.bottomNavigationBar] is a [BottomAppBar],
/// the bottom app bar can include a "notch" in its shape that accommodates
/// the overlapping floating action button.
///
/// This is unlikely to be a useful location for apps that lack a bottom
/// navigation bar.
///
/// 
static const FloatingActionButtonLocation endDocked = _EndDockedFabLocation();
/// End-aligned [FloatingActionButton], floating over the
/// [Scaffold.bottomNavigationBar] so that the center of the floating
/// action button lines up with the top of the bottom navigation bar,
/// optimized for mini floating action buttons.
///
/// To align a floating action button with [CircleAvatar]s in the
/// [ListTile.trailing] slots of [ListTile]s in a [ListView] in the [Scaffold.body],
/// use [miniEndDocked] and set [FloatingActionButton.mini] to true.
///
/// If the value of [Scaffold.bottomNavigationBar] is a [BottomAppBar],
/// the bottom app bar can include a "notch" in its shape that accommodates
/// the overlapping floating action button.
///
/// This is intended to be used with [FloatingActionButton.mini] set to true,
/// so that the floating action button appears to align with [CircleAvatar]s
/// in the [ListTile.trailing] slot of a [ListTile] in a [ListView] in the
/// [Scaffold.body].
///
/// This is unlikely to be a useful location for apps that lack a bottom
/// navigation bar.
///
/// 
static const FloatingActionButtonLocation miniEndDocked = _MiniEndDockedFabLocation();
/// Places the [FloatingActionButton] based on the [Scaffold]'s layout.
///
/// This uses a [ScaffoldPrelayoutGeometry], which the [Scaffold] constructs
/// during its layout phase after it has laid out every widget it can lay out
/// except the [FloatingActionButton]. The [Scaffold] uses the [Offset]
/// returned from this method to position the [FloatingActionButton] and
/// complete its layout.
翻译:------------
/// 根据 [Scaffold] 的布局放置 [FloatingActionButton]。
///
/// 这使用 [ScaffoldPrelayoutGeometry],由 [Scaffold] 构造
/// 在布局阶段,在它布局了它可以布局的每个小部件之后
/// 除了 [FloatingActionButton]。 [Scaffold] 使用 [Offset]
/// 从此方法返回以定位 [FloatingActionButton] 和
/// 完成它的布局。
Offset getOffset(ScaffoldPrelayoutGeometry scaffoldGeometry);
@override
String toString() => objectRuntimeType(this, 'FloatingActionButtonLocation');
}
#我们可以在源码中看到这是一个(abstract)抽象类 下面这个方法源码中指出我们除了设置位置还可以结合Offset 去修改坐标(x,y)。
#那么整体思路就很简单了,通过继承FloatingActionButtonLocation 并且重写:
Offset getOffset(ScaffoldPrelayoutGeometry scaffoldGeometry);
这个方法修改最终的位置
下面展示一些 内联代码片
。
代码如下:
// 1.继承 FloatingActionButtonLocation
// 2.增加 offsetX、offsetY 两个变量
// 3.重写getOffset 并通过父类”FloatingActionButtonLocation“ 调用 Offset offset = location.getOffset(scaffoldGeometry);获取到设置完location 之后的位置对其进行修改
class FloatingButtonCustomLocation extends FloatingActionButtonLocation {
FloatingActionButtonLocation location;
final double offsetX; // X方向的偏移量
final double offsetY; // Y方向的偏移量
FloatingButtonCustomLocation(this.location,{this.offsetX = 0, this.offsetY = 0});
@override
Offset getOffset(ScaffoldPrelayoutGeometry scaffoldGeometry) {
Offset offset = location.getOffset(scaffoldGeometry);
return Offset(offset.dx + offsetX, offset.dy + offsetY);
}
}
// 调用方法
FloatingButtonCustomLocation(
FloatingActionButtonLocation.centerDocked,
offsetY: Platform.isIOS && padding.bottom > 0 ? 15 : -10,
offsetX: 0
)
注:offsetY或offsetX 可选参数 默认 = 0
好了以上就是对FloatingActionButtonLocation 重写的全部内容,欢迎各路大神指点。