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 可继承写法

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值