Flutter 组件学习

208 阅读3分钟

AbsorbPointer

AbsorbPointer 可以禁止用户交互,如按钮点击,输入框输入,ListView 滚动等,相当于onPressd 设置为null, 但其优势是可以提供多组控件统一控制。

IgnorePointer 可以实现相同的逻辑,据说区别在于它的点击事件可以向后传递,但实测并没有。

AbsorbPointer(
  absorbing: true,
  child: Container(
    width: 200,
    height: 200,
    child: ElevatedButton(
        style:
            ElevatedButton.styleFrom(backgroundColor: Colors.green),
        onPressed: () {
          print('AbsorbPointer');
        },
        child: Text('a')),
  ),
),

AbsorbPointer(
  child: Row(
    children: <Widget>[
      ElevatedButton(onPressed: (){},child: Text('a')),
      ElevatedButton(onPressed: (){},child: Text('b')),
      ElevatedButton(onPressed: (){},child: Text('c')),
      ElevatedButton(onPressed: (){},child: Text('d')),

    ],
  ),
)

Align

Align 组件用于调整位置,使用简单,主要是明白他的坐标体系。

image.png

ImageFilter

ImageFilter 可以将图片模糊处理 BackdropFilter可以模糊任何组件,并且只模糊下面的组件,并不模糊child 组件。

Stack(
  alignment: Alignment.center,
  children: <Widget>[
    Container(
      width: 300,
      height: 400,
      child: Image.asset('assets/images/test/1.png'),
    ),
    BackdropFilter(
      filter: ImageFilter.blur(sigmaX: 5.0, sigmaY: 5.0),
      child: Text(
        '强东无敌',
        style: TextStyle(
            fontSize: 20, fontWeight: FontWeight.bold, color: Colors.white),
      ),
    )
  ],
);

WechatIMG552.png

Card

Card 组件可以方便的创建圆角卡片样式。

Card(
  child: Column(
    mainAxisSize: MainAxisSize.min,
    children: <Widget>[
      const ListTile(
        leading: Icon(Icons.album), //左侧图标
        title: Text('刘强'),         //标题
        
        //如果不需要换行,则必须设置overFlow
        subtitle: Text('这是一枚老菜鸟,水平菜,人品差,连头发都少',
                  style: TextStyle(overflow: TextOverflow.ellipsis),
        ),                           
                                    //副标题
        trailing: Icon(Icons.sort), //右侧图标
        isThreeLine: false,         //副标题是否换行
        dense: ture,                //内容和图标是否紧密排布
      ),
      ButtonBar(
        children: <Widget>[
          E(
            child: const Text('OK'),
            onPressed: () {
            },
          ),
          FlatButton(
            child: const Text('非常对'),
            onPressed: () {

            },
          ),
        ],
      ),
    ],
  ),
)

5541681098637_.pic.jpg

SwitchListTile

var _switchValue = false;

Center(
  child: SwitchListTile(
    title: Text('开关标题'),
    value: _switchValue,
    onChanged: (value) {
      setState(() {
        _switchValue = value;
      });
    },
  ),
);

5571681117314_.pic.jpg

LayoutBuilder

LayoutBuilder 可以获取父组件的约束尺寸

LayoutBuilder(
  builder: (BuildContext context, BoxConstraints constraints) {
    return Container(
      height: constraints.maxWidth,
      width: constraints.maxHeight,
      color: Colors.red,
    );
  },
);

Ink

Ink 设置BoxDecoration装饰,可以使Inkwell 水波纹效果得以在其上展示。

Ink(
  decoration: BoxDecoration(
      gradient: LinearGradient(
          begin: Alignment.topLeft,
          end: Alignment.bottomRight,
          colors: [Color(0xFFDE2F21), Color(0xFFEC592F)]),
      borderRadius: BorderRadius.all(Radius.circular(20))),
      
  child: InkWell(
    borderRadius: BorderRadius.all(Radius.circular(20)),
    child: Container(
      padding: EdgeInsets.symmetric(vertical: 8, horizontal: 20),
      child: Text(
        'InkWell效果',
        style: TextStyle(color: Colors.white),
      ),
    ),
    onTap: () {},
  ),
)

FittedBox

当父组件与子组件宽高比例不一致时,可以等比拉伸或填充父组件,FittedBox 可以设置填充模式。

fit参数说明:

  • fill 填充父组件,宽高比发生变化
  • contain 等比拉伸,但子组件不超过你组件
  • cover 尽可能的小,等比拉伸充满父组件
  • fitWidth 等比拉伸,宽度填满父组件
  • fitHeight 等比拉伸,高度填满父组件
  • none 默认子组件居中,不做拉伸处理,超出部分裁剪掉。
  • scaleDown: 子组件为Image且缩小时和contain一样,否则和 none 一样。
Container(
  height: 200,
  width: 200,
  color: Colors.green,
  child: FittedBox(
    fit: BoxFit.contain,
    child: Container(
      height: 50,
      width: 80,
      color: Colors.red,
    ),
  ),
);

Divider / VerticalDivider

分割线组件

Divider(
  height: 10,    //高度
  thickness: 5,  //线宽
  color: Colors.red,  //颜色
  indent: 10,      //分割线前面空白
  endIndent: 20,   //分割 线后面空白
);

FractionallySizedBox

FractionallySizedBox 设置子组件占你组件的尺寸比例

5551681116394_.pic.jpg

Center(
  child: Container(
    height: 200,
    color: Colors.grey,
    child: Column(
      children: <Widget>[
        Container(
          height: 50,
          color: Colors.red,
        ),
        Flexible(
          child: FractionallySizedBox(
            heightFactor: 0.3,
          ),
        ),
        Container(
          height: 50,
          color: Colors.blue,
        ),
      ],
    ),
  ),
);

ValueNotifier

ValueNotifier 是 ChangeNotifier 的延伸子类。 为 ValueNotifier 提供一个值,每个监听器都会收到值变化的通知。
这个值可以是任何类型的int、bool、list或任何自定义数据类型的ValueNotifier。

初始化


final ValueNotifier<String> fristName = ValueNotifier('Tom');

final ValueNotifier<String> secondName = ValueNotifier('Joy'); 

late final ValueNotifier<String> fullName;

监听/更新

void initState() { 
    super.initState();
    
    fullName = ValueNotifier('${fristName.value} ${secondName.value}'); 
    
    fristName.addListener(_updateFullName); 
    secondName.addListener(_updateFullName); 
}

void _updateFullName() {

    fullName.value = '${fristName.value} ${secondName.value}'; 
}

  
firstName.value = 'Jane';
secondName.value = 'Jane'

ValueListenableBuilder更新UI

ValueListenableBuilder(

    //数据变化时调用 
    builder: (context, value, child) {
    
        return Column(
          children: [
                if (chi != null) chi,
                Text(value),
          ],
        );      
    },
    
    valueListenable: fullName,  //监听数据
    
    child: Text('非更新值'), //此参数会回传给builder,可以为null
  );


ChangeNotifier

ChangeNotifier 也用于监听数据变化

定义一个私有变量 _count,和一个公有的 count, 增加一个 addCount 方法,并通过 notifyListeners通知所有监听者。

class Counter extends ChangeNotifier{//这里也可以使用with来进行实现

  int _count = 0;

  int get count => _count;

  addCount(){
    _count++;
    notifyListeners();
  }
}

使用

Counter _counter =  Counter();

_counter.addListener(() {
  //数值改变的监听
  print('------>新数值:${_counter.count}');
});

//_counter.dispose();//移除监听

使用AnimatedBuilder 更新UI

 AnimatedBuilder( 
     animation: _counter,
     builder: (context, child) => Text(_counter.count),
   ),