ios 如何在他的主类Flutter上使用可重用的SwitchListTile数据

rn0zuynd  于 11个月前  发布在  iOS
关注(0)|答案(1)|浏览(129)

我已经创建了可重用的SwitchListTile,每当我想使用任何东西时,我都会简单地调用它们。例如,我有一个像这样的自定义SwitchListTile:

import 'package:flutter/material.dart';

class FitterItem extends StatefulWidget {
  FitterItem(
      {super.key,
      required this.fitterValue,
      required this.fitterTittle,
      required this.fitterSubTit,
      required this.onChange});

  bool fitterValue;
  final String fitterTittle;
  final String fitterSubTit;
  final void Function(bool newValue) onChange;

  @override
  State<StatefulWidget> createState() {
    // TODO: implement createState
    return _FitterItemState();
  }
}

class _FitterItemState extends State<FitterItem> {
  @override
  Widget build(context) {
    // TODO: implement build
    return SwitchListTile(
      value: widget.fitterValue,
      onChanged: (newValue) {
        setState(() {
          widget.fitterValue = newValue;
        });
      },
      title: Text(
        widget.fitterTittle,
        style: Theme.of(context)
            .textTheme
            .titleLarge!
            .copyWith(color: Theme.of(context).colorScheme.primaryContainer),
      ),
      subtitle: Text(
        widget.fitterSubTit,
        style: Theme.of(context)
            .textTheme
            .labelLarge!
            .copyWith(color: Theme.of(context).colorScheme.primary),
      ),
    );
  }
}

字符串
我有一个像下面这样的父类:

import 'package:flutter/material.dart';
import 'package:meals/widgets/fitter_item.dart';

enum Fitter {
  GlutenFree,
  LactoseFree,
  Vegan,
  Vegetarian,
}

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

  @override
  State<StatefulWidget> createState() {
    // TODO: implement createState
    return _FitterScreenState();
  }
}

class _FitterScreenState extends State<FitterScreen> {
  @override
  Widget build(context) {
    var _glutenFitter = false;
    var _lactoseFitter = false;
    var _vegeterianFitter = false;
    var _veganFitter = false;

    // TODO: implement build
    return Scaffold(
      appBar: AppBar(
        title: const Text("Fitter"),
      ),
      body: WillPopScope(
        onWillPop: () async {
          Navigator.of(context).pop({
            Fitter.GlutenFree: _glutenFitter,
            Fitter.LactoseFree: _lactoseFitter,
            Fitter.Vegan: _veganFitter,
            Fitter.Vegetarian: _vegeterianFitter,
          });
          return false;
        },
        child: Column(
          children: [
            FitterItem(
                fitterValue: _glutenFitter,
                onChange: (bool newValue) {
                  setState(() {
                    _glutenFitter = newValue;
                  });
                },
                fitterTittle: "Gluten free",
                fitterSubTit: "Only include Gluten free meals"),
            const SizedBox(
              height: 5,
            ),
            FitterItem(
                fitterValue: _lactoseFitter,
                onChange: (newValue) {
                  setState(() {
                    _lactoseFitter = newValue;
                  });
                },
                fitterTittle: "Lactose free",
                fitterSubTit: "Only include Lactose free meals"),
            const SizedBox(
              height: 5,
            ),
            FitterItem(
                fitterValue: _veganFitter,
                onChange: (newValue) {
                  setState(() {
                    _veganFitter = newValue;
                  });
                },
                fitterTittle: "Vegan free",
                fitterSubTit: "Only include Vegan free meals"),
            const SizedBox(
              height: 5,
            ),
            FitterItem(
                fitterValue: _vegeterianFitter,
                onChange: (newValue) {
                  setState(() {
                    _vegeterianFitter = newValue;
                  });
                },
                fitterTittle: "Vegeterian free",
                fitterSubTit: "Only include Vegeterian free meals"),
          ],
        ),
      ),
    );
  }
}


但是我不能在Parent类上使用Updated值。它将Intilze值作为false。自定义SwitchListTile很好地改变了他的状态。

WillPopScope(
        onWillPop: () async {
          Navigator.of(context).pop({
            Fitter.GlutenFree: _glutenFitter,
            Fitter.LactoseFree: _lactoseFitter,
            Fitter.Vegan: _veganFitter,
            Fitter.Vegetarian: _vegeterianFitter,
          });
          return false;
        },

gajydyqb

gajydyqb1#

问题是在子FitterItem小部件的状态中设置值,以及使var低于FitterScreenbuild方法,这在每次构建时将它们设置为false。

  1. FitterItem可以是StatelessWidget
  2. SwitchListTileonChanged方法应该接受从父代传递的函数,因此它可以在父代中运行该函数。
// this
onChanged: (newValue) {
   setState(() {
     widget.fitterValue = newValue;
   });
 },
// should be
onChanged: onChange,

字符串
1.将FitterScreen中的变数移至建置方法上方。

var _glutenFitter = false;
var _lactoseFitter = false;
var _vegeterianFitter = false;
var _veganFitter = false;

@override
Widget build(context) {
// ...

完整代码

// start enum
enum Fitter {
  GlutenFree,
  LactoseFree,
  Vegan,
  Vegetarian,
}
/// end enum

// start FitterItem
class FitterItem extends StatelessWidget {
  const FitterItem({
    super.key,
    required this.fitterValue,
    required this.fitterTittle,
    required this.fitterSubTit,
    required this.onChange,
  });

  final bool fitterValue;
  final String fitterTittle;
  final String fitterSubTit;
  final void Function(bool newValue) onChange;

  @override
  Widget build(context) {
    return SwitchListTile(
      value: fitterValue,
      onChanged: onChange,
      title: Text(
        fitterTittle,
        style: Theme.of(context)
            .textTheme
            .titleLarge!
            .copyWith(color: Theme.of(context).colorScheme.primaryContainer),
      ),
      subtitle: Text(
        fitterSubTit,
        style: Theme.of(context)
            .textTheme
            .labelLarge!
            .copyWith(color: Theme.of(context).colorScheme.primary),
      ),
    );
  }
}
/// end FitterItem

// start FitterScreen
class FitterScreen extends StatefulWidget {
  const FitterScreen({super.key});

  @override
  State<StatefulWidget> createState() => _FitterScreenState();
}

class _FitterScreenState extends State<FitterScreen> {
  var _glutenFitter = false;
  var _lactoseFitter = false;
  var _vegeterianFitter = false;
  var _veganFitter = false;
  @override
  Widget build(context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("Fitter"),
      ),
      body: WillPopScope(
        onWillPop: () async {
          Navigator.of(context).pop({
            Fitter.GlutenFree: _glutenFitter,
            Fitter.LactoseFree: _lactoseFitter,
            Fitter.Vegan: _veganFitter,
            Fitter.Vegetarian: _vegeterianFitter,
          });
          return false;
        },
        child: Column(
          children: [
            ElevatedButton(
                onPressed: () {
                  Navigator.of(context).pop();
                },
                child: const Text('pop')),
            FitterItem(
                fitterValue: _glutenFitter,
                onChange: (bool newValue) {
                  setState(() {
                    _glutenFitter = newValue;
                  });
                },
                fitterTittle: "Gluten free",
                fitterSubTit: "Only include Gluten free meals"),
            const SizedBox(
              height: 5,
            ),
            FitterItem(
                fitterValue: _lactoseFitter,
                onChange: (newValue) {
                  setState(() {
                    _lactoseFitter = newValue;
                  });
                },
                fitterTittle: "Lactose free",
                fitterSubTit: "Only include Lactose free meals"),
            const SizedBox(
              height: 5,
            ),
            FitterItem(
                fitterValue: _veganFitter,
                onChange: (newValue) {
                  setState(() {
                    _veganFitter = newValue;
                  });
                },
                fitterTittle: "Vegan free",
                fitterSubTit: "Only include Vegan free meals"),
            const SizedBox(
              height: 5,
            ),
            FitterItem(
                fitterValue: _vegeterianFitter,
                onChange: (newValue) {
                  setState(() {
                    _vegeterianFitter = newValue;
                  });
                },
                fitterTittle: "Vegeterian free",
                fitterSubTit: "Only include Vegeterian free meals"),
          ],
        ),
      ),
    );
  }
}
/// end FitterScreen

相关问题