flutter 五点一点一:MaterialApp Theme

 factory ThemeData({
 	...
    TargetPlatform? platform,  //目标平台
    ScrollbarThemeData? scrollbarTheme,   //滚动条主题样式
    ...
  }

platform 目标平台

  • 貌似表示的是当前Theme 的目标平台
  • 枚举值
    例如 我将 platform 设置为ios
platform: TargetPlatform.iOS

然后运行到 android模拟器上
点击跳转页面动画 为默认动画
请添加图片描述

若改成 android

platform: TargetPlatform.android

则动画效果如下
请添加图片描述

  • 那么问题来了
  • 不同平台 如何显示不同效果?
  • Platform 可获取现在是那个平台 可根据不通的平台设置不同的效果
  • 例如
    把Theme的 platform 去掉 不指定平台
    Android 动画 ios动画不同
class MyPageTransitionsBuilder extends PageTransitionsBuilder {
  @override
  Widget buildTransitions<T>(
    PageRoute<T>? route,
    BuildContext? context,
    Animation<double> animation,
    Animation<double> secondaryAnimation,
    Widget? child,
  ) {
    // return

    AnimatedWidget? animatedWidget = null;

    if (Platform.isAndroid) {
      animatedWidget = SizeTransition(
        sizeFactor: animation,
        child: SizeTransition(
          sizeFactor: animation,
          child: child,
        ),
      );
    } else {
      animatedWidget = ScaleTransition(
        scale: animation,
        child: RotationTransition(
          turns: secondaryAnimation,
          child: child,
        ),
      );
    }

    return animatedWidget;
  }
}

根据不同平台使用不同Theme

ThemeData? needTheme = null;
    try{
      if(Platform.isAndroid){  //web 调用会报错 
        needTheme = themeRed;
      }else{
        needTheme = themeBlue;
      }
    }catch(e){
      needTheme = themeBlue;
    }
 return MaterialApp(
      theme: needTheme,
      home: A(),
      routes: {
        "/A": (context) => A(),
        "/B": (context) => B(),
        "/C": (context) => C(),
      },
    );

结果
在这里插入图片描述
在这里插入图片描述

  • 当然 platform 也可以根据不同的平台 来展示不同的页面

scrollbarTheme

  • Scrollbar 的样式
  • ScrollbarThemeData? scrollbarTheme,
//使用scrollbar
class BState extends State<B> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Scrollbar(
          child:ListView(
              primary: true,
              children: List.generate(100, (index) => Text("条目${index}"))
          )
      ),
    );
  }
}
//设置scrollbar样式
scrollbarTheme:ScrollbarThemeData(
            thumbVisibility:MaterialStateProperty.all(true)   // true默认显示scroolbar   false 不显示
        ),

在这里插入图片描述在这里插入图片描述

 scrollbarTheme:ScrollbarThemeData(
            thumbVisibility:MaterialStateProperty.all(false),
            trackVisibility:MaterialStateProperty.all(true),
        ),
  • trackVisibility:MaterialStateProperty.all(false ), //false 效果
    在这里插入图片描述

  • trackVisibility:MaterialStateProperty.all(true), //true效果
    在这里插入图片描述

 scrollbarTheme:ScrollbarThemeData(
            thumbVisibility:MaterialStateProperty.all(false),
            thickness: MaterialStateProperty.all(100),
            trackVisibility:MaterialStateProperty.all(false),
        ),
  • thickness: MaterialStateProperty.all(100), 效果
    在这里插入图片描述
scrollbarTheme:ScrollbarThemeData(
            thumbVisibility:MaterialStateProperty.all(true),
            thickness: MaterialStateProperty.all(100),
            trackVisibility:MaterialStateProperty.all(false),
            radius:Radius.elliptical(50, 50)
        ),
  • radius:Radius.elliptical(50, 50) 效果
    

在这里插入图片描述

  • thumbColor:MaterialStateProperty.all(Colors.yellow),
    在这里插入图片描述
 scrollbarTheme:ScrollbarThemeData(
            thumbVisibility:MaterialStateProperty.all(true),
            thickness: MaterialStateProperty.all(100),
            trackVisibility:MaterialStateProperty.all(true),
            radius:Radius.elliptical(50, 50),
            thumbColor:MaterialStateProperty.all(Colors.yellow),
            trackColor:MaterialStateProperty.all(Colors.cyanAccent),
        ),
  • trackColor:MaterialStateProperty.all(Colors.cyanAccent), 轨道颜色
    在这里插入图片描述
  •         trackBorderColor:MaterialStateProperty.all(Colors.red),
    

在这里插入图片描述

  • crossAxisMargin:20,  没设置之前如上图  设置后如下图
    

在这里插入图片描述
mainAxisMargin:50, 未设置前如上图 设置后如下图
在这里插入图片描述

  • minThumbLength:200, 未设置前如上图 设置后如下图

在这里插入图片描述

  • interactive:true, 是否可交互 true可拖动滚动条 false不可以

全部代码

import 'dart:io';

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()
            }),
        scrollbarTheme:ScrollbarThemeData(
            thumbVisibility:MaterialStateProperty.all(true),     //是否默认显示滚动条   false滑动的时候才显示
            thickness: MaterialStateProperty.all(100),   //滚动条宽度
            trackVisibility:MaterialStateProperty.all(true),  //轨道是否显示
            radius:Radius.elliptical(50, 50),   //滚动条弧度
            thumbColor:MaterialStateProperty.all(Colors.yellow),  //滚动条颜色
            trackColor:MaterialStateProperty.all(Colors.cyanAccent),    //轨道颜色
            trackBorderColor:MaterialStateProperty.all(Colors.red),  //轨道边框颜色
            crossAxisMargin:20,   //距离左右高
            mainAxisMargin:50,   //距离上下高
            minThumbLength:200,  //滚动条最小高度
            interactive:true,  //滚动条是否可拖动
          
        ),
    );


    ThemeData? needTheme = null;
    try{
      if(Platform.isAndroid){
        needTheme = themeRed;
      }else{
        needTheme = themeBlue;
      }
    }catch(e){
      needTheme = themeBlue;
    }

    return MaterialApp(
      theme: needTheme,
      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: Scrollbar(
          child:ListView(
              primary: true,
              children: List.generate(100, (index) => Text("条目${index}"))
          )
      ),
    );
  }
}

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

    AnimatedWidget? animatedWidget = null;

    if (Platform.isAndroid) {
      animatedWidget = SizeTransition(
        sizeFactor: animation,
        child: SizeTransition(
          sizeFactor: animation,
          child: child,
        ),
      );
    } else {
      animatedWidget = ScaleTransition(
        scale: animation,
        child: RotationTransition(
          turns: secondaryAnimation,
          child: child,
        ),
      );
    }

    return animatedWidget;
  }
}

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

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

相关文章

Eureka整合seata分布式事务

文章目录 一、分布式事务存在的问题二、分布式事务理论三、认识SeataSeata分布式事务解决方案1、XA模式2、AT模式3、SAGA模式4.SAGA模式优缺点&#xff1a;5.四种模式对比 四、微服务整合Seata AT案例Seata配置微服务整合2.1、父工程项目创建引入依赖 2.2、Eureka集群搭建2.3、…

Unity Binding冲突解决探究

主要参考&#xff1a; 官方文档&#xff1a;Unity官方Input System手册与API本文节选自&#xff1a;【Unity学习笔记】第十二 New Input System 及其系统结构 和 源码浅析 可能存在冲突的几种情况&#xff1a; 同一Action下不同binding引用同一个control&#xff0c;且都非组合…

阿里云ECS(CentOS镜像)安装docker

目录 1.前置条件 2.连接至ECS 3.yum软件包更新 4.安装docker前置所需软件包 5.添加docker 官方的 yum 软件源 6.安装docker 7.检测是否成功 8.配置阿里云镜像加速器 1.前置条件 在看本文前保证未安装过docker,或者安装过但是清理干净 如果多次安装失败过&#xff0c;…

C语言第五弹---分支语句(上)

✨个人主页&#xff1a; 熬夜学编程的小林 &#x1f497;系列专栏&#xff1a; 【C语言详解】 【数据结构详解】 分支语句 1、if语句1.1、if1.2、 else1.3、 分支中包含多条语句1.4、嵌套if1.5、 悬空else问题 2、关系操作符3、 条件操作符总结 C语言是结构化的程序设计语言&…

优思学院|怎样制作优秀的标准作业流程(SOP)?

我相信你一定去过众所周知的麦当劳。它在世界各地都有许多分店。不知道你是否曾在不同地方的麦当劳尝试过他们的美食&#xff0c;但你可能会好奇&#xff0c;为什么无论在世界哪个角落&#xff0c;麦当劳的食物口味都如此一致&#xff1f;它们是如何确保全球各地分店都能提供同…

【C++】类和对象(上篇)

文章目录 &#x1f6df;一、面向过程和面向对象初步认识&#x1f6df;二、类的引入&#x1f6df;三、类的定义&#x1f4dd;1、类的两种定义方式&#x1f4dd;2、成员变量命名规则的建议 &#x1f6df;四、类的访问限定符及封装&#x1f369;1、访问限定符&#x1f369;2、封装…

Docker(九)Docker Buildx

作者主页&#xff1a; 正函数的个人主页 文章收录专栏&#xff1a; Docker 欢迎大家点赞 &#x1f44d; 收藏 ⭐ 加关注哦&#xff01; Docker Buildx Docker Buildx 是一个 docker CLI 插件&#xff0c;其扩展了 docker 命令&#xff0c;支持 [Moby BuildKit] 提供的功能。提…

Unity中实现捏脸系统

前言 目前市面上常见的捏脸一般是基于BlendShapes和控制骨骼点坐标两种方案实现的。后者能够控制的精细程度更高&#xff0c;同时使用BlendShapes来控制表情。 控制骨骼点坐标 比如找到控制鼻子的骨骼节点修改localScale缩放&#xff0c;调节鼻子大小。 BlendShapes控制表…

PLC网关BL121PO 实现低成本的PLC接入OPC UA的解决方案

随着工业4.0的迅猛发展&#xff0c;人们深刻认识到在工业生产和生活中&#xff0c;实时、可靠、安全的数据传输至关重要。在此背景下&#xff0c;高性能的工业自动化数据传输解决方案——协议转换网关应运而生&#xff0c;广泛应用于工业自动化和数字化工厂应用环境中。 无缝衔…

Linux 命令大全 CentOS常用运维命令

文章目录 1、Linux 目录结构2、解释目录3、命令详解3.1、shutdown命令3.1、文件目录管理命令ls 命令cd 命令pwd 命令tree 命令mkdir 命令touch 命令cat 命令cp 命令more 命令less 命令head 命令mv 命令rm 命令ln 命令tail 命令cut命令 3.2、用户管理useradd/userdel 命令用户的…

51单片机LED点阵屏

LED点阵屏 LED点阵屏是一种由许多小型LED灯组成的矩阵式显示屏。这些LED灯可以是单色、双色或全彩的&#xff0c;它们排列成行和列的网格&#xff0c;可以根据需要点亮来显示图像、文字或动画等内容。LED点阵屏广泛应用于户外广告牌、室内显示、交通信号灯、电子价格标签和其他…

[小程序]基于token的权鉴测试

一、服务器配置 服务器基于flask&#xff0c;需要额外安装flask_jwt_extended包 from flask import Flask #导入Flask包 from flask import request from flask import jsonify #用来返回json消息 from flask_jwt_extended import create_access_token, jwt_requi…

Docker(十)Docker Compose

作者主页&#xff1a; 正函数的个人主页 文章收录专栏&#xff1a; Docker 欢迎大家点赞 &#x1f44d; 收藏 ⭐ 加关注哦&#xff01; Docker Compose 项目 Docker Compose 是 Docker 官方编排&#xff08;Orchestration&#xff09;项目之一&#xff0c;负责快速的部署分布式…

轻松打卡:使用Spring Boot和Redis Bitmap构建高效签到系统【redis实战 四】

欢迎来到我的博客&#xff0c;代码的世界里&#xff0c;每一行都是一个故事 轻松打卡&#xff1a;使用Spring Boot和Redis Bitmap构建高效签到系统【redis实战 四】 引言(redis实战)前言回顾bitmap基本概念核心特性使用场景 为什么使用redis中的bitmap实现&#xff1f;1. 存储效…

探索全球DNS体系 | 从根服务器到本地解析

DNS 发展 DNS&#xff08;Domain Name System&#xff09;的起源可以追溯到互联网早期。 早期的挑战&#xff1a; 早期互联网主要通过IP地址进行通信&#xff0c;用户需要记住复杂的数字串来访问网站。 需求的催生&#xff1a; 随着互联网的扩大&#xff0c;更简单、易记的…

binary_search_tree的介绍与实现(二叉搜索树精美图示详解哦)

二叉搜搜索树 引言二叉搜索树的介绍二叉搜索树的实现框架默认成员函数构造析构赋值重载 InsertR&#xff08;插入&#xff09;EraseR&#xff08;删除&#xff09;SearchR&#xff08;查找&#xff09; 源码概览总结 引言 在C语言部分&#xff0c;我们已经认识了树与二叉树的结…

如何进行正确的 CodeReview

软件开发生命周期中至关重要的一步是代码审查。它使开发人员能够显著提升代码质量。它类似于书籍的创作过程。首先&#xff0c;作者写故事&#xff0c;然后经过编辑以确保不会出现诸如混淆“you’re”和“yours”之类的错误。在这个语境中&#xff0c;代码审查指的是检查和评估…

GPT应用程序的行业应用

GPT&#xff08;Generative Pre-trained Transformer&#xff09;应用程序在各个行业都有广泛的应用潜力&#xff0c;其自然语言生成的能力使其适用于多种场景。以下是一些行业中常见的GPT应用&#xff0c;希望对大家有所帮助。北京木奇移动技术有限公司&#xff0c;专业的软件…

【明道云】学习笔记1-了解APaaS

【背景】 APaaS (Application Platform As A Service) &#xff0c;即应用程序平台即服务&#xff0c;这是基于PaaS&#xff08;平台即服务&#xff09;的一种解决方案&#xff0c;支持应用程序在云端的开发、部署和运行&#xff0c;提供软件开发中的基础工具给用户&#xff0…

React Hooks 源码解析:useEffect

React Hooks 源码解析&#xff08;4&#xff09;&#xff1a;useEffect React 源码版本: v16.11.0源码注释笔记&#xff1a;airingursb/react 1. useEffect 简介 1.1 为什么要有 useEffect 我们在前文中说到 React Hooks 使得 Functional Component 拥有 Class Component 的…