自定义小部件 Flutter - 从小部件外部查看变量

问题描述 投票:0回答:1

我正在尝试使用下面的代码创建一个自定义小部件,但还没有找到一种方法来做到这一点,以便在调用 setState 函数后屏幕上显示的文本发生变化。它只是保持初始值。我还尝试在变量更改后从类外部查看变量,但也无法查看。

我尝试将容器封装在名为 CustomDatePicker 的小部件中,设置类的构造函数来初始化变量,但这并没有起作用,因为我无法在主文件中调用小部件的位置查看变量.

Color darkBlueCustom = const Color(0xFF003366);
Color lightBlueCustom = const Color(0xFFadd8e6);
List months = [
    "January",
    "February",
    "March",
    "April",
    "May",
    "June",
    "July",
    "August",
    "September",
    "October",
    "November",
    "December",
  ];


Container(
      padding: const EdgeInsets.all(10),
      child: Column(
        children: [
          Container(
            padding: const EdgeInsets.only(left: 10),
            height: 45,
            color: darkBlueCustom,
            child: Align(
              alignment: Alignment.centerLeft,
              child: CupertinoButton(
                padding: EdgeInsets.zero,
                // Display a CupertinoPicker with list of months.
                onPressed: () {
                  setState(() {
                    clickedMonth = true;
                    _showDialog(
                      CupertinoPicker(
                        magnification: 1.22,
                        squeeze: 1.2,
                        useMagnifier: true,
                        itemExtent: 32.0,
                        // This sets the initial item.
                        scrollController: FixedExtentScrollController(
                          initialItem: selectedMonth,
                        ),
                        // This is called when selected item is changed.
                        onSelectedItemChanged: (int selectedItem) {
                          setState(() {
                            selectedMonth = selectedItem;
                          });
                        },
                        children:
                            List<Widget>.generate(months.length, (int index) {
                          return Center(child: Text(months[index]));
                        }),
                      ),
                    );
                  });
                },
                // This displays the selected Month name.
                child: Text(
                  months[selectedMonth],
                  style: GoogleFonts.ubuntu(
                    textStyle: TextStyle(
                      fontSize: 18,
                      fontWeight: FontWeight.bold,
                      color: clickedMonth ? Colors.white : Colors.white38,
                    ),
                  ),
                ),
              ),
            ),
          ),
          Text(
            "$title,$selectedMonth,$clickedMonth",
          ),
        ],
      ),
    )

我尝试过像这样制作小部件:

import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'package:google_fonts/google_fonts.dart';

Color darkBlueCustom = const Color(0xFF003366);
Color lightBlueCustom = const Color(0xFFadd8e6);


class CustomDatePicker extends StatefulWidget {
  final String title;
  final int selectedMonth;
  final bool clickedMonth;

  const CustomDatePicker({
    super.key,
    required this.title,
    required this.selectedMonth,
    required this.clickedMonth,
  });

  @override
  State<CustomDatePicker> createState() => _CustomDatePickerState();
}

class _CustomDatePickerState extends State<CustomDatePicker> {
  List months = [
    "January",
    "February",
    "March",
    "April",
    "May",
    "June",
    "July",
    "August",
    "September",
    "October",
    "November",
    "December",
  ];

  void _showDialog(Widget child) {
    showCupertinoModalPopup<void>(
      context: context,
      builder: (BuildContext context) => Container(
        height: 216,
        padding: const EdgeInsets.only(top: 6.0),
        // The Bottom margin is provided to align the popup above the system navigation bar.
        margin: EdgeInsets.only(
          bottom: MediaQuery.of(context).viewInsets.bottom,
        ),
        // Provide a background color for the popup.
        color: CupertinoColors.systemBackground.resolveFrom(context),
        // Use a SafeArea widget to avoid system overlaps.
        child: SafeArea(
          top: false,
          child: child,
        ),
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    String title = widget.title;
    int selectedMonth = widget.selectedMonth;
    bool clickedMonth = widget.clickedMonth;
    return Container(
      padding: const EdgeInsets.all(10),
      child: Column(
        children: [
          Container(
            padding: const EdgeInsets.only(left: 10),
            height: 45,
            color: darkBlueCustom,
            child: Align(
              alignment: Alignment.centerLeft,
              child: CupertinoButton(
                padding: EdgeInsets.zero,
                // Display a CupertinoPicker with list of months.
                onPressed: () {
                  setState(() {
                    clickedMonth = true;
                    _showDialog(
                      CupertinoPicker(
                        magnification: 1.22,
                        squeeze: 1.2,
                        useMagnifier: true,
                        itemExtent: 32.0,
                        // This sets the initial item.
                        scrollController: FixedExtentScrollController(
                          initialItem: selectedMonth,
                        ),
                        // This is called when selected item is changed.
                        onSelectedItemChanged: (int selectedItem) {
                          setState(() {
                            selectedMonth = selectedItem;
                          });
                        },
                        children:
                            List<Widget>.generate(months.length, (int index) {
                          return Center(child: Text(months[index]));
                        }),
                      ),
                    );
                  });
                },
                // This displays the selected month name.
                child: Text(
                  months[selectedMonth],
                  style: GoogleFonts.ubuntu(
                    textStyle: TextStyle(
                      fontSize: 18,
                      fontWeight: FontWeight.bold,
                      color: clickedMonth ? Colors.white : Colors.white38,
                    ),
                  ),
                ),
              ),
            ),
          ),
          Text(
            "$title,$selectedMonth,$clickedMonth",
          ),
        ],
      ),
    );
  }
}
flutter dart widget
1个回答
0
投票

参数

selectedMonth
传递给
CustomDatePicker
的构造函数 只能用于设置初始选择。为了避免混淆,它应该被命名为例如
preSelectedMonth
initiallySelectedMonth

您的小部件的状态应存储在

_CustomDatePickerState
中,例如 在一个名为
selectedMonth
的变量中:

import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'package:google_fonts/google_fonts.dart';

Color darkBlueCustom = const Color(0xFF003366);
Color lightBlueCustom = const Color(0xFFadd8e6);


class CustomDatePicker extends StatefulWidget {
  final String title;
  final int preSelectedMonth;
  final bool clickedMonth;  // Can be removed. 

  const CustomDatePicker({
    super.key,
    required this.title,
    required this.preSelectedMonth,
    required this.clickedMonth,  // Can be removed. 
  });

  @override
  State<CustomDatePicker> createState() => _CustomDatePickerState();
}

class _CustomDatePickerState extends State<CustomDatePicker> {
  final List months = [
    "Select a month",  // <--- Added entry to make selection easier. 
    "January",         // Otherwise, January -> 0 and December -> 11
    "February",
    "March",
    "April",
    "May",
    "June",
    "July",
    "August",
    "September",
    "October",
    "November",
    "December",
  ];
  
  int selectedMonth = 0;
  bool clickedMonth = false; 
  
  @override
  void initState() {
    selectedMonth = widget.preSelectedMonth; // Initialize the widget state
    super.initState();
  }

  void _showDialog(Widget child) {
    showCupertinoModalPopup<void>(
      context: context,
      builder: (BuildContext context) => Container(
        height: 216,
        padding: const EdgeInsets.only(top: 6.0),
        // The Bottom margin is provided to align the popup above the system navigation bar.
        margin: EdgeInsets.only(
          bottom: MediaQuery.of(context).viewInsets.bottom,
        ),
        // Provide a background color for the popup.
        color: CupertinoColors.systemBackground.resolveFrom(context),
        // Use a SafeArea widget to avoid system overlaps.
        child: SafeArea(
          top: false,
          child: child,
        ),
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    String title = widget.title;
    return Container(
      padding: const EdgeInsets.all(10),
      child: Column(
        children: [
          Container(
            padding: const EdgeInsets.only(left: 10),
            height: 45,
            color: darkBlueCustom,
            child: Align(
              alignment: Alignment.centerLeft,
              child: CupertinoButton(
                padding: EdgeInsets.zero,
                // Display a CupertinoPicker with list of months.
                onPressed: () {
                  setState(() {
                    clickedMonth = true;
                    _showDialog(
                      CupertinoPicker(
                        magnification: 1.22,
                        squeeze: 1.2,
                        useMagnifier: true,
                        itemExtent: 32.0,
                        // This sets the initial item.
                        scrollController: FixedExtentScrollController(
                          initialItem: selectedMonth,
                        ),
                        // This is called when selected item is changed.
                        onSelectedItemChanged: (int selectedItem) {
                          setState(() {
                            selectedMonth = selectedItem;
                            // Store selectedMonth
                          });
                        },
                        children:
                            List<Widget>.generate(months.length, (int index) {
                          return Center(child: Text(months[index]));
                        }),
                      ),
                    );
                  });
                },
                // This displays the selected month name.
                child: Text(
                  months[selectedMonth],
                  style: GoogleFonts.ubuntu(
                    textStyle: TextStyle(
                      fontSize: 18,
                      fontWeight: FontWeight.bold,
                      color: clickedMonth ? Colors.white : Colors.white38,
                    ),
                  ),
                ),
              ),
            ),
          ),
          Text(
            "$title,$selectedMonth,$clickedMonth",
          ),
        ],
      ),
    );
  }
}

要从小部件外部访问选定的月份,您需要存储该变量。有关更多详细信息,我建议阅读应用程序状态管理。提供的信息包括状态管理方法列表。就我个人而言,我推荐

riverpod

© www.soinside.com 2019 - 2024. All rights reserved.