Flutter组件 StatefulWidget、StatelessWidget 可继承写法
前言
学过Java的同学,应该都知道面向对象语言的三大特征,封装、继承、多态;
Dart也是面向对象的语言,但是在Flutter中的很多组件都被下划线 '_' 标记为私有,导致无法继承,本文将介绍一种非私有的创建组件写法。
当前案例 Flutter SDK版本:3.13.2
效果图
StatefulWidget
基类:base_stateful_widget.dart
import 'package:flutter/material.dart';
class BaseStatefulWidget extends StatefulWidget {
final Map<String,dynamic>? arguments;
const BaseStatefulWidget({super.key,this.arguments});
@override
State<BaseStatefulWidget> createState() => BaseStatefulWidgetState();
}
class BaseStatefulWidgetState<T extends StatefulWidget> extends State<BaseStatefulWidget> {
@override
Widget build(BuildContext context) {
return const Placeholder();
}
}
创建第一个非私有的StatefulWidget组件:parent_box.dart
import 'package:flutter/material.dart';
import 'package:flutter_widget_extends/base/base_stateful_widget.dart';
class ParentBox extends BaseStatefulWidget {
const ParentBox({super.key,super.arguments});
@override
ParentBoxState<ParentBox> createState() => ParentBoxState();
}
class ParentBoxState<T extends ParentBox> extends BaseStatefulWidgetState<ParentBox> {
@override
Widget build(BuildContext context) {
final size = double.parse((widget.arguments?['size'] ?? 50).toString());
return Container(
width: size,
height: size,
margin: const EdgeInsets.only(bottom: 12),
color: Colors.green,
alignment: Alignment.center,
child: content(),
);
}
content() {
final content = widget.arguments?['content'];
return Text(content,
style: const TextStyle(
fontSize: 20,
color: Colors.yellow,
));
}
}
子类:child_box.dart
import 'package:flutter/material.dart';
import 'package:flutter_widget_extends/widget/parent_box.dart';
class ChildBox extends ParentBox {
const ChildBox({super.key,super.arguments});
@override
ChildBoxState<ChildBox> createState() => ChildBoxState();
}
class ChildBoxState<T extends ChildBox> extends ParentBoxState<ChildBox> {
@override
content() {
final content = widget.arguments?['content'];
return Text(content,
style: const TextStyle(
fontSize: 20,
color: Colors.white,
));
}
}
子孙类:posterity_box.dart
import 'package:flutter/material.dart';
import 'package:flutter_widget_extends/widget/child_box.dart';
class PosterityBox extends ChildBox {
const PosterityBox({super.key,super.arguments});
@override
ChildBoxState<ChildBox> createState() => PosterityBoxState();
}
class PosterityBoxState<T extends PosterityBox> extends ChildBoxState<PosterityBox> {
@override
content() {
final content = widget.arguments?['content'];
return Text(content,
style: const TextStyle(
fontSize: 20,
color: Colors.black,
));
}
}
StatelessWidget
基类:base_stateless_widget.dart
import 'package:flutter/material.dart';
class BaseStatelessWidget extends StatelessWidget {
final Map<String,dynamic>? arguments;
const BaseStatelessWidget({super.key, this.arguments});
@override
Widget build(BuildContext context) {
return const Placeholder();
}
}
创建第一个非私有的StatelessWidget组件:school_box.dart
import 'package:flutter/material.dart';
import 'package:flutter_widget_extends/base/base_stateless_widget.dart';
class SchoolBox extends BaseStatelessWidget {
const SchoolBox({super.key,super.arguments});
@override
Widget build(BuildContext context) {
final size = double.parse((arguments?['size'] ?? 50).toString());
return Container(
width: size,
height: size,
margin: const EdgeInsets.only(bottom: 12),
color: Colors.cyan,
alignment: Alignment.center,
child: content(),
);
}
content() {
final content = arguments?['content'];
return Text(content,
style: const TextStyle(
fontSize: 20,
color: Colors.white,
));
}
}
子类:teacher_box.dart
import 'package:flutter/material.dart';
import 'package:flutter_widget_extends/widget/school_box.dart';
class TeacherBox extends SchoolBox {
const TeacherBox({super.key,super.arguments});
@override
content() {
final content = arguments?['content'];
return Text(content,
style: const TextStyle(
fontSize: 20,
color: Colors.yellow,
));
}
}
子孙类:student_box.dart
import 'package:flutter/material.dart';
import 'package:flutter_widget_extends/widget/teacher_box.dart';
class StudentBox extends TeacherBox {
const StudentBox({super.key,super.arguments});
@override
content() {
final content = arguments?['content'];
return Text(content,
style: const TextStyle(
fontSize: 20,
color: Colors.greenAccent,
));
}
}
入口相关文件:test_stateful_widget.dart、test_stateless_widget.dart、main.dart
import 'package:flutter/material.dart';
import '../widget/child_box.dart';
import '../widget/parent_box.dart';
import '../widget/posterity_box.dart';
class TestStatefulWidget extends StatefulWidget {
const TestStatefulWidget({super.key});
@override
State<TestStatefulWidget> createState() => _TestStatefulWidgetState();
}
class _TestStatefulWidgetState extends State<TestStatefulWidget> {
@override
Widget build(BuildContext context) {
return Scaffold(
body: SizedBox(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
child: const Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
ParentBox(arguments: {
'size': 260,
'content': '父级',
}),
ChildBox(arguments: {
'size': 200,
'content': '子级',
}),
PosterityBox(arguments: {
'size': 150,
'content': '子孙级',
}),
],
),
),
);
}
}
import 'package:flutter/material.dart';
import 'package:flutter_widget_extends/widget/school_box.dart';
import 'package:flutter_widget_extends/widget/student_box.dart';
import 'package:flutter_widget_extends/widget/teacher_box.dart';
class TestStatelessWidget extends StatefulWidget {
const TestStatelessWidget({super.key});
@override
State<TestStatelessWidget> createState() => _TestStatelessWidgetState();
}
class _TestStatelessWidgetState extends State<TestStatelessWidget> {
@override
Widget build(BuildContext context) {
return Scaffold(
body: SizedBox(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
child: const Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
SchoolBox(arguments: {
'size': 150,
'content': '父级',
}),
TeacherBox(arguments: {
'size': 200,
'content': '子级',
}),
StudentBox(arguments: {
'size': 260,
'content': '子孙级',
}),
],
),
),
);
}
}
import 'package:flutter/material.dart';
import 'package:flutter_widget_extends/page/test_stateful_widget.dart';
import 'package:flutter_widget_extends/page/test_stateless_widget.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter Demo',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
body: SizedBox(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Padding(
padding: const EdgeInsets.only(bottom: 16),
child: ElevatedButton(
onPressed: () {
Navigator.push<void>(
context,
MaterialPageRoute<void>(
builder: (BuildContext context) =>
const TestStatefulWidget(),
),
);
},
child: const Text(
'TestStatefulWidget',
style: TextStyle(fontSize: 16),
),
),
),
ElevatedButton(
onPressed: () {
Navigator.push<void>(
context,
MaterialPageRoute<void>(
builder: (BuildContext context) =>
const TestStatelessWidget(),
),
);
},
child: const Text(
'TestStatelessWidget',
style: TextStyle(fontSize: 16),
),
)
],
),
),
);
}
}
源码地址
GitHub - LanSeLianMa/flutter_widget_extends: Flutter组件 StatefulWidget、StatelessWidget 可继承写法