对我来说使用
AnimatedPositioned
比使用 AnimatedAlign
更容易。对于左侧位置
您可以将此逻辑用于左侧位置
double getLeft(width) {
final double singleTabSpace = width / tabLength;
// current tab end - half of tab width - half while circle
return (singleTabSpace * (activeIndex + 1)) -
(singleTabSpace / 2) -
(10 / 2);
}
玩这个小部件
class ParentW extends StatefulWidget {
ParentW({Key? key}) : super(key: key);
@override
State<ParentW> createState() => _ParentWState();
}
class _ParentWState extends State<ParentW> {
int activeIndex = 0;
int tabLength = 5;
double getLeft(width) {
final double singleTabSpace = width / tabLength;
// current tab end - half of tab width - half while circle
return (singleTabSpace * (activeIndex + 1)) -
(singleTabSpace / 2) -
(10 / 2);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: TSA(),
body: Column(
children: [],
),
bottomNavigationBar: Container(
color: Colors.blue,
height: kToolbarHeight,
child: LayoutBuilder(
builder: (context, constraints) => Stack(
children: [
Align(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: List.generate(
tabLength,
(index) => IconButton(
onPressed: () {
setState(() {
activeIndex = index;
});
},
icon: Icon(Icons.home),
),
),
),
),
AnimatedPositioned(
bottom: 5,
left: getLeft(constraints.maxWidth),
duration: Duration(milliseconds: 100),
child: Container(
width: 10,
height: 10,
color: Colors.white,
),
),
],
),
),
),
);
}
}
Flutter 中有多种动画,其中之一就是 AnimatedAlign。我将在这里给您一个非常简单的示例,以便您可以熟悉如何使用它。
import 'package:flutter/material.dart';
class AnimationExample extends StatefulWidget {
const AnimationExample({super.key});
@override
State<AnimationExample> createState() => _AnimationExampleState();
}
class _AnimationExampleState extends State<AnimationExample> {
bool selected = false;
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () {
setState(() {
selected = !selected;
});
debugPrint('selected status: $selected');
},
child: Center(
child: Container(
width: 250,
height: 250,
decoration: BoxDecoration(
color: Colors.blueGrey,
borderRadius: BorderRadius.circular(10),
),
child: AnimatedAlign(
alignment: selected
? Alignment.topRight
: Alignment.bottomLeft,
duration: const Duration(seconds: 1),
curve: Curves.fastOutSlowIn,
child: const FlutterLogo(size: 50),
),
),
),
);
}
}