Flutter中StatefulWidget控件狀態(tài)管理的兩種方式

Flutter 有兩種狀態(tài)控件:StatelessWidget、StatefulWidget,對于有可變狀態(tài)控件的管理,官方文檔是寫了有3種模式:控件自己管理狀態(tài)、交給父控件管理狀態(tài)以及混合管理。我個人初學對于自己管理比較好理解,對于父控件管理理解起來有點困難,所以只能多看多學。這里寫一下兩種狀態(tài)管理的方式和代碼,加深自己的印象,尤其是父控件管理方式。

項目說明:兩種方式實現(xiàn)一個容器盒子,點擊的時候切換顏色和顯示內(nèi)容。我將把這兩個盒子做到一個頁面,雖然最終效果是一樣的,但是實現(xiàn)方式不同。

一、控件自身管理自己的狀態(tài)

/*
TapBoxA 是自身widget管理自己狀態(tài)
 */
class TapBoxA extends StatefulWidget {
  @override
  _TapBoxAState createState() {
    return new _TapBoxAState();
  }
}
 
class _TapBoxAState extends State<TapBoxA> {
  bool _aActive = false;
 
  void _aActiveChanged() {
    setState(() {
      if (_aActive) {
        _aActive = false;
      } else {
        _aActive = true;
      }
    });
  }
 
  @override
  Widget build(BuildContext context) {
    return new GestureDetector(
      onTap: _aActiveChanged,
      child: new Center(
        child: new Container(
          alignment: Alignment.center,
          width: 200.0,
          height: 200.0,
          child: new Text(
            _aActive ? 'Active' : 'Inactive',
            style: new TextStyle(fontSize: 50.0, color: Colors.white),
          ),
          decoration: new BoxDecoration(
              color: _aActive ? Colors.green[400] : Colors.grey),
        ),
      ),
    );
  }
}

二、由父控件管理子控件的狀態(tài)
子控件自身是無狀態(tài)的控件,但是父控件會在子控件發(fā)生變化以后得知這一更新,并進行狀態(tài)的更新以及控件的重繪。

/*
TapBoxB 是父widget管理子widget狀態(tài);
TapBoxB 繼承自無狀態(tài)控件,不管理任何狀態(tài)
 */
class TapBoxB extends StatelessWidget {
  TapBoxB({Key key, this.bActive: false, this.onChanged}) : super(key: key);
  final bActive;
  final ValueChanged<bool> onChanged;
 
  void _bActiveChanged() {
    onChanged(!bActive);
  }
 
  @override
  Widget build(BuildContext context) {
    return new GestureDetector(
      onTap: _bActiveChanged,
      child: new Center(
        child: new Container(
          alignment: Alignment.center,
          width: 200.0,
          height: 200.0,
          child: new Text(
            bActive ? 'Active' : 'Inactive',
            style: new TextStyle(fontSize: 50.0, color: Colors.white),
          ),
          decoration: new BoxDecoration(
              color: bActive ? Colors.green[400] : Colors.grey),
        ),
      ),
    );
  }
}
 
/*
ParentWidget類是TapBoxB的父類
他會得知盒子是否被點擊從而管理盒子的狀態(tài),通過setState更新展示內(nèi)容
 */
class ParentWidgetB extends StatefulWidget {
  @override
  _ParentWidgetBState createState() {
    return new _ParentWidgetBState();
  }
}
 
class _ParentWidgetBState extends State<ParentWidgetB> {
  bool _bActive = false;
 
  void _handleTapBoxBChanged(bool value) {
    setState(() {
      _bActive = value;
    });
  }
 
  @override
  Widget build(BuildContext context) {
    return new TapBoxB(
      bActive: _bActive,
      onChanged: _handleTapBoxBChanged,
    );
  }
}

最后是代碼整合,把上面兩個不同方式實現(xiàn)盒子點擊狀態(tài)更改的代碼在一個APP里展示出來

import 'package:flutter/material.dart';
 
void main() => runApp(new MyApp());
 
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'TapBox',
      theme: new ThemeData(primaryColor: Colors.white),
      home: new Scaffold(
        appBar: new AppBar(
          title: new Text('TapBox'),
        ),
        body: new Column(
          mainAxisAlignment: MainAxisAlignment.spaceEvenly,
          children: <Widget>[
            new TapBoxA(),
            new ParentWidgetB(),
          ],
        ),
      ),
    );
  }
}

運行后首頁顯示如下:


狀態(tài)管理實現(xiàn)1.png

點擊后效果如下(實現(xiàn)方式不同):


Screenshot_20180913-105838.png
最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容