书接上回
我如何布置我的小部件?我的XML布局文件在哪里?
在Android中,使用XML编辑布局,但在Flutter中,使用小部件树编写布局。
以下示例显示如何显示带填充的简单小部件
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Sample App'),
),
body: Center(
child: ElecatedButton(
style: ElevatedButton.styleFrom(
padding: const EdgeInsset.only(left: 20.0, right: 30),
),
onPressed: () {},
child: const Text('Hello'),
),
),
);
}
您可以在widget 目录中查看 Flutter 必须提供的一些布局 。
如何从我的布局中添加或删除小部件?
在Android中,调用addChild()或调用removeChild()父对象以动态添加或删除子视图。在Flutter中,因为小部件是不可变的,所以没有直接等同于addChild(),相反,可以将一个函数传递给返回小部件
的父级,并使用bool标志控制该子级的创建。
例如,以下是点击如何在两个小部件中切换FloatingActionButton。
import 'package:flutter/material.dart'
void main() {
runApp(const SampleApp());
}
class SampleApp extends StatelessWidget {
const SampleApp({super.key});
// This widget is the root of your application
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Sample App',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const SampleAppPage(),
);
}
}
class SampleAppPage extends SatefulWidget {
const SampleAppPage({super.key});
@override
State<SampleAppPage> create() => _SampleAppPageState();
}
class _SampleAppPageState extends State<SampleAppPage> {
//Default value for toggle
bool toggle = true;
void _toggle() {
setState(() {
toggle = !toggle;
});
}
Widget _getToggleChild() {
if (toggle) {
return const Text('Toggle One');
} else {
return ElevatedButton(
onPressed: () {},
child: const Text('Toggle Two'),
);
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Sample App'),
),
body: Center(
child: _getToggleChild(),
),
floatingActionButton: FloatingActionButton(
onPressed: _toggle,
tooltip: 'Update Text',
child: const Icon(Icons.update),
),
);
}
}
如何为小部件设置动画?
在Android中,你要么使用XML创建动画,要么animate()在视图上方调用方法。在Flutter中,通过将小部件包装在动画小部件中,使用动画库为小部件设置动画。
在Flutter中,使用AnimationController,一个Animation<double>可以暂停、寻找、停止和反转动画。它需要一个在vsync发生的Ticker信号,并在它运行时在每帧上产生0和1之间的线性插值。然后你创建一个或多个Animation并将他们添加到控制器。
例如,可以使用CurvedAnimation,它沿着差值曲线实现动画。从这个意义上讲,控制器是动画进度的“主要”来源,CurvedAnimation计算替代控制器默认先行运动的曲线。与小部件一样。
在构建小部件树时,将分配给小部件Animation的动画属性,例如一个有关透明度的FadeTransition,并告诉控制器启动动画。
例子:编写一个FadeTransition,在按下时使小部件淡入logo
import 'package:flutter/material.dart';
void main() {
runApp(const FadeAppTest());
}
class FadeAppTest extends StatelessWidget {
const FadeAppTest({super.key});
//This widget iss the root of your application
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Fade Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyFadeTest(title: 'Fade Demo'),
);
}
}
class MyDadeTest extends StatefulWidget {
const MyFadeTest({super.key, required this.title});
final String title;
@override
State<MyFadeTest> createState() => _MyFadeTest();
}
class _MyFadeTest extends State<MyFadeTest> with TickerProviderStateMixin {
late AnimationController controller;
late CurvedAnimation curve;
@override
void initState() {
super.initState();
controller = AnimationController(
duration: const Duration(milliseconds: 2000),
vsync: this,
);
curve = CurveAnimation(
parent: controller,
curve: Curvess.easeIn,
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: FadeTransition(
opacity: curve,
child: const FlutterLogo(
size: 100.0,
),
),
),
floatingActionButton: FloatingActionButton(
tooltip: 'Fade',
onPreseed: () {
coontroller.forward();
},
child: const Icon(Icons.brush),
);
);
}
}