flutter 五点一:MaterialApp Theme

news2024/12/23 22:38:06

ThemeData

  factory ThemeData({
    bool? applyElevationOverlayColor,  //material2的darkTheme下 增加一个半透明遮罩 来凸显阴影效果  material3下无效   貌似没啥用
    NoDefaultCupertinoThemeData? cupertinoOverrideTheme,  //ios组件样式  
    Iterable<ThemeExtension<dynamic>>? extensions,  //自定义颜色  可用于统一颜色处理
    InputDecorationTheme? inputDecorationTheme,   //TextField的主题样式
    MaterialTapTargetSize? materialTapTargetSize,   //配置可点击的weight 的点击目标和布局大小
    PageTransitionsTheme? pageTransitionsTheme,  //定义页面过度动画
    ...
}

extensions

  • Iterable<ThemeExtension>? extensions
  • 自定义颜色 可用于统一颜色处理 (定一个常量类不是更简单么 em…)
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';

main(){
  runApp(const MyApp());
}

class MyApp extends StatelessWidget{

  const MyApp();

  @override
  Widget build(BuildContext context) {
//定义不同的ThemeData
    ThemeData themeRed = ThemeData.light().copyWith(
      extensions: <ThemeExtension<ThemeColors>>[ThemeColors(themeType: 0)],
    );

    ThemeData themeGreen = ThemeData.light().copyWith(
      extensions: <ThemeExtension<ThemeColors>>[ThemeColors(themeType: 1)],
    );

    ThemeData themeBlue = ThemeData.light().copyWith(
      extensions: <ThemeExtension<ThemeColors>>[ThemeColors(themeType: 2)],
    );

     return MaterialApp(
        theme: themeBlue,   //使用ThemeData  显示不同的颜色
        home: A(),
     );
  }

  void changeTheme(){

  }
}

class ThemeColors extends ThemeExtension<ThemeColors>{

  static String main_color = "main_color";
  static String text_color = "text_color";
  static String text_background = "text_background";

  var themeType = 0;

  var themeRed = {
    main_color:Colors.red,
    text_color:const Color(0xFFD26161),
    text_background:const Color(0xFFEAE4E4),
  };

  var themeGreen = {
    main_color:Colors.green,
    text_color:const Color(0xFF6EDC9A),
    text_background:const Color(0xFFEAE4E4),
  };

  var themeBlue = {
    main_color:Colors.blue,
    text_color:const Color(0xFF6F83E7),
    text_background:const Color(0xFFEAE4E4),
  };


  ThemeColors({this.themeType = 0});
  ThemeColors.themeRed(this.themeRed);
  ThemeColors.themeGreen(this.themeGreen);
  ThemeColors.themeBlue(this.themeBlue);

  @override
  ThemeExtension<ThemeColors> copyWith() {
    var result = null;
    switch(this.themeType){
      case 0:
        result = ThemeColors.themeRed(themeRed);
        break;
      case 1:
        result = ThemeColors.themeGreen(themeGreen);
        break;
      case 2:
        result = ThemeColors.themeBlue(themeBlue);
        break;
    }

    return result;
  }

  @override
  ThemeExtension<ThemeColors> lerp(covariant ThemeExtension<ThemeColors>? other, double t) {
     if(other !is ThemeColors){
        return this;
     }
     var result = null;
     switch(this.themeType){
       case 0:
         result = ThemeColors.themeRed(themeRed);
         break;
       case 1:
         result = ThemeColors.themeGreen(themeGreen);
         break;
       case 2:
         result = ThemeColors.themeBlue(themeBlue);
         break;
     }

     return result;
  }

  Color getColor(String colorName){
    var resultMap = null;
    switch(this.themeType){
      case 0:
        resultMap = themeRed;
        break;
      case 1:
        resultMap = themeGreen;
        break;
      case 2:
        resultMap = themeBlue;
        break;
    }
    return resultMap[colorName];
  }
  
}


class A extends StatefulWidget{

  A(){
    print("A页面启动!");
  }

  @override
  State<StatefulWidget> createState() => AState();
}

class AState extends State<A>{
  @override
  Widget build(BuildContext context) {
    ThemeColors themeColors = Theme.of(context).extension<ThemeColors>()??ThemeColors(themeType: 0);

    return Scaffold(
      backgroundColor: themeColors.getColor(ThemeColors.main_color),  //背景色使用主题的颜色
    );
  }
}

结果
theme: themeRed, //红色
theme: themeGreen, //绿色
theme: themeBlue, //蓝色
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

inputDecorationTheme

  • 输入框的样式 定义输入框各种显示样式及交互样式
 ThemeData themeBlue = ThemeData.light().copyWith(
      extensions: <ThemeExtension<ThemeColors>>[ThemeColors(themeType: 2)],
      inputDecorationTheme: InputDecorationTheme(
        labelStyle: TextStyle(color: Colors.black),  //黑字
        hintStyle: TextStyle(color: Colors.grey),  //hint字体 灰色
        border: UnderlineInputBorder(),    //底部划线边框
        focusedBorder: UnderlineInputBorder(),
      )
    );

属性

const InputDecorationTheme({
    this.labelStyle,
    this.floatingLabelStyle,
    this.helperStyle,
    this.helperMaxLines,
    this.hintStyle,
    this.errorStyle,
    this.errorMaxLines,
    this.floatingLabelBehavior = FloatingLabelBehavior.auto,
    this.floatingLabelAlignment = FloatingLabelAlignment.start,
    this.isDense = false,
    this.contentPadding,
    this.isCollapsed = false,
    this.iconColor,
    this.prefixStyle,
    this.prefixIconColor,
    this.suffixStyle,
    this.suffixIconColor,
    this.counterStyle,
    this.filled = false,
    this.fillColor,
    this.activeIndicatorBorder,
    this.outlineBorder,
    this.focusColor,
    this.hoverColor,
    this.errorBorder,
    this.focusedBorder,
    this.focusedErrorBorder,
    this.disabledBorder,
    this.enabledBorder,
    this.border,
    this.alignLabelWithHint = false,
    this.constraints,
  });

![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/7

在这里插入图片描述

materialTapTargetSize

  • 组件最小点击区域
  • 取值 如下
enum MaterialTapTargetSize {
  /// Expands the minimum tap target size to 48px by 48px.  将最小点击目标大小扩展为 48px x 48px。
  ///
  /// This is the default value of [ThemeData.materialTapTargetSize] and the
  /// recommended size to conform to Android accessibility scanner
  /// recommendations.
  padded,

  /// Shrinks the tap target size to the minimum provided by the Material  将点击目标尺寸缩小到Material 规范提供的最小值。
  /// specification.
  shrinkWrap,
}

pageTransitionsTheme

  • 页面切换动画
  • 切换动画支持 android ios macos
    在这里插入图片描述

默认页面切换动画
请添加图片描述

修改后的切换动画 从下往上顶出动画

 pageTransitionsTheme:PageTransitionsTheme(
          builders: <TargetPlatform, PageTransitionsBuilder>{
            TargetPlatform.android:OpenUpwardsPageTransitionsBuilder()
          }
        ),

请添加图片描述
自定义页面切换动画

class MyPageTransitionsBuilder extends PageTransitionsBuilder {

  @override![请添加图片描述](https://img-blog.csdnimg.cn/direct/8874fd6cec764fa4a1b042b4d46bb67d.gif)

  Widget buildTransitions<T>(
      PageRoute<T>? route,
      BuildContext? context,
      Animation<double> animation,    //显示页面执行的动画
      Animation<double> secondaryAnimation,   //隐藏页面执行的动画
      Widget? child,
      ) {
    return ScaleTransition(   //缩放动画  
      scale: animation,
      child: RotationTransition(  //旋转动画
        turns: animation,
        child: child,
      ),
    );
  }
}

结果:B页面旋转放大显示
请添加图片描述
若 return改为如下

return ScaleTransition(  //B页面放大
      scale: animation,
      child: RotationTransition(   //A页面旋转
        turns: secondaryAnimation,
        child: child,
      ),
    );

效果如下
请添加图片描述
其它类型动画 改变return即可 或可仿照系统默认切换动画类改造自己想要的动画

return SizeTransition(
        sizeFactor: animation,
        child: SizeTransition(
          sizeFactor: animation,
          child: child,
    ),
    );

请添加图片描述

全部代码


import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';

main(){
  runApp(const MyApp());
}

class MyApp extends StatelessWidget{

  const MyApp();

  @override
  Widget build(BuildContext context) {
    ThemeData themeRed = ThemeData.light().copyWith(
      extensions: <ThemeExtension<ThemeColors>>[ThemeColors(themeType: 0)],
    );

    ThemeData themeGreen = ThemeData.light().copyWith(
      extensions: <ThemeExtension<ThemeColors>>[ThemeColors(themeType: 1)],
    );

    ThemeData themeBlue = ThemeData.light().copyWith(
      extensions: <ThemeExtension<ThemeColors>>[ThemeColors(themeType: 2)],
      inputDecorationTheme: InputDecorationTheme(
        labelStyle: TextStyle(color: Colors.black),
        hintStyle: TextStyle(color: Colors.grey),
        border: UnderlineInputBorder(),
        focusedBorder: UnderlineInputBorder(),
      ),
        materialTapTargetSize:MaterialTapTargetSize.shrinkWrap,
        pageTransitionsTheme:PageTransitionsTheme(
          builders: <TargetPlatform, PageTransitionsBuilder>{
            TargetPlatform.android:MyPageTransitionsBuilder()
          }
        ),

    );

     return MaterialApp(
        theme: themeBlue,
        home: A(),
       routes: {
         "/A": (context) => A(),
         "/B": (context) => B(),
         "/C": (context) => C(),
       },
     );
  }

  void changeTheme(){

  }
}

class ThemeColors extends ThemeExtension<ThemeColors>{

  static String main_color = "main_color";
  static String text_color = "text_color";
  static String text_background = "text_background";

  var themeType = 0;

  var themeRed = {
    main_color:Colors.red,
    text_color:const Color(0xFFD26161),
    text_background:const Color(0xFFEAE4E4),
  };

  var themeGreen = {
    main_color:Colors.green,
    text_color:const Color(0xFF6EDC9A),
    text_background:const Color(0xFFEAE4E4),
  };

  var themeBlue = {
    main_color:Colors.blue,
    text_color:const Color(0xFF6F83E7),
    text_background:const Color(0xFFEAE4E4),
  };


  ThemeColors({this.themeType = 0});
  ThemeColors.themeRed(this.themeRed);
  ThemeColors.themeGreen(this.themeGreen);
  ThemeColors.themeBlue(this.themeBlue);

  @override
  ThemeExtension<ThemeColors> copyWith() {
    var result = null;
    switch(this.themeType){
      case 0:
        result = ThemeColors.themeRed(themeRed);
        break;
      case 1:
        result = ThemeColors.themeGreen(themeGreen);
        break;
      case 2:
        result = ThemeColors.themeBlue(themeBlue);
        break;
    }

    return result;
  }

  @override
  ThemeExtension<ThemeColors> lerp(covariant ThemeExtension<ThemeColors>? other, double t) {
     if(other !is ThemeColors){
        return this;
     }
     var result = null;
     switch(this.themeType){
       case 0:
         result = ThemeColors.themeRed(themeRed);
         break;
       case 1:
         result = ThemeColors.themeGreen(themeGreen);
         break;
       case 2:
         result = ThemeColors.themeBlue(themeBlue);
         break;
     }

     return result;
  }

  Color getColor(String colorName){
    var resultMap = null;
    switch(this.themeType){
      case 0:
        resultMap = themeRed;
        break;
      case 1:
        resultMap = themeGreen;
        break;
      case 2:
        resultMap = themeBlue;
        break;
    }
    return resultMap[colorName];
  }
  
}


class A extends StatefulWidget{

  A(){
    print("A页面启动!");
  }

  @override
  State<StatefulWidget> createState() => AState();
}

class AState extends State<A>{
  @override
  Widget build(BuildContext context) {
    ThemeColors themeColors = Theme.of(context).extension<ThemeColors>()??ThemeColors(themeType: 0);


    return Scaffold(
      backgroundColor: themeColors.getColor(ThemeColors.main_color),
      body: Container(
        child: Column(
          children: [
            // TextField(
            //   decoration: InputDecoration(
            //     hintText: "请输入内容"
            //   ),
            // ),
            TextButton(onPressed: (){
              Navigator.pushNamed(context, '/B');
            }, child: Text("B"),
              style: ButtonStyle(
                backgroundColor: MaterialStateProperty.all(Colors.green),
                padding: MaterialStateProperty.all(EdgeInsets.all(100))
              ),
            ),
            TextButton(onPressed: (){
              Navigator.pushNamed(context, '/C');
            }, child: Text("C"),
              style: ButtonStyle(
                  backgroundColor: MaterialStateProperty.all(Colors.red),
                  padding: MaterialStateProperty.all(EdgeInsets.all(100)),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

class B extends StatefulWidget{

  B(){
    print("B页面启动!");
  }

  @override
  State<StatefulWidget> createState() => BState();
}

class BState extends State<B>{
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Text("BBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"),
      ),
    );
  }
}

class C extends StatefulWidget{
  @override
  State<StatefulWidget> createState() => CState();
}

class CState extends State<C>{
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Text("CCCCCCCCCCCCCCCCCCCCCCCCC"),
      ),
    );
  }
}


class MyPageTransitionsBuilder extends PageTransitionsBuilder {

  @override
  Widget buildTransitions<T>(
      PageRoute<T>? route,
      BuildContext? context,
      Animation<double> animation,
      Animation<double> secondaryAnimation,
      Widget? child,
      ) {
    // return ScaleTransition(
    //   scale: animation,
    //   child: RotationTransition(
    //     turns: secondaryAnimation,
    //     child: child,
    //   ),
    // );
    return SizeTransition(
        sizeFactor: animation,
        child: SizeTransition(
          sizeFactor: animation,
          child: child,
    ),
    );
  }
}

其他分享

  • 学习过程中最大的方式就是查看源码
    比如pageTransitionsTheme 此属性传什么值 怎么传
    Android Studio 使用 Ctrl+左键
    在这里插入图片描述

Ctrl+左键 点击
在这里插入图片描述
需要一个 builders参数
并且有个 defalutBuilder
基本上可以知道怎么使用

再加上 百度/google 搞定!

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

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

相关文章

Elasticsearch:聊天机器人教程(一)

在本教程中&#xff0c;你将构建一个大型语言模型 (LLM) 聊天机器人&#xff0c;该机器人使用称为检索增强生成 (RAG) 的模式。 使用 RAG 构建的聊天机器人可以克服 ChatGPT 等通用会话模型所具有的一些限制。 特别是&#xff0c;他们能够讨论和回答以下问题&#xff1a; 你的…

IPhone、IPad、安卓手机、平板以及鸿蒙系统使用惠普无线打印教程

演示机型&#xff1a;惠普M281fdw&#xff0c;测试可行机型&#xff1a;惠普M277&#xff0c;惠普M452、惠普M283 点击右上角图标。 点击WI-FI Direct 开&#xff0c;(如果WI-FI Direct关闭&#xff0c;请打开&#xff01;) 记录打印机的wifi名称(SSID)和密码。 打开IPhone、I…

Altium Designer简介以及下载安装

阅读引言&#xff1a; Altium Designer的离线安装包在文章最后&#xff0c; 注意该软件只能用于个人的学习使用&#xff0c; 不能用于商业用途&#xff0c; 文章主题图片来自网络。 一、Altium Designer简介 Altium Designer是一款功能强大的电子设计自动化&#xff08;EDA&…

HBase学习六:LSM树算法

1、简介 HBase是基于LSM树架构实现的,天生适合写多读少的应用场景。 LSM树本质上和B+树一样,是一种磁盘数据的索引结构。但和B+树不同的是,LSM树的索引对写入请求更友好。因为无论是何种写入请求,LSM树都会将写入操作处理为一次顺序写,而HDFS擅长的正是顺序写(且HDFS不…

高光谱分类论文解读分享之Grid Network: 基于各向异性视角下特征提取的高光谱影像分类

IEEE GRSL 2023&#xff1a;Grid Network: 基于各向异性视角下特征提取的高光谱影像分类 题目 Grid Network: Feature Extraction in Anisotropic Perspective for Hyperspectral Image Classification 作者 Zhonghao Chen , Student Member, IEEE, Danfeng Hong , Senior …

MySQL窗口函数(MySQL Window Functions)

1、窗口函数基本概念 官网地址&#xff1a;https://dev.mysql.com/doc/refman/8.0/en/window-functions.html 窗口可以理解为 记录集合&#xff0c;窗口函数就是在满足某种条件的记录集合上执行的特殊函数。 即&#xff1a;每条记录都要在此窗口内执行函数。 静态窗口&#x…

k8s的对外服务--ingress

service作用体现在两个方面 1、集群内部 不断跟踪pod的变化&#xff0c;更新endpoint中的pod对象&#xff0c;基于pod的IP地址不断变化的一种服务发现机制 2、集群外部 类似负载均衡器&#xff0c;把流量ip端口&#xff0c;不涉及转发url&#xff08;http&#xff0c;https&a…

如何给新华网投稿发稿?新华网的媒体发稿方法步骤

现如今&#xff0c;互联网已经成为了人们获取信息的主要途径&#xff0c;各大媒体网站也成为了发布自己作品的首选平台。其中&#xff0c;新华网作为中国最具影响力的新闻媒体之一&#xff0c;其内容覆盖面广、触及人群众多&#xff0c;因此&#xff0c;能够在新华网上发表文章…

Django项目中的默认文件都有什么用

manager.py&#xff1a; 是django用于管理本项目的命令行工具&#xff0c;之后进行站点运行&#xff0c;数据库自动生成等都是通过本文件完成。 djangoStudy/__init__.py&#xff1a; 告诉python该目录是一个python包&#xff0c;暂无内容&#xff0c;后期一些工具的初始化可…

【华为 ICT HCIA eNSP 习题汇总】——题目集2

1、交换机某个端口配置信息如下&#xff0c;则此端口的PVID为&#xff08;&#xff09;。 A、100 B、2 C、4 D、1 # interface GigabitEthernet0/0/1 port hybrid tagged vlan 2 to 3 100 port hybrid unatgged vlan 4 6 #考点&#xff1a;VLAN&#xff08;虚拟局域网&#xff…

Hex Editor的使用教程(VS Code)

Hex Editor&#xff08;十六进制编辑器&#xff09;是一种用于查看和编辑计算机文件的低级别编辑工具。与常规文本编辑器不同&#xff0c;它允许用户直接查看和修改文件的二进制数据。在 Hex Editor 中&#xff0c;数据通常以十六进制&#xff08;hex&#xff09;格式显示&…

《C++入门篇》——弥补C不足

文章目录 前言一.命名空间二.缺省参数三.函数重载四.引用4.1引用做参数4.2引用做返回值 五.内联函数六.小语法6.1auto6.2范围for6.3空指针 前言 C是业内一门久负盛名的计算机语言&#xff0c;从C语言发展起来的它&#xff0c;不仅支持C语言的语法&#xff0c;还新添加了面向对…

分享用is_sorted()解决单调数列问题

题目名称 896. 单调数列 目录 题目名称 896. 单调数列 1.题目 2.题目分析 3.题目知识 3.1 is_sorted() 3.2.迭代器与反向迭代器 3.2.1理解迭代器 3.2.2正向迭代器 3.2.3反向迭代器 最后&#x1f368; 推荐阅读顺序: 1.题目->2.题目分析->3.题目知识点 1.题目 如…

基于R语言的NDVI的Sen-MK趋势检验

本实验拟分析艾比湖地区2010年至2020年间的NDVI数据&#xff0c;数据从MODIS遥感影像中提取的NDVI值&#xff0c;在GEE遥感云平台上将影像数据下载下来。代码如下&#xff1a; import ee import geemap geemap.set_proxy(port7890)# 设置全局网络代理 Map geemap.Map()# 指定…

安卓屏幕自动息屏时亮度突然变亮

自然息屏流程 USER_ACTIVITY_SCREEN_BRIGHT&#xff08;亮屏&#xff09; → USER_ACTIVITY_SCREEN_DIM&#xff08;DIM&#xff09; → USER_ACTIVITY_SCREEN_DREAM&#xff08;灭屏&#xff09;变化&#xff0c;最终进入ASLEEP后。在息屏时会执行一个变暗的动画 frameworks\…

echarts tooltip显示不全问题

在项目里面的tooltip数据特别多&#xff0c;显示不全问题&#xff1a; 1、如果盒子还够大&#xff0c;只是tooltip飘到上面或者下面被覆盖住了&#xff0c;可以考虑confine: true这个属性&#xff0c;将tooltip限制在盒子内; 2、如果盒子比较小&#xff0c;展示不全的话&#…

【PyTorch】PyTorch之Tensors索引切片篇

文章目录 前言一、ARGWHERE二、CAT、CONCAT、CONCATENATE三、CHUNK四、GATHER五、MOVEDIM和MOVEAXIS六、PERMUTE七、RESHAPE八、SELECT九、SPLIT十、SQUEEZE十一、T十二、TAKE十三、TILE十四、TRANSPOSE十五、UNBIND十六、UNSQUEEZE十七、WHERE 前言 介绍常用的PyTorch之Tenso…

如何使用Synology Drive作为文件同步服务器实现云同步Obsidian笔记

文章目录 一、简介软件特色演示&#xff1a; 二、使用免费群晖虚拟机搭建群晖Synology Drive服务&#xff0c;实现局域网同步1 安装并设置Synology Drive套件2 局域网内同步文件测试 三、内网穿透群晖Synology Drive&#xff0c;实现异地多端同步Windows 安装 Cpolar步骤&#…

Oracle 实战手册 工作实战经验总结

目录 一、基本的数据库管理 1、数据库的启动和关闭 ​编辑2、如何确定Oracle的版本&#xff1f; 3、如何修改数据库的内存参数 4、修改用户名密码 5、如何查看最大会话数 6、如何修改oracle数据库的用户连接数 7、解锁用户 8、如何获取被锁定的数据库对象 9、如何确定…

金融CRM系统是什么?有哪些功能和作用

今年市场经济下行&#xff0c;投资趋向于保守、人们消费降级&#xff0c;对于金融行业来说影响很大。受经济形式的影响加上行业的数字化转型升级&#xff0c;金融企业都在寻求客户管理的新策略&#xff0c;维护好忠实客户、吸引新客户投资。小编认为CRM系统是管理客户的不二之选…