Flutter组件 StatefulWidget、StatelessWidget 可继承写法

news2024/11/17 7:36:26

前言

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1429052.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

大数据-Spark-关于Json数据格式的数据的处理与练习

上一篇&#xff1a; 大数据-MapReduce-关于Json数据格式的数据的处理与练习-CSDN博客 16.7 Json在Spark中的引用 依旧利用上篇的数据去获取每部电影的平均分 {"mid":1,"rate":6,"uid":"u001","ts":15632433243} {"m…

Qt/C++音视频开发66-音频变速不变调/重采样/提高音量/变速变调/倍速播放/sonic库使用

一、前言 之前在做倍速这个功能的时候&#xff0c;发现快速播放会有滴滴滴的破音出现&#xff0c;正常1倍速没有这个问题&#xff0c;尽管这个破音间隔很短&#xff0c;要放大音量才能听到&#xff0c;但是总归是不完美的&#xff0c;后面发现&#xff0c;通过修改qaudiooutpu…

centOS/Linux系统安全加固方案手册

服务器系统:centos8.1版本 说明:该安全加固手册最适用版本为centos8.1版本,其他服务器系统版本可作为参考。 1.账号和口令 1.1 禁用或删除无用账号 减少系统无用账号,降低安全风险。 操作步骤  使用命令 userdel <用户名> 删除不必要的账号。  使用命令 passwd…

ubuntu 上安装和配置Apache2+Subversion

目录 一、安装Apache2和SVN 二、Apache2设置 三、subversion配置 四、创建仓库和设置权限 五、仓库备份和恢复 系统环境 Ubuntu Linux (20.04) apache2 Subversion(1.13.0) 一、安装Apache2和SVN 通过命令在线安装apache2和subversion apt-get install apache2 libap…

Datax问题记录

1、同步mysql&#xff1a;OS errno 24 - Too many open files 2023-11-20 12:30:04.371 [job-0] ERROR JobContainer - Exception when job run com.alibaba.datax.common.exception.DataXException: Code:[DBUtilErrorCode-07], Description:[读取数据库数据失败. 请检查您的…

颐和园龙纹珍宝展亮相,文物预防保护科技护航

在皇家园林颐和园的深处&#xff0c;一场独特的文化盛宴正静静上演。2月1日&#xff0c;“祥龙贺岁—颐和园藏龙纹题材文物特展”在德和园华丽揭幕。此次特展汇聚了66件珍贵文物&#xff0c;包括玉器、瓷器、书画、珐琅、家具等&#xff0c;每一件都是颐和园园藏的瑰宝。这些文…

LLM应用开发与落地:使用gradio十分钟搭建聊天UI

一、背景 如果你是做LLM应用开发的&#xff0c;特别是做后端开发&#xff0c;你一定会遇到怎么快速写一个聊天UI界面来调试prompt或agent的问题。这时候的你可能在苦恼中&#xff0c;毕竟react.js, next.js, css, html也不是每个人都那么熟练&#xff0c;对吧&#xff1f;即使…

pyqt5-QCheckBox控件使用介绍

一、简介 作用&#xff1a;用于给用户提供若干选项中的多选操作&#xff0c;比如&#xff1a;爱好可以有多个 等等。 继承自 QAbstractButton。 1、基础工程 from PyQt5.Qt import * import sysapp QApplication(sys.argv)window QWidget()window.setWindowTitle("Q…

一文掌握SpringBoot注解之@Configuration知识文集(3)

&#x1f3c6;作者简介&#xff0c;普修罗双战士&#xff0c;一直追求不断学习和成长&#xff0c;在技术的道路上持续探索和实践。 &#x1f3c6;多年互联网行业从业经验&#xff0c;历任核心研发工程师&#xff0c;项目技术负责人。 &#x1f389;欢迎 &#x1f44d;点赞✍评论…

【ADI 知识库】 AN-1354:集成式ZIF、RF至比特、LTE、广域接收机分析和测试结果

官方链接&#xff1a; https://www.analog.com/cn/resources/app-notes/an-1354.html 简介 本应用笔记参考了3GPP TS 36系列文件和ADI公司的多种数据手册、特性标定报告和实验室测试结果。本文重点关注基于集成式零中频(ZIF)、RF至比特、IC (AD9371)的多载波广域LTE接收机的性…

使用css绘制小三角形

要使用CSS绘制小三角形&#xff0c;您可以使用border属性来设置边框样式。下面是一种常见的绘制小三角形的方法&#xff1a; <style>.box {width: 0;height: 0;/* border-top: 10px solid red; */border-bottom: 10px solid blue;border-left: 10px solid transparent;b…

2024PMP考试新考纲-【业务环境领域】典型真题和很详细解析(3)

华研荟继续分享【业务环境Business Environment领域】在新考纲下的真题&#xff0c;帮助大家体会和理解新考纲下PMP的考试特点和如何应用所学的知识和常识&#xff08;经验&#xff09;来解题&#xff0c;并且举一反三&#xff0c;一次性3A通过2024年PMP考试。 2024年PMP考试新…

Interpolator:在Android中方便使用一些常见的CubicBezier贝塞尔曲线动画效果

说明 方便在Android中使用Interpolator一些常见的CubicBezier贝塞尔曲线动画效果。 示意图如下 import android.view.animation.Interpolator import androidx.core.view.animation.PathInterpolatorCompat/*** 参考* android https://yisibl.github.io/cubic-bezier* 实现常…

在flutter中集成Excel导入和导出

flutter中集成Excel导入和导出功能 1、需要的依赖 在pubspec.yaml #excel导出syncfusion_flutter_xlsio: ^24.1.45open_file: ^3.0.1#导入excelflutter_excel: ^1.0.1#选择文件的依赖file_picker: ^6.1.1&#xff08;1&#xff09;依赖说明 在测试时&#xff0c;我们在使用导…

MySQL学习记录——일 MySQL 安装、配置

文章目录 1、卸载内置环境2、安装MySQL3、启动4、登录5、配置my.cnf 当前环境是1核2G云服务器&#xff0c;CentOS7.6 1、卸载内置环境 云服务器中有可能会自带mysql还有mariadb这样的数据库服务&#xff0c;在安装我们mysql前&#xff0c;得先查找一下是否有。 ps ajx |grep m…

20240202在WIN10下使用whisper.cpp

20240202在WIN10下使用whisper.cpp 2024/2/2 14:15 【结论&#xff1a;在Windows10下&#xff0c;确认large模式识别7分钟中文视频&#xff0c;需要83.7284 seconds&#xff0c;需要大概1.5分钟&#xff01;效率太差&#xff01;】 83.7284/4200.1993533333333333333333333333…

Latex学习记录

目录 1.Latex各种箭头符号总结 2.[Latex]公式编辑&#xff0c;编号、对齐 3.Latex公式编号: 多行公式多编号&#xff0c;多行公式单编号 4.LaTex中输入空格以及换行 1.Latex各种箭头符号总结 箭头符号 - ➚ (piliapp.com)https://cn.piliapp.com/symbol/arrow/Latex各种箭头…

【algorithm】一个简单的PID工程 base 用于手生时候快速复习 用于设计模式 cpp语法八股 快速复习校验

写在前面 最近项目一直用matlab&#xff0c;防止手生整一个回忆工具使用的简单的pid demo&#xff0c;走一边流程&#xff0c;包括配工程debug看结果&#xff0c;复用之前记录的配置见我的bloghttps://blog.csdn.net/weixin_46479223/article/details/135082867?csdn_share_t…

Faster-Whisper 实时识别电脑语音转文本

Faster-Whisper 实时识别电脑语音转文本 前言项目搭建环境安装Faster-Whisper下载模型编写测试代码运行测试代码实时转写脚本 参考 前言 以前做的智能对话软件接的Baidu API&#xff0c;想换成本地的&#xff0c;就搭一套Faster-Whisper吧。 下面是B站视频实时转写的截图 项…

thinkphp项目之composer快速安装使用

引言 由于项目的需求&#xff0c;thinkphp项目使用到composer。网上搜索有一堆的教程使用&#xff0c;根据自己的需要摸索了下。 步骤 1. 安装phpstudy v8&#xff0c;这个经常用的运行环境&#xff0c;方便好多开发者。安装教程一步一步到最后就行。 2. 安装composer组件&a…