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;
  }
}
相关推荐
老田低代码9 小时前
Dart自从引入null check后写Flutter App总有一种难受的感觉
前端·flutter
AiFlutter19 小时前
Flutter Web首次加载时添加动画
前端·flutter
ZemanZhang2 天前
Flutter启动无法运行热重载
flutter
AiFlutter3 天前
Flutter-底部选择弹窗(showModalBottomSheet)
flutter
帅次3 天前
Android Studio:驱动高效开发的全方位智能平台
android·ide·flutter·kotlin·gradle·android studio·android jetpack
程序者王大川3 天前
【前端】Flutter vs uni-app:性能对比分析
前端·flutter·uni-app·安卓·全栈·性能分析·原生
yang2952423613 天前
使用 Vue.js 将数据对象的值放入另一个数据对象中
前端·vue.js·flutter
我码玄黄3 天前
解锁定位服务:Flutter应用中的高德地图定位
前端·flutter·dart
hudawei9963 天前
flutter widget 设置GestureDetector点击无效
flutter·gesturedetector·点击事件
AiFlutter3 天前
Flutter iOS混淆打包
flutter·ios