flutter 五点一:MaterialApp Theme

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 搞定!

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

计算机网络——运输层(1)暨小程送书

计算机网络——运输层&#xff08;1&#xff09;暨小程送书 小程一言专栏链接: [link](http://t.csdnimg.cn/ZUTXU) 运输层概述两个主要协议运输层和网络层的关系网络层运输层总结 多路复用与多路分解多路复用多路分解不同的技术实现时分复用&#xff08;TDM&#xff09;频分复…

Proxmox VE 8安装OpenSuse和部署JumpServer

作者&#xff1a;田逸&#xff08;formyz&#xff09; 跳板服务器Jumpserver部署起来非常容易&#xff0c;但由于其组件多&#xff0c;组件之间关联复杂&#xff0c;一旦出现故障&#xff0c;恢复起来就比较费事。为了解决这个麻烦&#xff0c;本人通常是将Jumpserver部署到Pro…

5. UE5 RPG使用GAS技能系统

之前也介绍过GAS的使用&#xff1a; UE 5 GAS Gameplay Ability System UE 5 GAS 在项目中处理AttributeSet相关 UE 5 GAS 在项目中通过数据初始化 基础的讲解这里不再诉说&#xff0c;有兴趣的可以翻我之前的博客。 接下来&#xff0c;在RPG游戏中实现GAS系统的使用。 GAS系统…

笔记本电脑如何连接显示屏?

目录 1.按下快捷键 winP,选择扩展 2.连接显示器&#xff0c;连好接线 3.笔记本驱动有问题&#xff0c;显示错误如下&#xff1a; 4.驱动已经下载完成&#xff0c; 按下快捷键&#xff0c;还是显示第3步中的错误 5.驱动已经下载完成&#xff0c; 按下快捷键&#xff0c;参照…

Redis:原理速成+项目实战——Redis实战13(GEO实现附近商铺、滚动分页查询)

&#x1f468;‍&#x1f393;作者简介&#xff1a;一位大四、研0学生&#xff0c;正在努力准备大四暑假的实习 &#x1f30c;上期文章&#xff1a;Redis&#xff1a;原理速成项目实战——Redis实战12&#xff08;好友关注、Feed流&#xff08;关注推送&#xff09;、滚动分页查…

拼多多无货源中转仓项目真的靠谱吗?发展前景如何?

阿阳最近一直在关注无货源电商这一块&#xff0c;尤其是拼多多无货源中转仓&#xff0c; 现如今也有了自己的运营团队和交付团队&#xff0c;整体来看这个项目还算不错&#xff01; 说实话&#xff0c;在考察这个项目的时候&#xff0c;看到市面上很多人在做&#xff0c;包括我…

JAVA基础-----认识异常

文章目录 1. 异常的概念与体系结构1.1 异常的概念1.2 异常的体系结构1.3 异常的分类 2. 异常的处理2.1 防御式编程2.2 异常的抛出2.3 异常的捕获2.3.1 异常声明throws2.3.2 try-catch捕获并处理2.3.3 finally 2.4 异常的处理流程 3. 自定义异常类 1. 异常的概念与体系结构 1.1…

C/C++ 基本数据类型的范围

一、常见的数据类型及其范围 数据类型Size(64位)范围int4Byteunsigned int4Bytelong4Byteunsigned long4Bytelong long8Byteunsigned long long8Byte 查询Size代码&#xff1a;sizeof(类型) 查询范围代码&#xff1a;numeric_limits<类型>::max和numeric_limits<类…

使用 mybatis-plus 的mybaits的一对多时, total和record的不匹配问题

应该是框架的问题&#xff0c;去官方仓库提了个issues&#xff0c;等回复 https://github.com/baomidou/mybatis-plus/issues/5923 回复来了&#xff1a; 背景 发现 record是两条&#xff0c;但是total显示3 使用resultMap一对多时&#xff0c;三条数据会变成两条&#xff0…

redis原理(四)redis命令

目录 一、字符串命令&#xff1a; 二、列表命令&#xff1a; 三、集合命令&#xff1a; 四、散列命令&#xff1a; 五、有序集合命令&#xff1a; 六、redis发布与订阅命令&#xff1a; 七、事务命令 八、其他命令 1、排序&#xff1a;SORT 2、键的过期时间&#xff…

代码随想录算法训练营Day23 | 455.分发饼干、376.摆动子序列、53.最大子数组和

LeetCode 455 分发饼干 本题思路&#xff1a;分发饼干的时候&#xff0c;外层循环是胃口&#xff0c;内层是饼干&#xff0c;按照大饼干满足大胃口的思维来投递饼干。 需要将 两个数组&#xff0c;一开始就进行排序处理。 class Solution {public int findContentChildren(int…

java转义字符

//转义字符的使用 public class ChangeChar{//编写一个main方法public static void main(String[] args){// \t :一个制表位&#xff0c;实现对齐的功能System.out.println("北京\t天津\t上海");// \n :换行符&#xff0c;实现换行System.out.println("jack\nsm…

SSH隧道技术

SSH隧道 简介 SSH隧道是一种通过SSH协议在两个网络节点之间建立安全通信的技术。它可以用于多种用途&#xff0c;包括加密和保护敏感数据传输、绕过防火墙限制、远程访问内部服务等。 应用&#xff1a; 端口转发&#xff1a;SSH隧道可以将本地端口转发到远程主机上&#xf…

Python学习从0到1 day5 python基础语法3 数据类型及数据类型转换

一切都会好的&#xff0c;我一直相信 ——24.1.17 一、数据类型 1.数据是有类型的 目前主要接触如下三类数据类型&#xff1a; 2.type()语句 我们可以通过type()语句来得到数据的类型 语法&#xff1a;type(被查看类型的数据) a 10 type(a) print(type(a)) print(type(11…

分子动力学模拟—LAMMPS 模拟(固体和液体)数据后处理软件(六)

记录一下检索到一篇分子动力学模拟数据后处理的软件。 感谢论文的原作者&#xff01; 主要功能&#xff1a; Structure Analysis Ackland Jones Analysis CentroSymmetry Parameter Common Neighbor Analysis Common Neighbor Parameter Atomic Structure Entropy Stein…

IOS-高德地图连续定位-Swift

使用定位功能需要需要接入高德地图定位Api&#xff1a; pod AMapLocation配置Info 在info中新建一个名为Privacy - Location Temporary Usage Description Dictionary的字典&#xff0c;然后在这个字典下新建Privacy - Location When In Use Usage Description、Privacy - Lo…

【​电力电子在电力系统中的应用​】6 滞环电流控制的PWM整流器 + STATCOM整流器 + APF仿真

【仅供参考】 【2023.06西南交大电力电子在电力系统中的应用】 目录 步骤一&#xff1a;基于滞环电流控制的PWM整流器仿真 1.1 仿真要求 1.2 仿真电路原理及设计 1.2.1 主电路的搭建 1.2.2 控制电路的搭建 1.3 波形分析 步骤二&#xff1a;从PWM整流器到STATCOM仿真 2…

使用ProxySql实现Mysql的读写分离 详细安装步骤 亲测可行

主机ip说明192.168.168.109ProxySql192.168.168.77mysql master(主&#xff09;192.168.168.78mysql slave&#xff08;从&#xff09; 1.下载ProxySql安装包 在192.168.168.109机器上操作 https://github.com/sysown/proxysql/releases/download/v2.5.5/proxysql-2.5.5-1-ce…

阿里云ack集群管理及故障处理

一、集群管理维护 二、常见故障处理 存储&#xff1a; 网络 弹性伸缩 service

Microsoft Word 设置底纹

Microsoft Word 设置底纹 References 打开文档页面&#xff0c;选中特定段落或全部文档 在“段落”中单击“边框”下三角按钮 在列表中选择“边框和底纹”选项 在“边框和底纹”对话框中单击“底纹”选项卡 在图案样式和图案颜色列表中设置合适颜色的底纹&#xff0c;单击“确…