当前位置:网站首页>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(),
),
),
);
}),
);
}边栏推荐
- Before creating an image, it is recommended to execute the following code to purify the image as an administrator
- The principle of defer keyword in go
- CTF learning notes 18:iwesec file upload vulnerability-03-content-type filtering bypass
- Redis pipeline technology speed and efficiency increased by 5 times
- Introduction à la méthode de descente par Gradient - document d'apprentissage automatique pour les programmeurs de chevaux noirs
- Medical industry EDI overview
- Detailed explanation of the process after the browser enters the domain name and web address
- Bi-sql insert into
- How are ECS leased? Can the ECS use VPN?
- Customer disaster recovery case - a MySQL database migration scheme
猜你喜欢

解析后人类时代类人机器人的优越性

Facebook internal announcement: instant messaging will be re integrated

少儿编程教育在特定场景中的普及作用

SAP mts/ato/mto/eto topic 7: ATO mode 1 m+m mode strategy 82 (6892)

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

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

Leetcode (question 2) - adding two numbers

Analyzing the superiority of humanoid robot in the post human era

『应急响应实践』LogParser日志分析实践

『渗透基础』Cobalt Strike基础使用入门_Cobalt Strike联动msfconsole
随机推荐
What is the new generation cloud computing architecture cipu of Alibaba cloud?
Leetcode (question 1) - sum of two numbers
Before creating an image, it is recommended to execute the following code to purify the image as an administrator
MySQL cases MySQL find out who holds the row lock (RC)
Leetcode (question 2) - adding two numbers
Develop a customized music player from scratch, and your girlfriend will have it?
What's wrong with the failure of uploading web pages to ECS? How many kinds of servers are there
解析后人类时代类人机器人的优越性
Svg quick start small white article
Integration of Alibaba cloud SMS services and reasons for illegal message signing
Introduction to ebpf
Pg-pool-ii read / write separation experience
Jimureport building block report - what problems does the layout design solve?
How to build a website for ECS? What are the prices of different ECS
CTF learning notes 17:iwesec file upload vulnerability-02 file name filtering bypass
What is the domain name of the website? How much is a domain name
cuDNN installation
What is stored in the domain name server? How does the domain name server provide services?
RedHat 8 time synchronization and time zone modification
How the query address of cloud native monitoring data exposes the public network