【flutter】篇7:加入交互式

文档网址

  1. 静态:Icon --> 动态: IconButton
    加入交互式,需要两个类,1.是stateful widget,该widget调用自己的构造方法以及创造一个state类,createstate 2.是State对象,里面存储一些变量等信息可以动态的改变,通过调用动态组件,可以捕获点击状态,从而改变变量的状态,改变渲染的数值的大小。
    下面这段代码基于以前的静态代码博客
    代码:
class FavoriteWidget extends StatefulWidget {
  const FavoriteWidget({Key? key}) : super(key: key);

  @override
  State<FavoriteWidget> createState() => _FavoriteWidgetState();
}
class _FavoriteWidgetState extends State<FavoriteWidget> {
  bool _isFavorited = true;
  int _favoriteCount = 41;
  void _toggleFavorite(){
    //可以改变外观
    setState(() {
      if(_isFavorited){
        _isFavorited = false;
        _favoriteCount -= 1;
      }
      else{
        _isFavorited = true;
        _favoriteCount += 1;
      }
    });
  }
  @override
  Widget build(BuildContext context) {
    return Row(
      mainAxisSize: MainAxisSize.min,
      children: [
        Container(
          padding: const EdgeInsets.all(8),
          child: IconButton(
            padding: const EdgeInsets.all(0),
            alignment: Alignment.centerRight,
            icon:(//这一步就是对图标的选择,选择的条件是开设一个变量,进行真假变换
              _isFavorited? const Icon(Icons.star):const Icon(Icons.star_border)
            ),
            color: Colors.red[500],
            onPressed: _toggleFavorite,
          )
        ),
        SizedBox(
          width: 18,
          child:Text('$_favoriteCount')//变量动态改变页面
        )
      ],
    );
  }
}

嵌入到静态代码,直接就是:const FavoriteWidget();即可

ManageState

管理对象的方式有自己管理对象,适用于美术类的场景,比如动画。或者是父widget管理对象,适用于和用户的数据打交道的场景

自己管理状态

class interactive4 extends StatelessWidget {
  const interactive4({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: "Flutter app",
      home: Scaffold(
        appBar: AppBar(
         title: const Text("Flutter Demo"),
        ),
        body: Center(child: Tapbox()),
      ),
    );
  }
}
class Tapbox extends StatefulWidget {
  const Tapbox({Key? key}) : super(key: key);

  @override
  State<Tapbox> createState() => _TapboxState();
}
class _TapboxState extends State<Tapbox> {
  bool state1 = false;
  void changeState1(){
    setState(() {
      state1 = !state1;
    });
  }
  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: changeState1,
      child: Container(
        width: 200,
        height: 200,
        decoration: BoxDecoration(
          color: state1?Colors.green:Colors.black12,
        ),
        child: Center(
          child:Text(
             state1?"Active":"Inactive",
             style: TextStyle(fontSize: 50),
         ),
        )
      ),
    );
  }
}

在这里插入图片描述
在这里插入图片描述

父widget管理状态

import 'package:flutter/material.dart';

// ParentWidget manages the state for TapboxB.

//------------------------ ParentWidget --------------------------------

class ParentWidget extends StatefulWidget {
  const ParentWidget({super.key});

  @override
  State<ParentWidget> createState() => _ParentWidgetState();
}

class _ParentWidgetState extends State<ParentWidget> {
  bool _active = false;

  void _handleTapboxChanged(bool newValue) {
    setState(() {
      _active = newValue;
    });
  }

  @override
  Widget build(BuildContext context) {
    return SizedBox(
      child: TapboxB(
        active: _active,
        onChanged: _handleTapboxChanged,
      ),
    );
  }
}

//------------------------- TapboxB ----------------------------------

class TapboxB extends StatelessWidget {
  const TapboxB({
    super.key,
    this.active = false,
    required this.onChanged,
  });

  final bool active;
  final ValueChanged<bool> onChanged;

  void _handleTap() {
    onChanged(!active);
  }

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: _handleTap,
      child: Container(
        width: 200.0,
        height: 200.0,
        decoration: BoxDecoration(
          color: active ? Colors.lightGreen[700] : Colors.grey[600],
        ),
        child: Center(
          child: Text(
            textDirection: TextDirection.ltr,
            active ? 'Active' : 'Inactive',
            style: const TextStyle(fontSize: 32.0, color: Colors.white),
          ),
        ),
      ),
    );
  }
}

二者的区别:

共同点是状态的管理都是通过一个变量,在这个例子中都是Bool变量。
自己控制状态:

  1. 自己是一个stateful widget
  2. 控制状态的变量声明在自己的state中
  3. 改变变量的setState也是在自己的state 类中
    父widget空置状态:
  4. 自己是一个stateless widget
  5. 控制状态的变量声明在父widget中,并通过传参构造穿给自己
  6. 改变变量的函数定义在父widget中 ,并通过传参构造把该函数传递给了孩子,怎么调用呢?该函数赋给了自己的一个函数,调用自己的函数就相当于调用了父widget的函数

二者融合:

例子

import 'package:flutter/material.dart';

//---------------------------- ParentWidget ----------------------------

class ParentWidgetMix extends StatefulWidget {
  const ParentWidgetMix({super.key});

  @override
  State<ParentWidgetMix> createState() => _ParentWidgetMixState();
}

class _ParentWidgetMixState extends State<ParentWidgetMix> {
  bool _active = false;

  void _handleTapboxChanged(bool newValue) {
    setState(() {
      _active = newValue;
    });
  }

  @override
  Widget build(BuildContext context) {
    return SizedBox(
      child: TapboxC(
        active: _active,
        onChanged: _handleTapboxChanged,
      ),
    );
  }
}

//----------------------------- TapboxC ------------------------------

class TapboxC extends StatefulWidget {
  const TapboxC({
    super.key,
    this.active = false,
    required this.onChanged,
  });

  final bool active;
  final ValueChanged<bool> onChanged;

  @override
  State<TapboxC> createState() => _TapboxCState();
}

class _TapboxCState extends State<TapboxC> {
  bool _highlight = false;

  void _handleTapDown(TapDownDetails details) {
    setState(() {
      _highlight = true;
    });
  }

  void _handleTapUp(TapUpDetails details) {
    setState(() {
      _highlight = false;
    });
  }

  void _handleTapCancel() {
    setState(() {
      _highlight = false;
    });
  }

  void _handleTap() {
    widget.onChanged(!widget.active);
  }

  @override
  Widget build(BuildContext context) {
    // This example adds a green border on tap down.
    // On tap up, the square changes to the opposite state.
    return GestureDetector(
      onTapDown: _handleTapDown, // Handle the tap events in the order that
      onTapUp: _handleTapUp, // they occur: down, up, tap, cancel
      onTap: _handleTap,
      onTapCancel: _handleTapCancel,
      child: Container(
        width: 200.0,
        height: 200.0,
        decoration: BoxDecoration(
          color: widget.active ? Colors.lightGreen[700] : Colors.grey[600],
          border: _highlight
              ? Border.all(
            color: Colors.teal[700]!,
            width: 10.0,
          )
              : null,
        ),
        child: Center(
          child: Text(widget.active ? 'Active' : 'Inactive',
              textDirection: TextDirection.ltr,
              style: const TextStyle(fontSize: 32.0, color: Colors.white)),
        ),
      ),
    );
  }
}

就是既有自己控制的“外观变量(_highlgiht)”,以及父 widget的“外观变量(_active)”,然后分别在不同场景下控制就行了。
【后话:GestureDetector】

  1. GestureDetector这个组件和有用,用它包裹起来,可以很方便地捕获用户的一些动作,比如tapdown,tapup,tap,tapcance。。。

When you need interactivity, it’s easiest to use one of the prefabricated widgets. Here’s a partial list:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值