Flutter实现点赞

这里用到Flutter的Stack,最近整体学完一遍后再仔细看看文档写博客。

Stack

  1. 其childWidget 可以层叠到一起,层叠顺序:Widget越后创建,层级越靠上
  2. 可以控制没有定位的childWidget的布局策略
Stack({
  this.alignment = AlignmentDirectional.topStart,
  this.textDirection,
  this.fit = StackFit.loose,
  this.overflow = Overflow.clip,
  List<Widget> children = const <Widget>[],
})
  • alignment
    决定如何去对齐没有定位(没有使用Positioned)或部分定位的子widget。所谓部分定位,在这里特指没有在某一个轴上定位:left、right为横轴,top、bottom为纵轴,只要包含某个轴上的一个定位属性就算在该轴上有定位
  • textDirection
    和Row、Wrap的textDirection功能一样,都用于决定alignment对齐的参考系即:textDirection的值为TextDirection.ltr,则alignment的start代表左,end代表右;textDirection的值为TextDirection.rtl,则alignment的start代表右,end代表左。
  • fit
    此参数用于决定没有定位的子widget如何去适应Stack的大小。StackFit.loose表示使用子widget的大小,StackFit.expand表示扩伸到Stack的大小。
  • overflow
    此属性决定如何显示超出Stack显示空间的子widget,值为Overflow.clip时,超出部分会被剪裁(隐藏),值为Overflow.visible 时则不会。

IndexedStack

继承自Stack,表示只显示第几个widget,其他隐藏

Positioned

const Positioned({
  Key key,
  this.left, 
  this.top,
  this.right,
  this.bottom,
  this.width,
  this.height,
  @required Widget child,
})
  1. left、right、bottom、top分别表示 距离stack的边的距离
  2. width、height表示宽高。Widget在指定left与width后,就自动确定了right。如果在设置right,则报错。其他情况(指定top与height,不能再指定bottom等)类似。
  3. 只能在Stack 的childs中使用。目前测试,在其他的Widget中使用会报错。

实现点赞

整体代码

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';

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

//ctrl+alt+w抽取新的widget
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(debugShowCheckedModeBanner: false, home: HomePage());
  }
}

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('注册'),
      ),
      body: MyHomeBody(),
      floatingActionButton: FloatingActionButton(
        child: Icon(Icons.add),
      ),
    );
  }
}

class MyHomeBody extends StatefulWidget {
  @override
  _MyHomeBodyState createState() => _MyHomeBodyState();
}

class _MyHomeBodyState extends State<MyHomeBody> {
  var n = false;

  @override
  Widget build(BuildContext context) {
    return Container(
      height: 200,
      child: Stack(overflow: Overflow.visible, //超出范围也可见
          children: <Widget>[
            Image.asset('asserts/images/校徽.jpg'),
            Positioned(    //内部的位置
              left: 0,  
              right: 0,
              bottom: 0,
              child: Container(
                  padding: EdgeInsets.symmetric(horizontal: 8),  //边距
                  color: Color.fromARGB(100, 0, 0, 0),  //展示的颜色,第一个数据为透明度
                  child: Row(  //行
                    mainAxisAlignment: MainAxisAlignment.spaceBetween, //between表示在两端
                    children: <Widget>[
                      Text("校徽"),
                      IconButton(
                        icon: Icon(Icons.favorite, color: n?Colors.red:Colors.white), //也可以写成函数
                        onPressed: (){
                          setState(() {
                            n=!n;  //更改状态,重建build
                          });
                        },
                      )
                    ],
                  )),
            )
          ]),
    );
  }
}

实现效果

其实flutter还有很多好看的效果,但是属性数目很多。还需要再研究。

发表评论