Flutter自定义滑动面板插件sliding_up_panel_custom的使用
Flutter自定义滑动面板插件sliding_up_panel_custom的使用
sliding_up_panel_custom
重要提示: 这是一个基于 此项目 的分支,增加了一些新功能。目标是保持其与Dart语言变化同步。如果你有任何改进建议,请通过pull请求提交。
一个可拖动的Flutter小部件,使实现SlidingUpPanel变得更加容易!基于Material Design的底部面板组件,该小部件在Android和iOS上均可使用。
差异
与之前的 sliding_up_panel 版本相比,主要差异如下:
- PanelController通知监听器
- 可以更改面板的最大高度
- onAttached回调
- onPanelMaxHeightUpdated回调
安装
在你的 pubspec.yaml
文件中添加以下内容:
dependencies:
sliding_up_panel_custom: ^2.1.1+1
然后运行 flutter pub get
来安装依赖。
如何使用
访问 这里 查看详细的使用说明。
完整示例代码
以下是完整的示例代码,展示了如何使用 sliding_up_panel_custom
插件。
import 'dart:ui';
import 'package:flutter/material.dart';
import 'package:sliding_up_panel_custom/sliding_up_panel_custom.dart';
import 'package:flutter/services.dart';
import 'package:flutter_map/flutter_map.dart';
import 'package:latlong2/latlong.dart';
import 'package:cached_network_image/cached_network_image.dart';
void main() {
runApp(SlidingUpPanelExample());
}
class SlidingUpPanelExample extends StatelessWidget {
const SlidingUpPanelExample({super.key});
[@override](/user/override)
Widget build(BuildContext context) {
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle(
systemNavigationBarColor: Colors.grey[200],
systemNavigationBarIconBrightness: Brightness.dark,
systemNavigationBarDividerColor: Colors.black,
));
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'SlidingUpPanel Example',
theme: ThemeData(
primarySwatch: Colors.blue,
useMaterial3: true,
),
home: HomePage(),
);
}
}
class HomePage extends StatefulWidget {
const HomePage({super.key});
[@override](/user/override)
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
final _controller = PanelController();
final _initButtonPosition = 120.0;
double _buttonPosition = 0.0;
final _initPanelHeightOpen = 400.0;
final _initPanelHeightClosed = 95.0;
bool _isExpanded = false;
double _currentPanelMaxHeight = 0.0;
[@override](/user/override)
void initState() {
super.initState();
_buttonPosition = _initButtonPosition;
_currentPanelMaxHeight = _initPanelHeightOpen;
}
void _onUpdatePanelHeight() {
if (_isExpanded) {
_currentPanelMaxHeight = 400.0;
_controller.animatePanelToMaxHeight(400.0);
_isExpanded = false;
} else {
_currentPanelMaxHeight = 500.0;
_controller.animatePanelToMaxHeight(500.0);
_isExpanded = true;
}
}
[@override](/user/override)
Widget build(BuildContext context) {
return Material(
child: Stack(
alignment: Alignment.topCenter,
children: <Widget>[
// 滑动面板
SlidingUpPanel(
controller: _controller,
panelBuilder: (sc) => _panel(sc),
body: _body(),
options: SlidingUpPanelOptions(
initialMaxHeight: _initPanelHeightOpen,
initialMinHeight: _initPanelHeightClosed,
parallaxEnabled: true,
parallaxOffset: 0.5,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(18.0),
topRight: Radius.circular(18.0),
),
),
onPanelSlide: (double pos) {
setState(() {
_buttonPosition = pos * (_currentPanelMaxHeight - _initPanelHeightClosed) + _initButtonPosition;
});
},
onPanelOpened: () {
setState(() {
_buttonPosition = 1.0 * (_currentPanelMaxHeight - _initPanelHeightClosed) + _initButtonPosition;
});
},
onPanelMaxHeightUpdated: (double pos) {
setState(() {
_buttonPosition = pos + 25.0;
});
},
),
// 浮动按钮
Positioned(
right: 20.0,
bottom: _buttonPosition,
child: FloatingActionButton(
onPressed: _onUpdatePanelHeight,
backgroundColor: Colors.white,
child: Icon(
Icons.gps_fixed,
color: Theme.of(context).primaryColor,
),
),
),
// 顶部模糊效果
Positioned(
top: 0.0,
child: ClipRRect(
child: BackdropFilter(
filter: ImageFilter.blur(sigmaX: 10.0, sigmaY: 10.0),
child: Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).padding.top,
color: Colors.transparent,
),
),
),
),
// 标题栏
Positioned(
top: 52.0,
child: Container(
padding: EdgeInsets.fromLTRB(24.0, 18.0, 24.0, 18.0),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(24.0),
boxShadow: [
BoxShadow(
color: Color.fromRGBO(0, 0, 0, 0.25),
blurRadius: 16.0,
)
],
),
child: Text(
"SlidingUpPanel Example",
style: TextStyle(fontWeight: FontWeight.w500),
),
),
),
],
),
);
}
Widget _panel(ScrollController sc) {
return MediaQuery.removePadding(
context: context,
removeTop: true,
child: ListView(
controller: sc,
children: <Widget>[
SizedBox(height: 12.0),
Row(mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[
Container(
height: 5.0,
width: 30.0,
decoration: BoxDecoration(
color: Colors.grey[300],
borderRadius: BorderRadius.all(Radius.circular(12.0)),
),
),
]),
SizedBox(height: 18.0),
Row(mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[
Text(
"Explore Pittsburgh",
style: TextStyle(fontWeight: FontWeight.normal, fontSize: 24.0),
),
]),
SizedBox(height: 36.0),
Row(mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: <Widget>[
_button("Popular", Icons.favorite, Colors.blue),
_button("Food", Icons.restaurant, Colors.red),
_button("Events", Icons.event, Colors.amber),
_button("More", Icons.more_horiz, Colors.green),
]),
SizedBox(height: 36.0),
Container(
padding: EdgeInsets.only(left: 24.0, right: 24.0),
child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: <Widget>[
Text("Images", style: TextStyle(fontWeight: FontWeight.w600)),
SizedBox(height: 12.0),
Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: <Widget>[
CachedNetworkImage(
imageUrl: "https://images.fineartamerica.com/images-medium-large-5/new-pittsburgh-emmanuel-panagiotakis.jpg",
height: 120.0,
width: (MediaQuery.of(context).size.width - 48.0) / 2.0 - 2.0,
fit: BoxFit.cover,
),
CachedNetworkImage(
imageUrl: "https://cdn.pixabay.com/photo/2016/08/11/23/48/pnc-park-1587285_1280.jpg",
width: (MediaQuery.of(context).size.width - 48.0) / 2.0 - 2.0,
height: 120.0,
fit: BoxFit.cover,
),
]),
]),
),
SizedBox(height: 36.0),
Container(
padding: EdgeInsets.only(left: 24.0, right: 24.0),
child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: <Widget>[
Text("About", style: TextStyle(fontWeight: FontWeight.w600)),
SizedBox(height: 12.0),
Text(
"Pittsburgh is a city in the state of Pennsylvania in the United States, and is the county seat of Allegheny County. A population of about 302,407 (2018) residents live within the city limits, making it the 66th-largest city in the U.S. The metropolitan population of 2,324,743 is the largest in both the Ohio Valley and Appalachia, the second-largest in Pennsylvania (behind Philadelphia), and the 27th-largest in the U.S.\n\nPittsburgh is located in the southwest of the state, at the confluence of the Allegheny, Monongahela, and Ohio rivers. Pittsburgh is known both as \"the Steel City\" for its more than 300 steel-related businesses and as the \"City of Bridges\" for its 446 bridges. The city features 30 skyscrapers, two inclined railways, a pre-revolutionary fortification and the Point State Park at the confluence of the rivers. The city developed as a vital link of the Atlantic coast and Midwest, as the mineral-rich Allegheny Mountains made the area coveted by the French and British empires, Virginians, Whiskey Rebels, and Civil War raiders.\n\nAside from steel, Pittsburgh has led in manufacturing of aluminum, glass, shipbuilding, petroleum, foods, sports, transportation, computing, autos, and electronics. For part of the 20th century, Pittsburgh was behind only New York City and Chicago in corporate headquarters employment; it had the most U.S. stockholders per capita. Deindustrialization in the 1970s and 80s laid off area blue-collar workers as steel and other heavy industries declined, and thousands of downtown white-collar workers also lost jobs when several Pittsburgh-based companies moved out. The population dropped from a peak of 675,000 in 1950 to 370,000 in 1990. However, this rich industrial history left the area with renowned museums, medical centers, parks, research centers, and a diverse cultural district.\n\nAfter the deindustrialization of the mid-20th century, Pittsburgh has transformed into a hub for the health care, education, and technology industries. Pittsburgh is a leader in the health care sector as the home to large medical providers such as University of Pittsburgh Medical Center (UPMC). The area is home to 68 colleges and universities, including research and development leaders Carnegie Mellon University and the University of Pittsburgh. Google, Apple Inc., Bosch, Facebook, Uber, Nokia, Autodesk, Amazon, Microsoft and IBM are among 1,600 technology firms generating \$20.7 billion in annual Pittsburgh payrolls. The area has served as the long-time federal agency headquarters for cyber defense, software engineering, robotics, energy research and the nuclear navy. The nation's eighth-largest bank, eight Fortune 500 companies, and six of the top 300 U.S. law firms make their global headquarters in the area, while RAND Corporation (RAND), BNY Mellon, Nova, FedEx, Bayer, and the National Institute for Occupational Safety and Health (NIOSH) have regional bases that helped Pittsburgh become the sixth-best area for U.S. job growth.",
softWrap: true,
),
]),
),
SizedBox(height: 24.0),
],
),
);
}
Widget _button(String label, IconData icon, Color color) {
return Column(children: <Widget>[
Container(
padding: EdgeInsets.all(16.0),
decoration: BoxDecoration(
color: color,
shape: BoxShape.circle,
boxShadow: [
BoxShadow(
color: Color.fromRGBO(0, 0, 0, 0.15),
blurRadius: 8.0,
),
],
),
child: Icon(icon, color: Colors.white),
),
SizedBox(height: 12.0),
Text(label),
]);
}
Widget _body() {
return FlutterMap(
options: MapOptions(
initialCenter: LatLng(40.441589, -80.010948),
initialZoom: 13.0,
maxZoom: 15.0,
),
children: [
TileLayer(
urlTemplate: "https://maps.wikimedia.org/osm-intl/{z}/{x}/{y}.png",
),
MarkerLayer(
markers: [
Marker(
point: LatLng(40.441753, -80.011476),
height: 60,
child: Icon(
Icons.location_on,
color: Colors.blue,
size: 48.0,
),
),
],
),
],
);
}
}
更多关于Flutter自定义滑动面板插件sliding_up_panel_custom的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter自定义滑动面板插件sliding_up_panel_custom的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
sliding_up_panel_custom
是一个自定义的 Flutter 滑动面板插件,它允许你在应用程序中创建一个可以从底部滑出的面板。这个插件非常适用于需要显示额外信息或功能的场景,例如设置菜单、表单或详细信息面板。
安装
首先,你需要在 pubspec.yaml
文件中添加 sliding_up_panel_custom
依赖:
dependencies:
flutter:
sdk: flutter
sliding_up_panel_custom: ^1.0.0 # 请使用最新版本
然后运行 flutter pub get
来安装依赖。
基本用法
以下是一个简单的示例,展示了如何使用 sliding_up_panel_custom
插件:
import 'package:flutter/material.dart';
import 'package:sliding_up_panel_custom/sliding_up_panel_custom.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Sliding Up Panel Custom Example'),
),
body: SlidingUpPanelExample(),
),
);
}
}
class SlidingUpPanelExample extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(
children: [
// 主内容
Center(
child: Text('Main Content'),
),
// 滑动面板
SlidingUpPanelCustom(
panel: Center(
child: Text('Sliding Panel Content'),
),
collapsed: Container(
color: Colors.blue,
child: Center(
child: Text('Collapsed Panel'),
),
),
minHeight: 100.0,
maxHeight: 300.0,
),
],
),
);
}
}
参数说明
panel
: 这是滑动面板的主要内容部分。当面板完全展开时,显示的内容。collapsed
: 这是面板折叠时显示的内容。通常是一个简化的视图或提示。minHeight
: 面板的最小高度,即折叠时的高度。maxHeight
: 面板的最大高度,即完全展开时的高度。
自定义和高级用法
sliding_up_panel_custom
还提供了许多其他参数和回调函数,允许你进一步自定义面板的行为和外观。例如:
borderRadius
: 设置面板的圆角。color
: 设置面板的背景颜色。onPanelSlide
: 在面板滑动时触发的回调函数。onPanelOpened
: 当面板完全展开时触发的回调函数。onPanelClosed
: 当面板完全折叠时触发的回调函数。
示例:自定义面板滑动动画
SlidingUpPanelCustom(
panel: Center(
child: Text('Sliding Panel Content'),
),
collapsed: Container(
color: Colors.blue,
child: Center(
child: Text('Collapsed Panel'),
),
),
minHeight: 100.0,
maxHeight: 300.0,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(20.0),
topRight: Radius.circular(20.0),
),
color: Colors.white,
onPanelSlide: (double position) {
print('Panel position: $position');
},
onPanelOpened: () {
print('Panel opened');
},
onPanelClosed: () {
print('Panel closed');
},
)