为什么setState更改小部件类型?

时间:2020-01-23 19:40:19

标签: flutter

在有状态窗口小部件中调用setState会将窗口小部件的类型更改为父级的类型。为什么会发生这种情况,有什么方法可以防止这种情况发生?

在提供的示例中,更改Slider值将调用setState来重建小部件。通过覆盖didUpdateWidget,可以看到没有任何反应,并且该小部件仍然是同一小部件​​。但是,覆盖==表明Slider Widget类型从Container更改为Slider。

输出: Runtime Type Old: Container New: SliderWidget

预期输出: Runtime Type Old: SliderWidget New: SliderWidget

为什么会这样?

截屏: Widget Type Changed

代码:

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key}) : super(key: key);

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.center,
          children: <Widget>[
            Text("Text Widget"),
            SliderWidget(),
          ],
        ),
      ),
    );
  }
}

class SliderWidget extends StatefulWidget {
  SliderWidget({Key key}) : super(key: key);

  @override
  _SliderWidgetState createState() => _SliderWidgetState();

  @override
  bool operator ==(other) {
    print("RuntimeType Old: ${other.runtimeType} New: $runtimeType");
    return this.runtimeType == other.runtimeType;
  }

  @override
  int get hashCode => runtimeType.hashCode;
}

class _SliderWidgetState extends State<SliderWidget> {
  int value = 10;

  @override
  void didUpdateWidget(SliderWidget oldWidget) {
    super.didUpdateWidget(oldWidget);
    print("didUpdateWidget");
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      child: SliderTheme(
        data: SliderThemeData(
          showValueIndicator: ShowValueIndicator.always,
        ),
        child: Slider(
          value: value.toDouble(),
          min: 0,
          max: 100,
          label: value.toString(),
          onChanged: (double value) {
            setState(() {
              this.value = value.toInt();
            });
          },
        ),
      ),
    );
  }
}

演示:

https://dartpad.dev/5bae524391974eb12efa825a7db4e674

0 个答案:

没有答案