Flutter轻量级UI组件插件slim的使用

Flutter轻量级UI组件插件slim的使用

slim - app essentials

slim 是一个为大多数应用提供通用功能和能力的轻量级UI组件插件。它简化了应用基础设施的设置,使开发者可以专注于屏幕和逻辑的开发。

slim 提供的功能:

  • 本地化(Localizations)
  • UI消息(UI Messages)
  • 状态管理(State Management)
  • 应用程序生命周期事件(AppLifecycleState Events)
  • 有用的扩展方法(Useful Extensions)
  • REST API(Rest Api)

配置(Configurations)

通过简单的配置,slim 可以快速实现本地化和UI消息支持。

1. App 类构造函数

这是设置支持的语言环境的地方。如果需要,还可以自定义 SlimLocaleLoader。默认的 SlimLocaleLoader 会从 assets/locales/ 文件夹加载语言文件。

MyApp() {
  SlimLocalizations.supportedLocales = [Locale('en', 'US')];
  // 如果要自定义语言加载器,创建一个继承自 SlimLocaleLoader 的类并修改:
  // SlimLocalizations.slimLocaleLoader = YourCustomLocalLoader();
}

2. MaterialApp 构建器

MaterialApp 中添加 SlimMaterialAppBuilder.builder。如果有其他构建器,可以链式调用。

builder: SlimMaterialAppBuilder.builder,

3. MaterialApplocalizationsDelegates

设置为 SlimLocalizations.delegates,这将包含所有必要的委托,包括 SlimLocalizations.slimLocaleLoader 委托。

localizationsDelegates: SlimLocalizations.delegates,

4. MaterialAppsupportedLocales

设置为 SlimLocalizations.supportedLocales,即在 App 类构造函数中配置的支持语言环境。

supportedLocales: SlimLocalizations.supportedLocales,

示例代码:

import 'package:slim/slim.dart';

class MyApp extends StatelessWidget {
  MyApp() {
    SlimLocalizations.supportedLocales = [Locale('en', 'US')];
  }

  [@override](/user/override)
  Widget build(BuildContext context) => MaterialApp(
        builder: SlimMaterialAppBuilder.builder,
        title: 'Flutter Demo',
        theme: ThemeData(
          primarySwatch: Colors.blue,
          visualDensity: VisualDensity.adaptivePlatformDensity,
        ),
        home: MyHomePage("First Screen"),
        localizationsDelegates: SlimLocalizations.delegates,
        supportedLocales: SlimLocalizations.supportedLocales,
      );
}

本地化(Localization)

UI 方向

上述配置会根据操作系统语言自动调整 UI 的方向(ltr/rtl)。可以通过 BuildContext 扩展方法获取当前文本方向:

context.textDirection

翻译

如果没有提供自定义的 SlimLocaleLoader,则会使用默认的配置。默认的 SlimLocaleLoader 期望语言文件位于 assets/locales/ 文件夹中,例如 assets/locales/en.json。默认的语言文件格式是一个单层 JSON 文件。

示例 JSON 文件:

{
  "welcome": "欢迎",
  "hello": "你好"
}

访问翻译的方法是通过 BuildContext 的扩展方法 translate

[@override](/user/override)
Widget build(BuildContext context) => Text(context.translate('welcome'));

UI 消息(UI Messages)

slim 提供了多种 UI 消息展示方式,如覆盖层、文本消息和 Snackbar。

方法:

showWidget(Widget widget, {bool dismissible = true, Color overlayColor = Colors.black, double overlayOpacity = .6})
showOverlay(String message, {Color backgroundColor = Colors.black, bool dismissible = true, textStyle = const TextStyle(color: Colors.white), Color overlayColor = Colors.black, double overlayOpacity = .6})
showSnackBar(String message, {Color messageBackgroundColor = Colors.black, messageTextStyle = const TextStyle(color: Colors.white)})

示例代码:

[@override](/user/override)
Widget build(BuildContext context) => Column(children: [
      FlatButton(
        child: Text('显示消息'),
        onPressed: () => context.showOverlay("一些文字"),
      ),
      FlatButton(
        child: Text('显示 Snackbar'),
        onPressed: () => context.showSnackBar("一些文字"),
      ),
      FlatButton(
        child: Text('显示 Widget'),
        onPressed: () => context.showWidget(
          Container(
            height: 100,
            width: 100,
            color: Colors.black,
          ),
        ),
      ),
    ]);

状态管理(State Management)

slim 使用基于 InhertiedNotifierChangeNotifier 的状态管理模式。

SlimController

这是一个抽象类,可以从任意位置访问,并且提供了重建 UI 的选项。

方法:

updateUI({bool current = false}) - 刷新所有或当前引用的 UI。
closeKeyBoard() - 请求关闭键盘。

SlimAppStateController

继承自 SlimController,接收 AppLifecycleState 事件。必须通过 SlimBuilder 访问。

示例代码:

class Counter extends SlimController {
  int value = 0;

  void inc() {
    value++;
  }
}

单独使用 Slim

Slim<Counter>(child: someWidget, stateObject: Counter());

使用 Slimer

Slimer<Counter>(Counter()).slim(someWidget);

多个 Slim

MultiSlim(child: someWidget, slimers: [Slimer<Counter>(Counter())]);

访问树中的 Slim 对象:

// 使用 SlimBuilder
SlimBuilder<Counter>(
  builder: (counter) => someWidget,
);

// 直接访问
final counter = Slim.of<Counter>(context);

有用的扩展方法(Useful Extensions)

slim 提供了一些扩展方法来增强常见类的功能。

String 扩展:

bool isNullOrEmpty
bool isNotNullOrEmpty
String format(List<dynamic> variables)

BuildContext 扩展:

bool hasOverlay
void clearOverlay()
void forceClearOverlay()
void showWidget(Widget widget, {bool dismissible = true})
void showOverlay(String message, {Color backgroundColor = Colors.black, ...})
void showSnackBar(String message, {Color backgroundColor = Colors.black, ...})
T slim<T>()
double width
double height
NavigatorState navigator
void pop<T>({T result})
Future<T> push<T>(Route<T> route)
Future<T> pushReplacement<T>(Route<T> route)
void popTop()
String translate(String key, [String group])
TextDirection textDirection
void closeKeyboard()

Widget 扩展:

Future<T> push<T>(BuildContext context)
Future<T> pushReplacement<T>(BuildContext context)
Future<T> pushTop<T>(BuildContext context)

int 扩展:

Duration get seconds
Duration get hours
Duration get days
Duration get minutes
Duration get milliseconds
Duration get microseconds
DateTime get nowMinutesInterval

REST API(RestApi)

SlimApi 是一个抽象类,提供了快速编写服务的 REST 方法(GET、DELETE、POST、PUT)。

示例代码:

class LoginService extends SlimApi {
  LoginService() : super("http://myserver.com/api");

  Future<SlimResponse> login(User user) =>
      post("login", {"userName": user.userName, "password": user.password});

  Future<SlimResponse> logout(User user) =>
      post("logout", {"userName": user.userName});
}

完整示例(Full Example)

以下是一个结合了大部分 slim 功能的完整示例。

示例代码:

import 'package:slim/slim.dart';

class User {
  String userName;
  String password;
}

class LoginService extends SlimApi {
  LoginService() : super("http://myserver.com/api");

  Future<SlimResponse> login(User user) =>
      post("login", {"userName": user.userName, "password": user.password});

  Future<SlimResponse> logout(User user) =>
      post("logout", {"userName": user.userName});
}

class LoginController extends SlimController {
  void badLogin(User user) async {
    final loginService = slim<LoginService>();
    showWidget(CircularProgressIndicator(), dismissible: false);
    final result = await loginService.login(user);
    forceClearOverlay();
    if (result.success)
      Home().pushReplacement(context);
    else
      context.showSnackBar(
        context.translate("badcreds"),
        backgroundColor: Colors.red,
      );
  }

  void goodLogin(User user) async {
    final loginService = slim<LoginService>();
    showWidget(CircularProgressIndicator(), dismissible: false);
    await loginService.login(user);
    forceClearOverlay();
    Home().pushReplacement(context);
  }
}

class Login extends SlimWidget<LoginController> {
  [@override](/user/override)
  Widget slimBuild(BuildContext context, LoginController controller) {
    final user = context.slim<User>();
    return Scaffold(
      backgroundColor: Colors.blue,
      body: Center(
        child: Container(
          width: context.width * 0.8,
          child: Card(
            elevation: 5,
            child: Padding(
              padding: const EdgeInsets.all(20.0),
              child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                mainAxisSize: MainAxisSize.min,
                children: <Widget>[
                  Text(
                    context.translate("loginform"),
                    style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
                  ),
                  SizedBox(height: 20),
                  TextFormField(
                    decoration: InputDecoration(hintText: "Username"),
                    initialValue: user.userName,
                    onChanged: (value) => user.userName = value,
                  ),
                  TextFormField(
                    decoration: InputDecoration(hintText: "Password"),
                    initialValue: user.password,
                    onChanged: (value) => user.password = value,
                    obscureText: true,
                  ),
                  SizedBox(height: 20),
                  Row(
                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
                    children: <Widget>[
                      FlatButton(
                        child: Text(context.translate("badlogin")),
                        onPressed: () => controller.badLogin(user),
                        color: Colors.pink,
                      ),
                      FlatButton(
                        child: Text(context.translate("goodlogin")),
                        onPressed: () => controller.goodLogin(user),
                        color: Colors.green,
                      )
                    ],
                  ),
                ],
              ),
            ),
          ),
        ),
      ),
    );
  }
}

class Home extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return SlimBuilder<User>(
      builder: (user) => Scaffold(
        backgroundColor: Colors.lightBlue,
        body: Center(
          child: Text("${context.translate("hi")} ${user.userName}"),
        ),
      ),
    );
  }
}

更多关于Flutter轻量级UI组件插件slim的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter轻量级UI组件插件slim的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


Slim 是一个轻量级的 Flutter UI 组件库,旨在帮助开发者快速构建简洁、高效的 UI 界面。它提供了一系列预定义的组件和样式,可以减少重复代码的编写,同时保持代码的简洁性和可维护性。

安装 Slim

首先,你需要在 pubspec.yaml 文件中添加 slim 依赖:

dependencies:
  flutter:
    sdk: flutter
  slim: ^0.1.0  # 请使用最新的版本号

然后运行 flutter pub get 来安装依赖。

使用 Slim 组件

Slim 提供了一些常见的 UI 组件,例如按钮、卡片、文本样式等。以下是一些常见组件的使用示例:

1. SlimButton

SlimButton 是一个简单的按钮组件,支持自定义样式和点击事件。

import 'package:flutter/material.dart';
import 'package:slim/slim.dart';

class MyHomePage extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Slim Example'),
      ),
      body: Center(
        child: SlimButton(
          onPressed: () {
            print('Button Pressed');
          },
          text: 'Click Me',
        ),
      ),
    );
  }
}

2. SlimCard

SlimCard 是一个简单的卡片组件,支持自定义内容和样式。

import 'package:flutter/material.dart';
import 'package:slim/slim.dart';

class MyHomePage extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Slim Example'),
      ),
      body: Center(
        child: SlimCard(
          child: Text('This is a SlimCard'),
        ),
      ),
    );
  }
}

3. SlimText

SlimText 是一个文本组件,支持自定义样式。

import 'package:flutter/material.dart';
import 'package:slim/slim.dart';

class MyHomePage extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Slim Example'),
      ),
      body: Center(
        child: SlimText(
          'Hello, Slim!',
          style: TextStyle(fontSize: 24, color: Colors.blue),
        ),
      ),
    );
  }
}

自定义主题

Slim 还支持自定义主题,你可以通过 SlimTheme 来定义全局样式。

import 'package:flutter/material.dart';
import 'package:slim/slim.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Slim Example',
      theme: SlimTheme.light(),  // 使用 Slim 提供的默认亮色主题
      home: MyHomePage(),
    );
  }
}

你还可以自定义主题:

ThemeData myTheme = ThemeData(
  primaryColor: Colors.blue,
  accentColor: Colors.orange,
  // 其他自定义样式
);

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Slim Example',
      theme: myTheme,  // 使用自定义主题
      home: MyHomePage(),
    );
  }
}
回到顶部