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 {
    @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;
  }
}
相关推荐
LawrenceLan1 小时前
Flutter 零基础入门(九):构造函数、命名构造函数与 this 关键字
开发语言·flutter·dart
一豆羹2 小时前
macOS 环境下 ADB 无线调试连接失败、Protocol Fault 及端口占用的深度排查
flutter
行者962 小时前
OpenHarmony上Flutter粒子效果组件的深度适配与实践
flutter·交互·harmonyos·鸿蒙
行者964 小时前
Flutter与OpenHarmony深度集成:数据导出组件的实战优化与性能提升
flutter·harmonyos·鸿蒙
小雨下雨的雨4 小时前
Flutter 框架跨平台鸿蒙开发 —— Row & Column 布局之轴线控制艺术
flutter·华为·交互·harmonyos·鸿蒙系统
小雨下雨的雨5 小时前
Flutter 框架跨平台鸿蒙开发 —— Center 控件之完美居中之道
flutter·ui·华为·harmonyos·鸿蒙
小雨下雨的雨6 小时前
Flutter 框架跨平台鸿蒙开发 —— Icon 控件之图标交互美学
flutter·华为·交互·harmonyos·鸿蒙系统
小雨下雨的雨6 小时前
Flutter 框架跨平台鸿蒙开发 —— Placeholder 控件之布局雏形美学
flutter·ui·华为·harmonyos·鸿蒙系统
行者966 小时前
OpenHarmony Flutter弹出菜单组件深度实践:从基础到高级的完整指南
flutter·harmonyos·鸿蒙
前端不太难7 小时前
Flutter / RN / iOS,在长期维护下的性能差异本质
flutter·ios