Flutter使用思源字体

1、找到字体ttf

https://github.com/Pal3love/Source-Han-TrueType

2、导入项目

  fonts:
- family: NotoSerif
  fonts:
  - asset: assets/fonts/NotoSerif-Regular.ttf
  - asset: assets/fonts/SourceHanSansCN-Light.ttf

3、使用

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

void main() {

  // declare the text style
  const textStyle = const TextStyle(
    fontFamily: 'NotoSerif',
  );

// use the text style
  var buttonText = const Text(
    "思源宋体",
    style: textStyle,
  );

  runApp(MaterialApp(
    home: Scaffold(
      body: Center(
        child: RaisedButton(
          onPressed: _incrementCounter,
          child: buttonText,
        ),
      ),
    ),
  ));
}

_incrementCounter() async {
  SharedPreferences prefs = await SharedPreferences.getInstance();
  int counter = (prefs.getInt('counter') ?? 0) + 1;
  print('Pressed $counter times.');
  await prefs.setInt('counter', counter);
}

flutter 构造函数总结

总结:

记住构造函数是不能被继承的,这将意味着子类不能继承父类的命名式构造函数,如果你想在子类中提供一个与父类命名构造函数名字一样的命名构造函数,则需要在子类中显式地声明

如果类A 没有显示声明构造函数,那么它将有一个默认的构造函数,这个构造函数 没有参数

如果这个类有父类,

a: 父类没有显示声明构造函数,或者写了一个普通无参构造

那么A构造函数(无论默认构造还是命名构造等),还会默认调用父类的无参数构造函数

b:父类显示声明构造函数

那么A类必须要有非默认构造函数(否则会把报错),且必须显示调用父类其中一个构造函数

1、默认构造函数

如果你定义了一个类,而没有定义构造函数,那么它将有一个默认的构造函数,这个构造函数 没有参数

如果这个类有父类,那么默认构造函数,还会默认调用父类的无参数构造函数。

如果自己写了构造函数,那就会覆盖默认构造(这个不存在了),

class People{
  String peopleName;
  People(String peopleName){
  }
}

class Student extends People{
  String studentName;
}

自己可以写个同样的无参构造进行覆盖默认无参构造

class People{
  String name;
  int age;
  int sex;
  People(){

  }
}

2、普通构造函数

声明一个和类名相同的函数,来作为类的构造函数

class Person {
    String name;
    num age;
    Person(String name, num age) {
      this.name = name;
      this.age = age;
    }
  }

Dart 中可以简写:


说明 普通构造函数不能重载,

并且子类必须显示的调用

explicitly invokes a constructor 显示的调用一个构造函数

3、命名构造函数

使用命名构造函数可为一个类实现多个构造函数,但是同样不能重载

子类必须显式的调用其中的一个

class Student extends People{
  String studentName;

  Student.studentinit() : super.init();
}

这里可以实现 构造函数的私有化 比如单例中的使用

4、调用父类构造函数

默认情况下,子类的构造函数会调用父类的匿名无参数构造方法,并且该调用会在子类构造函数的函数体代码执行前,如果子类构造函数还有一个初始化列表,那么该初始化列表会在调用父类的该构造函数之前被执行,总的来说,这三者的调用顺序如下:

  1. 初始化列表
  2. 父类的构造函数
  3. 当前类的构造函数

如果父类没有匿名无参数构造函数,那么子类必须调用父类的其中一个构造函数,为子类的构造函数指定一个父类的构造函数只需在构造函数体前使用(:)指定。

因为参数会在子类构造函数被执行前传递给父类的构造函数,因此该参数也可以是一个表达式,比如一个函数:

class Employee extends Person {
  Employee() : super.fromJson(defaultData);
  // ···
}

注意:

传递给父类构造函数的参数不能使用 this 关键字,因为在参数传递的这一步骤,子类构造函数尚未执行,子类的实例对象也就还未初始化,因此所有的实例成员都不能被访问,但是类成员可以。

class Student extends People{
String studentName;
String studentAge;
String studentSex;
int age1
Student(
    this.studentAge,
    {
      this.studentSex,
      int age
    }
    ):studentName = "1", this.age1 = age ?? 10,  super(age);

}


不能同时在构造器和初始化列表中同时初始化,

下面是两种不通过的写法

class People{
  String name;
  int age;
  int sex;
  People(int age){

  }

}

import 'People.dart';

class Student extends People {
  String studentName;
  String studentAge;
  String studentSex;
  String studentSex1;

  Student(this.studentAge,
      {
        this.studentSex,
        int age
      })
      :studentName = "1",
        super(age);


  Student.init(this.studentAge, {this.studentName: "22", this.studentSex1 = "33", int age})
      : studentSex = "1",
        super(age){

  }
}

5. 构造函数传递(重定向构造函数)

定义构造函数的时候,除了一个普通构造函数,还可以有若干命名构造函数,这些构造函数之间,有时候会有一些相同的逻辑,如果分别书写在各个构造函数中,会有些多余,所以构造函数可以传递。

class Point {
  num x, y;

  // The main constructor for this class.
  Point(this.x, this.y);

  // Delegates to the main constructor.
  Point.alongXAxis(num x) : this(x, 0);
}

class Point {
  num x, y,z;

  // The main constructor for this class.
  Point(this.x, this.y);
  Point.aaa(this.x,this.y,this.z);

  // Delegates to the main constructor.
  Point.alongXAxis(num x):this.aaa(x,0,x);
}

复制代码

传递构造函数,没有方法体,会在初始化列表中,调用另一个构造函数。

6常量构造函数

class ImmutablePoint {
  static final ImmutablePoint origin =
      const ImmutablePoint(0, 0);

  final num x, y;

  const ImmutablePoint(this.x, this.y);
}
复制代码

如果你的类,创建的对象永远不会改变,你可以在编译期就创建这个常量实例,并且定义一个常量构造函数,并且确保所有的成员变量都是final的。

7工厂构造函数的定义

工厂构造函数是一种构造函数,与普通构造函数不同,工厂函数不会自动生成实例,而是通过代码来决定返回的实例对象.

使用 factory 关键字标识类的构造函数将会令该构造函数变为工厂构造函数,这将意味着使用该构造函数构造类的实例时并非总是会返回新的实例对象。例如,工厂构造函数可能会从缓存中返回一个实例,或者返回一个子类型的实例。

以下示例演示了从缓存中返回对象的工厂构造函数:

class Logger {
  final String name;
  bool mute = false;

  // _cache 变量是库私有的,因为在其名字前面有下划线。
  static final Map<String, Logger> _cache =
      <String, Logger>{};

  factory Logger(String name) {
    return _cache.putIfAbsent(
        name, () => Logger._internal(name));
  }

  Logger._internal(this.name);

  void log(String msg) {
    if (!mute) print(msg);
  }
}

在工厂构造函数中无法访问 this

flutter 去掉右上角debug

初始化MaterialApp的时候,将debugShowCheckedModeBanner设置为false即可。

 

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner:false,
      title: 'Flutter Demo',
      theme: ThemeData(
        // This is the theme of your application.
        //
        // Try running your application with "flutter run". You'll see the
        // application has a blue toolbar. Then, without quitting the app, try
        // changing the primarySwatch below to Colors.green and then invoke
        // "hot reload" (press "r" in the console where you ran "flutter run",
        // or simply save your changes to "hot reload" in a Flutter IDE).
        // Notice that the counter didn't reset back to zero; the application
        // is not restarted.
        primarySwatch: Colors.blue,
        // This makes the visual density adapt to the platform that you run
        // the app on. For desktop platforms, the controls will be smaller and
        // closer together (more dense) than on mobile platforms.
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

Flutter 中渐变的高级用法

Flutter 中渐变有三种:

  • LinearGradient:线性渐变
  • RadialGradient:放射状渐变
  • SweepGradient:扇形渐变

看下原图,下面的渐变都是在此图基础上完成。

LinearGradient

给一张图片添加从上到下的线性渐变:

ShaderMask(
  shaderCallback: (Rect bounds) {
    return LinearGradient(
      begin: Alignment.topCenter,
      end: Alignment.bottomCenter,
      colors: [Colors.red,Colors.blue,Colors.green],
    ).createShader(bounds);
  },
  blendMode: BlendMode.color,
  child: Image.asset(
    'assets/images/b.jpg',
    fit: BoxFit.cover,
  ),
)

beginend 表示渐变的方向,上面设置的方向是从顶部中间到底部中间。

color 表示渐变的颜色。

设置各个渐变色的结束点:

Color color = Colors.orange;
return ShaderMask(
  shaderCallback: (Rect bounds) {
    return LinearGradient(
        begin: Alignment.topCenter,
        end: Alignment.bottomCenter,
        colors: [color,color,Colors.transparent,Colors.transparent,color,color],
        stops: [0,.4,.41,.6,.61,1]
    ).createShader(bounds);
  },
  blendMode: BlendMode.color,
  child: Image.asset(
    'assets/images/b.jpg',
    fit: BoxFit.cover,
  ),
);

stops 的个数要对应 color

由于中间设置的渐变色为透明,所以中间是原图。

RadialGradient

RadialGradient 是放射状渐变。

ShaderMask(
      shaderCallback: (Rect bounds) {
        return RadialGradient(
          radius: .5,
          colors: <Color>[Colors.red, Colors.blue],
        ).createShader(bounds);
      },
      blendMode: BlendMode.color,
      child: Image.asset(
        'assets/images/b.jpg',
        fit: BoxFit.cover,
      ),
    )

实现中间显示圆形原图,其他地方有灰色蒙板:

ShaderMask(
  shaderCallback: (Rect bounds) {
    return RadialGradient(
      radius: .6,
      colors: <Color>[
        Colors.transparent,
        Colors.transparent,
        Colors.grey.withOpacity(.7),
        Colors.grey.withOpacity(.7)
      ],
      stops: [0, .5, .5, 1],
    ).createShader(bounds);
  },
  blendMode: BlendMode.srcATop,
  child: Image.asset(
    'assets/images/b.jpg',
    fit: BoxFit.cover,
  ),
)

SweepGradient

SweepGradient 扇形渐变效果。

ShaderMask(
  shaderCallback: (Rect bounds) {
    return SweepGradient(
      colors: <Color>[
        Colors.red,
        Colors.blue
      ],
    ).createShader(bounds);
  },
  child: Image.asset(
    'assets/images/b.jpg',
    fit: BoxFit.cover,
  ),
)

startAngleendAngle 表示开始和结束角度。

绘制渐变圆环:

Container(
        width: 200,
        height: 200,
        child: CustomPaint(
          painter: _CircleProgressPaint(.5),
        ),
      )

class _CircleProgressPaint extends CustomPainter {
  final double progress;

  _CircleProgressPaint(this.progress);

  Paint _paint = Paint()
    ..style = PaintingStyle.stroke
    ..strokeWidth = 20;

  @override
  void paint(Canvas canvas, Size size) {
    _paint.shader = ui.Gradient.sweep(
        Offset(size.width / 2, size.height / 2), [Colors.red, Colors.yellow]);
    canvas.drawArc(
        Rect.fromLTWH(0, 0, size.width, size.height), 0, pi*2, false, _paint);
  }

  @override
  bool shouldRepaint(CustomPainter oldDelegate) {
    return true;
  }
}

除了图片,可以给任何组件加入渐变效果,比如文字:

ShaderMask(
  shaderCallback: (Rect bounds) {
    return LinearGradient(
      colors: <Color>[Colors.blue, Colors.red],
      tileMode: TileMode.mirror,
    ).createShader(bounds);
  },
  blendMode: BlendMode.srcATop,
  child: Center(
    child: Text(
      '老孟,一枚有态度的程序员',
      style: TextStyle(fontSize: 24),
    ),
  ),
)

Flutter 圆角圆形图片效果图集

class _RoundImageLayoutState extends State<RoundImageLayout> {
  @override
  void initState() {
    // TODO: implement initState
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text("测试图片"),
      ),
      body: new Column(
        children: <Widget>[
//          new Image.asset(
//            "image/lake.jpg",
//            width: 20,
//            height: 20,
//          ),
          ///CircleAvatar  圆形图像
          new Container(
//      new CircleAvatar(
//          backgroundImage: new AssetImage('images/p_box1.png'),
//      backgroundColor: Colors.transparent,
//      radius: 10.0,),),

            width: 100,
            height: 100,
            child: CircleAvatar(
//              backgroundColor: Colors.red,
//              foregroundColor: Colors.green,
              radius: 10.0,
//            minRadius: 2,
//            maxRadius: 2,
              backgroundImage: AssetImage("image/lake.jpg"),
//              child: new Image.asset(
//                "image/lake.jpg",
//                width: 95,
//                height: 95,
//                fit: BoxFit.cover,
//              ),
            ),
          ),
          ///ClipOval  第三个
          new Container(
            child: new ClipOval(
              clipBehavior: Clip.antiAliasWithSaveLayer,
              child: new Image.asset(
                "image/lake.jpg",
                fit: BoxFit.cover,
                width: 50,
                height: 50,
              ),
            ),
          ),
      new Container(
        width: 100.0,
        height: 100.0,
        padding: const EdgeInsets.symmetric(horizontal: 20),
        decoration: BoxDecoration(
            border: Border.all(color: Colors.grey, width: 1.0),
            borderRadius: BorderRadius.circular(90),
//          shape: BoxShape.circle,
          image: DecorationImage(
            image: AssetImage(
                "image/ali_connors.png",
            ),
          ),
        ),
      ),
          new Container(
            padding: const EdgeInsets.symmetric(horizontal: 20),
            child: new ClipRRect(
              borderRadius: BorderRadius.only(topLeft: Radius.circular(6),topRight: Radius.circular(6),bottomLeft: Radius.zero,bottomRight:Radius.zero),
              child: new Image.asset( "image/lake.jpg",),
            ),
          ),
      new Container(
        width: 80.0,
        height: 80.0,
        decoration: BoxDecoration(
//          backgroundBlendMode: BlendMode.colorBurn,
          shape: BoxShape.rectangle,
          color: Colors.green,
//          border: Border(top: BorderSide(width: 2,color: Colors.red)),
          borderRadius: BorderRadius.circular(10.0),
          image: DecorationImage(
            fit: BoxFit.fill,  //这个地方很重要,需要设置才能充满
            image: AssetImage("image/lake.jpg",
            ),
          ),
        ),
      ),
        ],
      ),
    );
  }
}


flutter好用的轮子推荐二十一-flutter制作刮刮卡效果

前言

Flutter是谷歌的移动UI框架,可以快速在iOS和Android上构建高质量的原生用户界面。

IT界著名的尼古拉斯·高尔包曾说:轮子是IT进步的阶梯!热门的框架千篇一律,好用轮子万里挑一!Flutter作为这两年开始崛起的跨平台开发框架,其第三方生态相比其他成熟框架还略有不足,但轮子的数量也已经很多了。本系列文章挑选日常app开发常用的轮子分享出来,给大家提高搬砖效率,同时也希望flutter的生态越来越完善,轮子越来越多。

本系列文章准备了超过50个轮子推荐,工作原因,尽量每1-2天出一篇文章。

tip:本系列文章合适已有部分flutter基础的开发者,入门请戳:flutter官网

正文

轮子

  • 轮子名称:scratcher
  • 轮子概述:flutter制作刮刮卡效果.
  • 轮子作者:rykowski.dev
  • 推荐指数:★★★★
  • 常用指数:★★★
  • 效果预览:

安装

dependencies:
  scratcher: "^1.3.0"
import 'package:scratcher/scratcher.dart';

基本使用

使用 Scratcher 构建刮刮卡组件,使用示例如下:

Scratcher(
    brushSize: 30, //刷子大小(手指刮动的笔刷)
    threshold: 50, //完全刮开的阈值 百分比
    color: Colors.grey, //覆盖层的颜色
    onChange: (value) { //被刮动的回调 返回当前刮开区域百分比
        print("当前刮开比例: $value%");
    },
    onThreshold: () { //触发完全刮开的阈值回调
        print("已触发设置的全部刮开阈值");
    },
    child: Container( //覆盖层下的原本组件 一般是刮卡结果展示
        height: 150,
        width: 300,
        color: Colors.blue,
    ),
)

进阶使用

使用图片作为刮卡结果,使用key来进行编程式控制:

final scratchKey = GlobalKey<ScratcherState>();

Scratcher(
    key: scratchKey,
    brushSize: 30,
    threshold: 50,
    color: Colors.pink,
    onChange: (value) {
        print("当前刮开比例: $value%");
    },
    onThreshold: () {
        print("已触发设置的全部刮开阈值");
        scratchKey.currentState.reveal(duration: Duration(milliseconds: 500));
    },
    child: Container(
        width: 300,
        height: 150,
        child: Image.network('图片地址',fit: BoxFit.cover,),
    ),
)

编程式控制刮刮卡方法:

RaisedButton(
    child: Text("重置"),
    onPressed: (){
        scratchKey.currentState.reset();
    },
),
RaisedButton(
    child: Text("刮开"),
    onPressed: (){
        scratchKey.currentState.reveal(duration: Duration(milliseconds: 500));
    },
)

结尾

flutter好用的轮子推荐二十-flutter仿iPhone锁屏界面

前言

Flutter是谷歌的移动UI框架,可以快速在iOS和Android上构建高质量的原生用户界面。

IT界著名的尼古拉斯·高尔包曾说:轮子是IT进步的阶梯!热门的框架千篇一律,好用轮子万里挑一!Flutter作为这两年开始崛起的跨平台开发框架,其第三方生态相比其他成熟框架还略有不足,但轮子的数量也已经很多了。本系列文章挑选日常app开发常用的轮子分享出来,给大家提高搬砖效率,同时也希望flutter的生态越来越完善,轮子越来越多。

本系列文章准备了超过50个轮子推荐,工作原因,尽量每1-2天出一篇文章。

tip:本系列文章合适已有部分flutter基础的开发者,入门请戳:flutter官网

正文

轮子

  • 轮子名称:passcode_screen
  • 轮子概述:flutter仿iPhone锁屏界面.
  • 轮子作者:vladimir.hudnitsky@gmail.com
  • 推荐指数:★★★★
  • 常用指数:★★★
  • 效果预览:

安装

dependencies:
  passcode_screen: ^1.0.2
import 'package:passcode_screen/passcode_screen.dart';
import 'package:passcode_screen/circle.dart';//如需要自定义密码圆点UI时需引入
import 'package:passcode_screen/keyboard.dart';//如需要自定义键盘UI时需引入

基本使用

使用 PasscodeScreen 构建密码锁屏界面,参数配置如下:

PasscodeScreen(
    title: "请输入锁屏密码",
    passwordEnteredCallback: _onPasscodeEntered,//密码输入后的处理方法
    cancelLocalizedText: '取消',//取消按钮文字
    deleteLocalizedText: '删除',//删除按钮文字
    shouldTriggerVerification: _verificationNotifier.stream,//控制器通知
    circleUIConfig: CircleUIConfig(//自定义密码圆点ui 可不填
        borderColor: color,
        fillColor: color,
        circleSize: 30
    ),
    keyboardUIConfig: KeyboardUIConfig(digitBorderWidth: 2, primaryColor: color),//自定义键盘ui 可不填
    backgroundColor: Colors.black.withOpacity(0.8),//背景透明度
    cancelCallback: _onPasscodeCancelled,//取消按钮回调  
)

示例

点击按钮弹出锁屏界面,输入123456后解锁:

1.在按钮事件中,push锁屏界面

openLockScreen(){
    Navigator.push(context,PageRouteBuilder(opaque: false,pageBuilder: (context, animation, secondaryAnimation) {
        return PasscodeScreen(
            title: "请输入锁屏密码",
            passwordEnteredCallback: _onPasscodeEntered,//密码输入后的处理方法
            cancelLocalizedText: '取消',//取消按钮文字
            deleteLocalizedText: '删除',//删除按钮文字
            shouldTriggerVerification: _verificationNotifier.stream,//控制器通知
            circleUIConfig: CircleUIConfig(//自定义密码圆点ui 可不填
                borderColor: color,
                fillColor: color,
                circleSize: 30
            ),
            keyboardUIConfig: KeyboardUIConfig(digitBorderWidth: 2, primaryColor: color),//自定义键盘ui 可不填
            backgroundColor: Colors.black.withOpacity(0.8),//背景透明度
            cancelCallback: _onPasscodeCancelled,//取消按钮回调  
        );  
    }));
}

2.定义控制器通知

final StreamController<bool> _verificationNotifier = StreamController<bool>.broadcast();
//需引入 import 'dart:async';

3.密码输入后的处理方法 _onPasscodeEntered 与点击取消处理方法 _onPasscodeCancelled

_onPasscodeEntered(String enteredPasscode) {
    bool isValid = '123456' == enteredPasscode;
    _verificationNotifier.add(isValid);
}
_onPasscodeCancelled(){
    print("点击取消");
}

4.在页面销毁时注销控制器

@override
void dispose() {
    _verificationNotifier.close();
    super.dispose();
}

结尾

flutter好用的轮子推荐十九-flutter水波效果的进度器

前言

Flutter是谷歌的移动UI框架,可以快速在iOS和Android上构建高质量的原生用户界面。

IT界著名的尼古拉斯·高尔包曾说:轮子是IT进步的阶梯!热门的框架千篇一律,好用轮子万里挑一!Flutter作为这两年开始崛起的跨平台开发框架,其第三方生态相比其他成熟框架还略有不足,但轮子的数量也已经很多了。本系列文章挑选日常app开发常用的轮子分享出来,给大家提高搬砖效率,同时也希望flutter的生态越来越完善,轮子越来越多。

本系列文章准备了超过50个轮子推荐,工作原因,尽量每1-2天出一篇文章。

tip:本系列文章合适已有部分flutter基础的开发者,入门请戳:flutter官网

正文

轮子

  • 轮子名称:liquid_progress_indicator
  • 轮子概述:flutter液体效果的页面切换组件.
  • 轮子作者:jordandavies1990@live.co.uk
  • 推荐指数:★★★★
  • 常用指数:★★★
  • 效果预览:

安装

dependencies:
  liquid_progress_indicator: ^0.3.2
import 'package:liquid_progress_indicator/liquid_progress_indicator.dart';

使用方法

条形进度器

LiquidLinearProgressIndicator(
    value: 0.8, //当前进度 0-1
    valueColor: AlwaysStoppedAnimation(Colors.greenAccent), // 进度值的颜色.
    backgroundColor: Colors.white, // 背景颜色.
    borderColor: Colors.green,//边框颜色
    borderWidth: 2.0,//边框宽度
    direction: Axis.horizontal, // 进度方向 (Axis.vertical = 从下到上, Axis.horizontal = 从左到右). 默认:Axis.vertical
    center: Text("正在加载..."), //中间显示的组件 
)

效果图:

圆形进度器

LiquidCircularProgressIndicator(
    value: 0.8, //当前进度 0-1
    valueColor: AlwaysStoppedAnimation(Colors.blue[200]), // 进度值的颜色.
    backgroundColor: Colors.white, // 背景颜色.
    borderColor: Colors.blue,//边框颜色
    borderWidth: 2.0,//边框宽度
    direction: Axis.vertical, // 进度方向 (Axis.vertical = 从下到上, Axis.horizontal = 从左到右). 默认:Axis.vertical
    center: Text("正在上传..."), //中间显示的组件 
)

效果图:

自定义形状进度器

LiquidCustomProgressIndicator(
    value: 0.2 ,
    valueColor: AlwaysStoppedAnimation(Colors.pink), 
    backgroundColor: Colors.pink[50], 
    direction: Axis.vertical, 
    shapePath: _buildHeartPath(), // 自定义形状路径
),
Path _buildHeartPath() {
    return Path()
    ..moveTo(55, 15)
    ..cubicTo(55, 12, 50, 0, 30, 0)
    ..cubicTo(0, 0, 0, 37.5, 0, 37.5)
    ..cubicTo(0, 55, 20, 77, 55, 95)
    ..cubicTo(90, 77, 110, 55, 110, 37.5)
    ..cubicTo(110, 37.5, 110, 0, 80, 0)
    ..cubicTo(65, 0, 55, 12, 55, 15)
    ..close();
}

效果图:

更多用法请参考pub轮子主页

结尾

flutter好用的轮子推荐十八-flutter液体效果的页面切换组件

前言

Flutter是谷歌的移动UI框架,可以快速在iOS和Android上构建高质量的原生用户界面。

IT界著名的尼古拉斯·高尔包曾说:轮子是IT进步的阶梯!热门的框架千篇一律,好用轮子万里挑一!Flutter作为这两年开始崛起的跨平台开发框架,其第三方生态相比其他成熟框架还略有不足,但轮子的数量也已经很多了。本系列文章挑选日常app开发常用的轮子分享出来,给大家提高搬砖效率,同时也希望flutter的生态越来越完善,轮子越来越多。

本系列文章准备了超过50个轮子推荐,工作原因,尽量每1-2天出一篇文章。

tip:本系列文章合适已有部分flutter基础的开发者,入门请戳:flutter官网

正文

轮子

  • 轮子名称:liquid_swipe
  • 轮子概述:flutter液体效果的页面切换组件.
  • 轮子作者:sahdeepsingh98@gmail.com
  • 推荐指数:★★★★
  • 常用指数:★★★★
  • 效果预览:

安装

dependencies:
  liquid_swipe: ^1.3.0
import 'package:liquid_swipe/Constants/Helpers.dart';
import 'package:liquid_swipe/liquid_swipe.dart';

使用方法

基础使用:

LiquidSwipe(
    pages: [],//页面列表
    fullTransitionValue: 200,//滑动阀值
    enableSlideIcon: true,//显示右侧图标
    enableLoop: true,//循环切换
    positionSlideIcon: 0.5,//右侧图标的位置
    waveType: WaveType.liquidReveal,//切换效果
    onPageChangeCallback: (page) => pageChangeCallback(page),//页面切换回调
    currentUpdateTypeCallback: (updateType) => updateTypeCallback(updateType),//当前页面更新回调

完整示例:

class LiquidSwipeDemo extends StatefulWidget {
    LiquidSwipeDemo({Key key}) : super(key: key);

    @override
    _demoState createState() => _demoState();
    }

    class _demoState extends State<LiquidSwipeDemo> {

    WaveType currentAnimate=WaveType.liquidReveal;

    void changeAnimate(){
        setState(() {
            if(currentAnimate==WaveType.liquidReveal){
                currentAnimate=WaveType.circularReveal;
            }else{
                currentAnimate=WaveType.liquidReveal;
            }
        });
    }

    @override
    Widget build(BuildContext context) {
        return Scaffold(
            appBar: AppBar(
                title: Text("liquid_swipe"),
                actions: <Widget>[
                    GoWeb(pluginName: 'liquid_swipe')
                ],
            ),
            body: LiquidSwipe(
                pages: [
                    Container(
                        color: Colors.blue,
                        child: Center(
                            child: FlatButton(
                                child: Text("切换效果"),
                                onPressed: (){
                                    changeAnimate();
                                },
                            ),
                        ),
                    ),
                    Container(
                        color: Colors.pink,
                    ),
                    Container(
                        color: Colors.teal,
                        child: ConstrainedBox(
                            child:Image.network('http://hbimg.b0.upaiyun.com/c9d0ae1ea6dafe5b7af0e2387e161778d7a146b83f571-ByOb1k_fw658',
                            fit: BoxFit.cover,),
                            constraints: new BoxConstraints.expand(),
                        )
                    ),
                ],
                fullTransitionValue: 200,
                enableSlideIcon: true,
                enableLoop: true,
                positionSlideIcon: 0.5,
                waveType: currentAnimate,
                onPageChangeCallback: (page) => pageChangeCallback(page),
                currentUpdateTypeCallback: (updateType) => updateTypeCallback(updateType),
                ),
        );
    }

    pageChangeCallback(int page) {
        print(page);
    }
    updateTypeCallback(UpdateType updateType) {
        print(updateType);
    }
}

更多用法请参考pub轮子主页

结尾