FlutterStack详解

发布时间:2023-05-22

Flutter是一款由Google开发的UI工具包,可以创建高性能、高保真度的移动应用程序。当然,Flutter也有自己的社区生态,FlutterStack就是其中之一。本文将从不同的方面对FlutterStack做详细的阐述。

一、点击穿透

点击穿透指的是用户在点击了一个可交互的widget但其下方还有一个位于相同位置并且可交互的widget,此时会出现优先响应下层widget的现象。在Flutter开发中,为了解决这个问题,我们可以使用IgnorePointerAbsorbPointer widget。IgnorePointer会忽略所有的用户事件,AbsorbPointer会拦截所有的用户事件。

@override
Widget build(BuildContext context) {
  return Stack(
    children: [
      // 下方widget
      Positioned(
        top: 0,
        left: 0,
        right: 0,
        bottom: 0,
        child: GestureDetector(
          onTap: () {
            print("click bottom widget");
          },
        ),
      ),
      // 上方widget
      Positioned(
        top: 0,
        left: 0,
        right: 0,
        bottom: 0,
        child: IgnorePointer(
          child: GestureDetector(
            onTap: () {
              print("click top widget");
            },
          ),
        ),
      ),
    ],
  );
}

二、路由传参

在Flutter中,路由管理是非常重要的,通过路由可以实现页面之间的跳转。在路由的跳转过程中需要传递参数,这时可以使用FlutterStack库中的ArgumentWidgetArgumentExtractorArgumentWidget用来传递参数,ArgumentExtractor用来提取参数。例如:

class SecondPage extends StatelessWidget with ArgumentWidget {
  final String name;
  SecondPage(this.name);
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("SecondPage"),
      ),
      body: Center(
        child: RaisedButton(
          onPressed: () {
            Navigator.pop(context, "Hello, $name!");
          },
          child: Text("返回并传递参数"),
        ),
      ),
    );
  }
  @override
  Map<String, dynamic> argument() {
    return {"name": name};
  }
}
class FirstPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("FirstPage"),
      ),
      body: Center(
        child: RaisedButton(
          onPressed: () async {
            final result = await Navigator.push(context, MaterialPageRoute(builder: (ctx) => SecondPage("FlutterStack")));
            print(result);
            final argument = ArgumentExtractor.extract(result);
            print(argument["name"]);
          },
          child: Text("跳转到SecondPage"),
        ),
      ),
    );
  }
}

三、网络请求

FlutterStack中提供了一个便捷的网络请求工具类,可以方便的进行网络请求。例如:

static Future<dynamic> get(String url, {Map<String, dynamic> params, Map<String, String> headers}) async {
  var client = new http.Client();
  try {
    var response = await client.get(_buildUrl(url, params), headers: headers);
    return _handleResponse(response);
  } catch (e) {
    return {"code": -1, "msg": e.toString()};
  } finally {
    client.close();
  }
}
static Future<dynamic> post(String url, {Map<String, dynamic> params, Map<String, String> headers}) async {
  var client = new http.Client();
  try {
    var response = await client.post(url, body: params, headers: headers);
    return _handleResponse(response);
  } catch (e) {
    return {"code": -1, "msg": e.toString()};
  } finally {
    client.close();
  }
}

使用方法也非常简单:

void _getData() async {
  final result = await HttpManager.get("https://www.baidu.com");
  print(result);
}

四、国际化

在开发中,有时需要我们的应用支持多语言,FlutterStack提供了一个简单易用的国际化工具。通过以下步骤,可以在应用中实现多语言:

  1. pubspec.yaml文件中添加依赖项:
dependencies:
  flutter_localizations:
    sdk: flutter
  1. 在main函数中添加如下代码:
void main() {
  runApp(
    MaterialApp(
      localizationsDelegates: [
        GlobalMaterialLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate,
        FallbackCupertinoLocalisationsDelegate(),
      ],
      supportedLocales: [const Locale('en', ''), const Locale('zh', '')],
      home: MyApp(),
    ),
  );
}
  1. lib目录下创建一个l10n目录,用于存放多语言文件,例如lib/l10n/messages_en.dartlib/l10n/messages_zh.dart
  2. 在消息文件中添加多语言翻译:
class Messages {
  static const String appTitle = "FlutterStack";
  static const String welcomeMessage = "Welcome";
  static const String language = "Language";
  static const String english = "English";
  static const String chinese = "中文";
  static String localeMessage(String language) {
    return "你选择了${language}";
  }
}
  1. 在需要使用的widget中使用FlutterStack提供的TranslationWidget,例如:
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(Messages.appTitle),
      ),
      body: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          Text(Messages.welcomeMessage),
          SizedBox(height: 20),
          TranslationWidget(
            builder: (BuildContext context, String value) {
              return Text(value);
            },
            translation: Messages.language,
          ),
          SizedBox(height: 20),
          TranslationWidget(
            builder: (BuildContext context, String value) {
              return Text(value);
            },
            translation: Messages.localeMessage("FlutterStack"),
          ),
        ],
      ),
    );
  }
}

五、动画效果

Flutter的动画效果非常丰富,通过FlutterStack中提供的AnimatedWidgetAnimationController可以实现各种复杂的动画效果。例如:

class AnimatedLogo extends AnimatedWidget {
  AnimatedLogo({Key key, Animation<double> animation}) : super(key: key, listenable: animation);
  @override
  Widget build(BuildContext context) {
    final Animation<double> animation = listenable;
    return Center(
      child: Container(
        margin: EdgeInsets.symmetric(vertical: 10),
        height: animation.value,
        width: animation.value,
        child: FlutterLogo(),
      ),
    );
  }
}
class LogoApp extends StatefulWidget {
  @override
  _LogoAppState createState() => _LogoAppState();
}
class _LogoAppState extends State<LogoApp> with TickerProviderStateMixin {
  AnimationController controller;
  Animation<double> animation;
  @override
  void initState() {
    super.initState();
    controller = AnimationController(vsync: this, duration: Duration(seconds: 2));
    animation = Tween(begin: 0.0, end: 200.0).animate(controller);
    controller.forward();
  }
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("AnimatedLogo"),
      ),
      body: AnimatedLogo(
        animation: animation,
      ),
    );
  }
  @override
  void dispose() {
    controller.dispose();
    super.dispose();
  }
}

六、总结

本文从多个方面对FlutterStack做了详细的阐述,包括点击穿透、路由传参、网络请求、国际化以及动画效果等。通过对FlutterStack的了解,可以更加方便地进行Flutter开发,提高开发效率。