admin管理员组文章数量:1124388
I need this result (The app is just for example)
I tried to use BottomSheet, modal_bottom_sheet and various similar libraries, but they hide the widget completely. I want it to stay above the navigation bar as a small strip and be able to be pulled out with a swipe or tap.
I need this result (The app is just for example)
I tried to use BottomSheet, modal_bottom_sheet and various similar libraries, but they hide the widget completely. I want it to stay above the navigation bar as a small strip and be able to be pulled out with a swipe or tap.
Share Improve this question edited 2 days ago jonrsharpe 122k30 gold badges264 silver badges472 bronze badges asked 2 days ago DimaDima 1,2491 gold badge10 silver badges14 bronze badges1 Answer
Reset to default 1This is just an idea to achieve your design and I will made it with GetX if you want to pull out i think you should try GestureDetector
to know drag offset
ps.Maybe this is not best practices that why Im just said just an idea hope this will help
result
page widget
class PlaygroundPage extends StatelessWidget {
const PlaygroundPage({super.key});
@override
Widget build(BuildContext context) {
return GetBuilder<PlaygroundPageController>(
global: false,
init: PlaygroundPageController(),
builder: (controller) => Scaffold(
backgroundColor: AppColors.white,
bottomNavigationBar: _Bottombar(
controller: controller,
),
body: Padding(
padding: EdgeInsets.fromLTRB(0, Get.mediaQuery.padding.top, 0, 0),
child: Column(
children: [
ToButton(
onPressed: () {
Get.back();
},
child: Container(
width: 200,
height: 50,
color: AppColors.green1,
child: const Text('back'),
),
)
],
),
),
),
);
}
}
class _Bottombar extends StatelessWidget {
final PlaygroundPageController controller;
const _Bottombar({
required this.controller,
Key? key,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return PopScope(
canPop: false,
child: Container(
clipBehavior: Clip.antiAlias,
decoration: const BoxDecoration(
boxShadow: [AppShadow.shadowTop],
),
height: (72 + Get.mediaQuery.padding.bottom + 70) + (controller.animation.value * 500),
child: Stack(
children: [
Positioned(
bottom: 0,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
ToButton(
onPressed: () {
controller.isCollapsed.toggle();
controller.handleToggleExpanded();
},
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(0 + (24 * controller.animation.value)),
topRight: Radius.circular(0 + (24 * controller.animation.value)),
),
color: AppColors.red,
),
width: Get.width,
height: (72 + Get.mediaQuery.padding.bottom + 70),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Container(
margin: const EdgeInsets.fromLTRB(0, 8, 0, 0),
width: 100,
height: 10,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(24),
color: AppColors.grey2,
),
)
],
),
),
),
SizeTransition(
axisAlignment: 1.0,
sizeFactor: controller.animation,
child: Container(
width: Get.width,
height: 500,
color: AppColors.green1,
),
),
],
),
),
Positioned(
bottom: ((72 + Get.mediaQuery.padding.bottom) * controller.reverseAnimation.value) - (72 + Get.mediaQuery.padding.bottom),
child: Container(
padding: const EdgeInsets.fromLTRB(0, 16, 0, 0),
width: Get.width,
height: (72 + Get.mediaQuery.padding.bottom),
decoration: const BoxDecoration(
color: AppColors.grey,
boxShadow: [AppShadow.shadowTop],
),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
color: Colors.red,
width: sizing(20),
height: sizing(20),
padding: const EdgeInsets.fromLTRB(4, 8, 4, 0).toResponsive(),
),
SizedBox(width: sizing(20)),
Container(
color: Colors.red,
width: sizing(20),
height: sizing(20),
padding: const EdgeInsets.fromLTRB(4, 8, 4, 0).toResponsive(),
),
SizedBox(width: sizing(20)),
Container(
color: Colors.red,
width: sizing(20),
height: sizing(20),
padding: const EdgeInsets.fromLTRB(4, 8, 4, 0).toResponsive(),
),
SizedBox(width: sizing(20)),
Container(
color: Colors.red,
width: sizing(20),
height: sizing(20),
padding: const EdgeInsets.fromLTRB(4, 8, 4, 0).toResponsive(),
),
SizedBox(width: sizing(20)),
Container(
color: Colors.red,
width: sizing(20),
height: sizing(20),
padding: const EdgeInsets.fromLTRB(4, 8, 4, 0).toResponsive(),
),
],
),
),
),
],
),
),
);
}
}
controller
class PlaygroundPageController extends GetxController with GetTickerProviderStateMixin {
late AnimationController expandController;
late AnimationController collapseController;
late Animation<double> animation;
late Animation<double> reverseAnimation;
final isCollapsed = true.obs;
@override
void onInit() {
super.onInit();
prepareAnimations();
prepareReverseAnimations();
}
void handleToggleExpanded() {
if (!isCollapsed.value) {
expandController.forward();
collapseController.forward();
} else {
expandController.reverse();
collapseController.reverse();
}
}
void prepareAnimations() {
expandController = AnimationController(
vsync: this,
duration: const Duration(
milliseconds: 1500,
),
);
Animation<double> curve = CurvedAnimation(
parent: expandController,
curve: Curves.fastOutSlowIn,
);
animation = Tween(begin: 0.0, end: 1.0).animate(curve)..addListener(() => refresh());
}
void prepareReverseAnimations() {
collapseController = AnimationController(
vsync: this,
duration: const Duration(
milliseconds: 1500,
),
);
Animation<double> curve = CurvedAnimation(
parent: collapseController,
curve: Curves.fastOutSlowIn,
);
reverseAnimation = Tween(begin: 1.0, end: 0.0).animate(curve)..addListener(() => refresh());
}
}
本文标签: flutterHow to expand a widget from a small strip to full screen and collapse it backStack Overflow
版权声明:本文标题:flutter - How to expand a widget from a small strip to full screen and collapse it back? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1736624788a1945651.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论