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;
  }
}
相关推荐
ujainu44 分钟前
Flutter与DevEco Studio结合开发简单项目实战指南
flutter·开发·deveco studio
嗝o゚1 小时前
Flutter 无障碍功能开发最佳实践
python·flutter·华为
嗝o゚2 小时前
Flutter与ArkTS混合开发框架的探索
flutter
小a杰.2 小时前
Flutter国际化(i18n)实现详解
flutter
嗝o゚2 小时前
开源鸿蒙 Flutter 应用包瘦身实战
flutter·华为·开源·harmonyos
小a杰.3 小时前
Flutter 响应式设计基础
flutter
狮恒3 小时前
OpenHarmony Flutter 分布式设备发现与连接:无感组网与设备协同管理方案
分布式·flutter·wpf·openharmony
嗝o゚4 小时前
Flutter与开源鸿蒙:一场“应用定义权”的静默战争,与开发者的“范式跃迁”机会
python·flutter
狮恒5 小时前
OpenHarmony Flutter 分布式音视频:跨设备流传输与实时协同交互方案
分布式·flutter·wpf·openharmony
duangww5 小时前
Flutter和SAPUI5集成
flutter