Flutter開発実践 - ValueListenableBuilderで部分リフレッシュ機能を実装

Flutter開発実践 - ValueListenableBuilderで部分リフレッシュ機能を実装

作成された新しいプロジェクトでは、ボタンをクリックしてカウンターを更新した後、setState を通じてこのクラスのビルド メソッドを開始して更新できます。コントロールのごく一部のみを更新する必要がある場合、setState を使用するのは適切ではなく、プロバイダーなどの状態管理ライブラリを使用して部分的な更新が必要になります。もちろん、フラッターはローカル コントロールを更新するための ValueListenableBuilder を提供します。

一、ValueListenableBuilder

ValueListenableBuilderのプロパティは次のとおりです。

const ValueListenableBuilder({
    super.key,
    required this.valueListenable,
    required this.builder,
    this.child,
  }) : assert(valueListenable != null),
       assert(builder != null);
    
  • ValueListenable は Listenable を継承し、リッスン可能なオブジェクトです。
  • ビルダーは 1 つの typedef
    typedef ValueWidgetBuilder = Widget Function(BuildContext context, T value, Widget? child);
  • 子、オプション、空にすることもできます

ValueListenableBuilder クラスの実装を見ると、次のことがわかります。

class _ValueListenableBuilderState<T> extends State<ValueListenableBuilder<T>> {
  late T value;

  @override
  void initState() {
    super.initState();
    value = widget.valueListenable.value;
    widget.valueListenable.addListener(_valueChanged);
  }

  @override
  void didUpdateWidget(ValueListenableBuilder<T> oldWidget) {
    super.didUpdateWidget(oldWidget);
    if (oldWidget.valueListenable != widget.valueListenable) {
      oldWidget.valueListenable.removeListener(_valueChanged);
      value = widget.valueListenable.value;
      widget.valueListenable.addListener(_valueChanged);
    }
  }

  @override
  void dispose() {
    widget.valueListenable.removeListener(_valueChanged);
    super.dispose();
  }

  void _valueChanged() {
    setState(() { value = widget.valueListenable.value; });
  }

  @override
  Widget build(BuildContext context) {
    return widget.builder(context, value, widget.child);
  }
}
    

initState では、受信する listenable オブジェクトを監視し、_valueChanged メソッドを実行します。_valueChanged は setState を実行して、現在の状態の更新をトリガーします。 setState が build メソッドを実行し、build メソッドの実行をトリガーし、最後に widget.builder コールバックをトリガーすることで、部分的な更新が行われることがわかっています。

子の役割も非常に重要で、子の中にウィジェットを入れておきますが、ビルダーを実行する際には子が直接使用され、再度ビルドされることはありません。

2. ValueListenableBuilderによる部分リフレッシュの例

以下では、ValueListenableBuilder を使用して部分更新の例を実装しています。この例では、インターフェイスに、isShowNotifier の値の変更を制御するための表示ボタンと非表示ボタンがあります。 ValueListenableBuilder のビルダーを通じて表示する必要があるコンテンツを決定します。
サンプルコードは次のとおりです

import 'package:flutter/material.dart';

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

  @override
  State<ValueListenablePage> createState() => _ValueListenablePageState();
}

class _ValueListenablePageState extends State<ValueListenablePage> {
  final isShowNotifier = ValueNotifier<bool>(false);

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
  }

  void show() {
    isShowNotifier.value = true;
  }

  void hide() {
    isShowNotifier.value = false;
  }

  @override
  void dispose() {
    // TODO: implement dispose
    isShowNotifier.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    Size screenSize = MediaQuery.of(context).size;
    return Scaffold(
      appBar: AppBar(
        title: const Text('ValueListenablePage'),
      ),
      body: Container(
        width: screenSize.width,
        height: screenSize.height,
        child: Stack(
          alignment: Alignment.center,
          children: [
            Positioned(
              top: 50,
              child: buildValueListenable(context),
            ),
            Positioned(
              top: 200,
              child: buildButton(context),
            ),
          ],
        ),
      ),
    );
  }

  Widget buildHide(BuildContext context) {
    return Container(
      color: Colors.green,
      padding: EdgeInsets.symmetric(vertical: 20, horizontal: 50),
      child: Text(
        "当前隐藏",
        textAlign: TextAlign.center,
        overflow: TextOverflow.ellipsis,
        softWrap: true,
        style: TextStyle(
          fontSize: 16,
          fontWeight: FontWeight.w600,
          fontStyle: FontStyle.italic,
          color: Colors.white,
          decoration: TextDecoration.none,
        ),
      ),
    );
  }

  Widget buildValueListenable(BuildContext context) {
    return ValueListenableBuilder(
      valueListenable: isShowNotifier,
      builder: (BuildContext aContext, bool isShow, Widget? child) {
        if (isShow) {
          return child ?? buildHide(context);
        } else {
          return buildHide(context);
        }
      },
      child: Container(
        color: Colors.blueGrey,
        padding: EdgeInsets.symmetric(vertical: 50, horizontal: 50),
        child: Text(
          "ValueListenableBuilder Child",
          textAlign: TextAlign.center,
          overflow: TextOverflow.ellipsis,
          softWrap: true,
          style: TextStyle(
            fontSize: 16,
            fontWeight: FontWeight.w600,
            fontStyle: FontStyle.italic,
            color: Colors.white,
            decoration: TextDecoration.none,
          ),
        ),
      ),
    );
  }

  Widget buildButton(BuildContext context) {
    return Container(
      width: 300,
      height: 220,
      color: Colors.deepOrange,
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        crossAxisAlignment: CrossAxisAlignment.center,
        children: [
          TextButton(
            onPressed: () {
              show();
            },
            child: Container(
              height: 50,
              width: 200,
              color: Colors.lightBlue,
              alignment: Alignment.center,
              child: Text(
                '点击显示',
                style: TextStyle(
                  fontSize: 14,
                  color: Colors.white,
                ),
              ),
            ),
          ),
          TextButton(
            onPressed: () {
              hide();
            },
            child: Container(
              height: 50,
              width: 200,
              color: Colors.lightBlue,
              alignment: Alignment.center,
              child: Text(
                '点击隐藏',
                style: TextStyle(
                  fontSize: 14,
                  color: Colors.white,
                ),
              ),
            ),
          ),
        ],
      ),
    );
  }
}

    

レンダリングは次のとおりです

ここに画像の説明を挿入します

ここに画像の説明を挿入します

3. まとめ

Flutter開発実践 - ValueListenableBuilderで部分リフレッシュ機能を実装

勉強して記録し、日々改善を続けてください。

おすすめ

転載: blog.csdn.net/gloryFlow/article/details/134732970