先决条件
- Dart 编程语言的基础知识。
- 熟悉 Flutter 框架及其小部件。
- Flutter SDK 和 Android Studio 或 VS Code 的有效安装
- 了解有状态的小部件及其在 Flutter 应用程序中管理状态的作用。
- Flutter布局定位基础知识
- 熟悉在 Flutter 中使用图像资源。
教程
打开任一 IDE。创建一个 flutter 项目(应用程序)并将项目命名为您选择的任何名称。
创建项目后,在您的设备或模拟器上运行该应用程序。
下载三个支付平台的标识和对勾圆圈图标。我从谷歌上的图片下载了它们。
将四个图像添加到assets文件夹中,或者您可能需要在项目文件夹的根目录下创建文件夹。
assets/images/
将图像的路径添加到 pubspec.yaml
# To add assets to your application, add an assets section, like this:
assets:
- assets/images/visa.png
- assets/images/mastercard.png
- assets/images/paypal.png
- assets/images/tick-circle.png
在 main.dart 文件中,将您的代码替换为以下代码。该代码设置了一个基本的 Flutter 应用程序,主页上有一个应用程序栏和一个空容器。
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primaryColor: const Color(0xFF5C6ED1),
),
home: const HomePage(),
);
}
}
class HomePage extends StatefulWidget {
const HomePage({super.key});
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("Custom Radio Button Demo"),
),
body: Container();
}
}
该类HomePage是一个有状态的小部件,具有 类型的状态对象_HomePageState。此类的方法build()返回一个Scaffold小部件,它是应用程序的基本视觉结构。脚手架小部件有一个AppBar和一个body。标题AppBar带有文本“自定义单选按钮演示”,正文为空Container。
...
class _HomePageState extends State<HomePage> {
int selectedPayment = 0;
Widget CustomPaymentCardButton(String assetName, int index) {
return OutlinedButton(
onPressed: () {
setState(() {
selectedPayment = index;
});
},
style: OutlinedButton.styleFrom(
padding: const EdgeInsets.symmetric(horizontal: 5, vertical: 5),
shape:
RoundedRectangleBorder(borderRadius: BorderRadius.circular(10.0)),
side: BorderSide(
width: (selectedPayment == index) ? 2.0 : 0.5,
color: (selectedPayment == index)
? Colors.green
: Colors.blue.shade600),
),
child: Stack(
children: [
Center(
child: Image.asset(
assetName,
fit: BoxFit.contain,
width: 120,
height: 120,
),
),
if (selectedPayment == index)
Positioned(
top: 5,
right: 5,
child: Image.asset(
"assets/images/tick-circle.png",
width: 25,
fit: BoxFit.cover,
),
),
],
),
);
}
...
_HomePageState在which extends类里面State。有一个名为selectedPayment初始设置为 0 的变量。它用于跟踪所选的支付选项。有一个方法CustomPaymentCardButton有两个参数,assetName 和 index。assetName 是表示图像资产路径的字符串,index 是表示按钮在支付选项列表中的位置的整数。
该方法返回一个OutlinedButton小部件,它是一个带有轮廓边框的 Material Design 风格按钮。按钮的回调onPressed将 的值设置selectedPayment为按下的按钮的索引。
child按钮的属性是一个 Stack 小部件,其中包含一个带有Image.asset参数指定图像的小部件assetName。它还Stack包含一个 Positioned 小部件,如果按钮被选中,它会显示一个复选标记图标。
按钮的属性style用于根据是否选中来设置其填充、边框形状和颜色。如果按钮被选中,其边框宽度设置为 2.0,颜色设置为绿色。否则,其边框宽度设置为 0.5,颜色设置为蓝色。
...
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("Custom Radio Button Demo"),
),
body: Padding(
padding: const EdgeInsets.symmetric(horizontal: 20),
child: Column(
children: [
const SizedBox(
height: 20,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: CustomPaymentCardButton("assets/images/visa.png", 0),
),
const SizedBox(
width: 20,
),
Expanded(
child: CustomPaymentCardButton(
"assets/images/mastercard.png", 1),
),
],
),
const SizedBox(
height: 16,
),
CustomPaymentCardButton("assets/images/paypal.png", 2),
],
),
),
);
}
...
正文是使用Padding水平填充为 20 的小部件定义的。填充包含一个包含Column支付选项列表的小部件。
该Row小部件包含两个Expanded小部件,每个小部件都包含一个使用该CustomPaymentCardButton方法定义的自定义支付卡按钮。第一个按钮显示 Visa 卡的图像,索引为 0。第二个按钮显示万事达卡的图像,索引为 1。该小部件用于并排显示两个Row按钮宽度。
CustomPaymentCardButton使用 PayPal 徽标的图像和 2 的索引再次调用该方法,以显示 下方的第三个按钮Row。
整体代码如下:
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primaryColor: const Color(0xFF5C6ED1),
),
home: const HomePage(),
);
}
}
class HomePage extends StatefulWidget {
const HomePage({super.key});
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
int selectedPayment = 0;
Widget CustomPaymentCardButton(String assetName, int index) {
return OutlinedButton(
onPressed: () {
setState(() {
selectedPayment = index;
});
},
style: OutlinedButton.styleFrom(
padding: const EdgeInsets.symmetric(horizontal: 5, vertical: 5),
shape:
RoundedRectangleBorder(borderRadius: BorderRadius.circular(10.0)),
side: BorderSide(
width: (selectedPayment == index) ? 2.0 : 0.5,
color: (selectedPayment == index)
? Colors.green
: Colors.blue.shade600),
),
child: Stack(
children: [
Center(
child: Image.asset(
assetName,
fit: BoxFit.contain,
width: 120,
height: 120,
),
),
if (selectedPayment == index)
Positioned(
top: 5,
right: 5,
child: Image.asset(
"assets/images/tick-circle.png",
width: 25,
fit: BoxFit.cover,
),
),
],
),
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("Custom Radio Button Demo"),
),
body: Padding(
padding: const EdgeInsets.symmetric(horizontal: 20),
child: Column(
children: [
const SizedBox(
height: 20,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: CustomPaymentCardButton("assets/images/visa.png", 0),
),
const SizedBox(
width: 20,
),
Expanded(
child: CustomPaymentCardButton(
"assets/images/mastercard.png", 1),
),
],
),
const SizedBox(
height: 16,
),
CustomPaymentCardButton("assets/images/paypal.png", 2),
],
),
),
);
}
}
运行应用程序。
整体代码创建了一个应用程序,该应用程序显示可以选择的自定义支付卡按钮,并显示所选支付选项的刻度线。
结论
总之,自定义单选按钮可以提供一种增强 Flutter 应用程序用户体验的好方法。通过使用自定义小部件并仔细选择视觉提示,您可以创建突出的单选按钮并将其目的传达给您的用户。