当前位置:网站首页>Shuttle global levitation button
Shuttle global levitation button
2022-06-24 05:04:00 【nuts】
Method 1
Offset _offset = Offset.zero;
Scaffold(
body: Stack(
children: [
_pageList[_currentIndex],
Positioned(
left: _offset.dx,
top: _offset.dy,
child: GestureDetector(
onPanUpdate: (d) =>
setState(() => _offset += Offset(d.delta.dx, d.delta.dy)),
child: FloatingActionButton(
onPressed: () {},
backgroundColor: Colors.orange,
child: Icon(Icons.add),
),
),
),
],
),Method 2
WidgetsBinding.instance
.addPostFrameCallback((_) => _insertOverlay(context));void _insertOverlay(BuildContext context) {
return Overlay.of(context).insert(
OverlayEntry(builder: (context) {
final size = MediaQuery.of(context).size;
print(size.width);
return Positioned(
width: 56,
height: 56,
top: size.height - 72,
left: size.width - 72,
child: Material(
color: Colors.transparent,
child: GestureDetector(
onTap: () => print('ON TAP OVERLAY!'),
child: Container(
decoration: BoxDecoration(
shape: BoxShape.circle, color: Colors.redAccent),
),
),
),
);
}),
);
}Method 3
1. scene Now we need to make a Test Button , Hover over all pages , And you can drag .
2. Ideas 1) The hover button can be used flutter Provided Overlay + OverlayEntry Combination to achieve
2) The drag and drop function can be used GestureDetector Gesture buttons or Draggable Realization (PS: I made a version Draggable Realized , But I found that it will have the original widget Float in place , Obviously not the effect I want )
3) When I click, I make it pop up a pop-up box at the bottom , Here you can play freely , This article will not be redundant
PubScaffold(
child: MaterialApp(
theme: CustomTheme.lightTheme,
darkTheme: CustomTheme.darkTheme,
themeMode: currentTheme.currentTheme,
home: Scaffold(
body: Stack(
children: [
_pageList[_currentIndex],
// Positioned(
// left: _offset.dx,
// top: _offset.dy,
// child: GestureDetector(
// onPanUpdate: (d) =>
// setState(() => _offset += Offset(d.delta.dx, d.delta.dy)),
// child: FloatingActionButton(
// onPressed: () {},
// backgroundColor: Colors.orange,
// child: Icon(Icons.add),
// ),
// ),
// ),
],
),
bottomNavigationBar: CurvedNavigationBar(
// key: _bottomNavigationKey,
index: 0,
height: 60.0,
items: <Widget>[
Icon(Icons.home, size: 30),
Icon(Icons.list, size: 30),
Icon(Icons.compare_arrows, size: 30),
// Icon(Icons.call_split, size: 30),
],
color: Colors.white,
buttonBackgroundColor: Colors.white,
backgroundColor: Colors.blueAccent,
animationCurve: Curves.easeInOut,
animationDuration: Duration(milliseconds: 600),
onTap: (index) {
setState(() {
_currentIndex = index;
});
},
// letIndexChange: (index) => true,
),
),
),
); there PubScaffold It's a floating button component I encapsulated , Wrap it in MaterialApp outside , You can achieve a button suspended on all components ( Of course, it can not be a button , Specific styles can be defined by yourself ). So let's see PubScaffold Code in ~
import 'dart:math';
import 'package:flutter/material.dart';
class PubScaffold extends StatefulWidget {
final Widget child;
PubScaffold({this.child});
@override
_PubScaffoldState createState() => _PubScaffoldState();
}
class _PubScaffoldState extends State<PubScaffold> {
bool draggable = false;
// At rest offset
Offset idleOffset = Offset(0, 0);
// The of this move offset
Offset moveOffset = Offset(0, 0);
// The last time down The event offset
Offset lastStartOffset = Offset(0, 0);
int count = 0;
final List<String> testWidgetList = [
' test 1',
' test 2',
];
testAppFun(e) {
// TODO: Your code logic
}
// Show a pop-up window at the bottom , Here is a list of tests
showTestList() {
showModalBottomSheet(
context: context,
enableDrag: false,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(20.0),
topRight: Radius.circular(20.0),
),
),
builder: (BuildContext context) {
return ListView(
children: testWidgetList
.map(
(e) => Container(
decoration: BoxDecoration(
border: Border(
bottom: BorderSide(color: Color(0xFFe3e3e3)),
),
),
child: ListTile(
onTap: () => testAppFun(e),
title: Text(e),
),
),
)
.toList(),
);
},
);
}
@override
Widget build(BuildContext context) {
return LayoutBuilder(
builder: (context, constraints) {
// Display the hover button
WidgetsBinding.instance
.addPostFrameCallback((_) => _insertOverlay(context));
return widget.child;
},
);
}
// Hover button , Drag and drop ( Customizable styles )
void _insertOverlay(BuildContext context) {
return Overlay.of(context).insert(
OverlayEntry(builder: (context) {
final size = MediaQuery.of(context).size;
print(size.width);
return Positioned(
top: draggable ? moveOffset.dy : size.height - 102,
left: draggable ? moveOffset.dx : size.width - 72,
child: GestureDetector(
// Move start
onPanStart: (DragStartDetails details) {
setState(() {
lastStartOffset = details.globalPosition;
draggable = true;
});
if (count <= 1) {
count++;
}
},
// Moving
onPanUpdate: (DragUpdateDetails details) {
setState(() {
moveOffset =
details.globalPosition - lastStartOffset + idleOffset;
if (count > 1) {
moveOffset = Offset(max(0, moveOffset.dx), moveOffset.dy);
} else {
moveOffset = Offset(max(0, moveOffset.dx + (size.width - 72)),
moveOffset.dy + (size.height - 102));
}
});
},
// End of move
onPanEnd: (DragEndDetails detail) {
setState(() {
idleOffset = moveOffset * 1;
});
},
child: TestContainer(
onPress: () => showTestList(),
),
),
);
}),
);
}
}
// The style of the hover button
class TestContainer extends StatelessWidget {
final Function onPress;
TestContainer({this.onPress});
@override
Widget build(BuildContext context) {
return Material(
color: Colors.transparent,
child: GestureDetector(
onTap: onPress,
child: Container(
width: 56,
height: 56,
alignment: Alignment.center,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: Colors.green[600],
),
child: Text(
"Test",
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
),
),
),
),
);
}
}
1. Global hover button
Here we use flutter Self contained material In the library Overlay Components , The specific use method is as follows :
void _insertOverlay(BuildContext context) {
return Overlay.of(context).insert(
OverlayEntry(builder: (context) {
final size = MediaQuery.of(context).size;
print(size.width);
return Positioned(
top: draggable ? moveOffset.dy : size.height - 102,
left: draggable ? moveOffset.dx : size.width - 72,
child: GestureDetector(
// Move start
onPanStart: (DragStartDetails details) {
setState(() {
lastStartOffset = details.globalPosition;
draggable = true;
});
if (count <= 1) {
count++;
}
},
// Moving
onPanUpdate: (DragUpdateDetails details) {
setState(() {
moveOffset =
details.globalPosition - lastStartOffset + idleOffset;
if (count > 1) {
moveOffset = Offset(max(0, moveOffset.dx), moveOffset.dy);
} else {
moveOffset = Offset(max(0, moveOffset.dx + (size.width - 72)),
moveOffset.dy + (size.height - 102));
}
});
},
// End of move
onPanEnd: (DragEndDetails detail) {
setState(() {
idleOffset = moveOffset * 1;
});
},
child: TestContainer(
onPress: () => showTestList(),
),
),
);
}),
);
}边栏推荐
- Bi-sql where
- Develop a customized music player from scratch, and your girlfriend will have it?
- Bi-sql - Select
- Ext4 file system jam caused by MEM CGroup OOM
- Customer disaster recovery case - a MySQL database migration scheme
- 『渗透基础』Cobalt Strike基础使用入门_Cobalt Strike联动msfconsole
- Spirit breath development log (16)
- mini-Web框架:装饰器方式的添加路由 | 黑马程序员
- Understanding OAuth 2.0
- Here's all you want to know about takin data (1) startup command
猜你喜欢

阿里云新一代云计算体系架构 CIPU 到底是啥?

Analyzing the superiority of humanoid robot in the post human era

Recognize workplus again, not only im but also enterprise mobile application management expert

011_ Cascader cascade selector

What are the disadvantages of the free IP address replacement tool?

Idea creates a servlet and accesses the 404 message

线性回归的损失和优化,机器学习预测房价

Introduction to the "penetration foundation" cobalt strike Foundation_ Cobalt strike linkage msfconsole

阿里云混合云首席架构师张晓丹:政企混合云技术架构的演进和发展

少儿编程教育在特定场景中的普及作用
随机推荐
Bi-sql order by
Tencent cloud audio and video award-winning evaluation | leave online messages or submit evaluation, win Dajiang UAV /iphone/switch and other awards
Why domain name should be resolved? What is the domain name registration query
What is an evpn switch?
Where can I buy a domain name? Does the domain name have promotion space?
What are the functions of ASP files on ECs? What if the ECS cannot run ASP with a low version?
少儿编程教育在特定场景中的普及作用
Bi-sql where
Detailed explanation of the process after the browser enters the domain name and web address
Bi-sql basic cognition
What are the functions and advantages of the Internet of things cloud platform?
Use of golang testing framework goshub
Real time monitoring: system and application level real-time monitoring based on flow computing Oceanus (Flink)
mini-Web框架:装饰器方式的添加路由 | 黑马程序员
What is the implementation of domain name to IP address conversion? What are the benefits of switching to a website?
How novices choose ECs and how to judge the quality of ECS
Activity recommendation | cloud native community meetup phase VII Shenzhen station begins to sign up!
Deep learning NLP from RNN LSTM Gru seq2seq to attention classification and analysis
Medical industry EDI overview
What is the secondary domain name of the website? What is the relationship between the secondary domain name and the primary domain name?