我想在 Flutter 中创建一个一开始是透明的应用程序栏(其中有一些图标按钮),如果你慢慢滚动它,它就会开始过渡到某种颜色,并且标题会淡入。在特定的偏移量之后,过渡应该完成。
我尝试将普通的应用程序栏小部件与滚动控制器结合使用,但遇到了一些错误。也许是因为我想在无状态小部件中实现它。
我不知道如何拖动appbar,直到ChatGpt教我。 我不太清楚你想要什么,但我做了一个可能有帮助的例子。 如果足以解决您的问题,请将我设为最佳答案。`
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
// This method is rerun every time setState is called, for instance as done
// by the _incrementCounter method above.
//
// The Flutter framework has been optimized to make rerunning build methods
// fast, so that you can just rebuild anything that needs updating rather
// than having to individually change instances of widgets.
return const Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
TopWidget(child: DraggableAppBar())
],
),
),
// This trailing comma makes auto-formatting nicer for build methods.
);
}
}
class TopWidget extends StatelessWidget {
final Widget child;
const TopWidget({required this.child, super.key});
@override
Widget build(BuildContext context) {
return Container(
color: Colors.grey,
width: double.infinity,
height: 300,
child: child,
);
}
}
class DraggableAppBar extends StatefulWidget {
const DraggableAppBar({super.key});
@override
State<DraggableAppBar> createState() => _DraggableAppBarState();
}
double appBarheight=60;
class _DraggableAppBarState extends State<DraggableAppBar> {
double top = 0;
@override
Widget build(BuildContext context) {
return Stack(
children: [
Positioned(
height: appBarheight,
left: 0,
top: top,
child: Draggable(
onDragUpdate: (details) {
setState(() {
top = top + details.delta.dy;
if(top>300-appBarheight){
top=300-appBarheight;
}
if(top<0){
top=0;
}
});
},
feedback: Container(),
childWhenDragging: CustomAppBar(top: top),
child:const CustomAppBar(top: 0,),
),
),
],
);
}
}
class CustomAppBar extends StatelessWidget {
final double top;
final String text='Drag me';
const CustomAppBar({required this.top,super.key});
Color colorFromTop(double top) {
// Clamp the value of top between 0 and 240
double normalizedTop = top.clamp(0.0, 240.0);
// Convert the top value to a value between 0.0 and 1.0
double t = normalizedTop / 240.0;
// Use Color.lerp to interpolate between black and white based on t
return Color.lerp(Colors.black, Colors.white, t)!;
}
@override
Widget build(BuildContext context) {
print(top);
double width = MediaQuery.of(context).size.width;
return Container(
decoration: BoxDecoration(color: colorFromTop(top)),
height: appBarheight,
width: width,
child: Text(text,style:const TextStyle(color: Colors.black),),
);
}
}```