Flutter,通过选择轮选择 int 和 double 值并将它们从一页解析到另一页

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

我正在尝试使用选择轮小部件在一个页面上选择高度(int)和重量(double)值,然后将其发送到另一页面以显示并最终在计算中使用这些值。

我尝试通过构造函数解析变量,但无论如何它们都停留在 0 或 0.0。我不确定问题是否来自选择轮没有保存我的选择,或者解析在某个时刻将值设置为 0

以下是涉及的不同页面,它们被分隔在多个.dart文件中:

main.dart:

import 'package:appli_teeshirt/pages/profile.dart';
import 'package:appli_teeshirt/pages/bt_connect.dart';
import 'package:appli_teeshirt/pages/historique.dart';
import 'package:appli_teeshirt/pages/page_accueil.dart';
import 'package:flutter/material.dart';

final GlobalKey<_MyappState> myAppKey = GlobalKey<_MyappState>();

void main() {
  runApp(Myapp(key: myAppKey));
}

class Myapp extends StatefulWidget {
  const Myapp({Key? key}) : super(key: key);

  @override
  State<Myapp> createState() => _MyappState();
}

class _MyappState extends State<Myapp> {
  int _currentIndex = 0;
  double _poids = 0.0;
  int _taille = 0;

  void setCurrentIndex(int index) {
    setState(() {
      _currentIndex = index;
    });
  }

  void setPoidsAndTaille(double poids, int taille) {
    setState(() {
      _poids = poids;
      _taille = taille;
    });
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: [
            const Text("Accueil"),
            const Text("Connection Bluetooth"),
            const Text("Historique des courses"),
            const Text("Profile Utilisateur"),
          ][_currentIndex],
        ),
        body: IndexedStack(
          index: _currentIndex,
          children: [
            const PageAccueil(),
            const BTconnect(),
            historique(poids: _poids, taille: _taille),
            UserProfile(
              onSubmit: (index) {
                setCurrentIndex(index);
              },
              onPoidsTailleChange: (poids, taille) {
                setPoidsAndTaille(poids, taille);
              },
            ),
          ],
        ),
        bottomNavigationBar: BottomNavigationBar(
          currentIndex: _currentIndex,
          onTap: setCurrentIndex,
          type: BottomNavigationBarType.fixed,
          selectedItemColor: Colors.deepPurple,
          unselectedItemColor: Colors.grey,
          iconSize: 32,
          elevation: 10,
          items: const [
            BottomNavigationBarItem(
                icon: Icon(Icons.home),
                label: 'Accueil'
            ),
            BottomNavigationBarItem(
                icon: Icon(Icons.bluetooth),
                label: 'Connection BT'
            ),
            BottomNavigationBarItem(
                icon: Icon(Icons.history),
                label: 'Historique'
            ),
            BottomNavigationBarItem(
                icon: Icon(Icons.account_circle),
                label: 'profile'
            )
          ],
        ),
      ),
    );
  }
}

profile.dart(我在其中选择值):

import 'package:flutter/material.dart';
import 'package:selector_wheel/selector_wheel.dart';
import 'package:appli_teeshirt/main.dart';

class UserProfile extends StatefulWidget {
  final void Function(int) onSubmit;
  final void Function(double, int) onPoidsTailleChange;

  const UserProfile({
    Key? key,
    required this.onSubmit,
    required this.onPoidsTailleChange,
  }) : super(key: key);

  @override
  State<UserProfile> createState() => _UserProfileState();
}



class _UserProfileState extends State<UserProfile> {

  final _formKey = GlobalKey<FormState>();

  final profilNameController = TextEditingController();
  final tailleController = TextEditingController();

  @override
  void dispose() {
    super.dispose();

    profilNameController.dispose();
    tailleController.dispose();
  }
  @override
  Widget build(BuildContext context) {
    double selectedPoids = 0.0;
    int selectedTaille = 0;
    return Container(
      margin: const EdgeInsets.all(20),
      child: Form(
        key: _formKey,
          child: Column(
            children: [
              Container(
                margin: const EdgeInsets.only(bottom: 10),
                child: TextFormField(
                  decoration: const InputDecoration(
                    labelText: "nom du profil",
                    hintText: "entre ton nom",
                    border: OutlineInputBorder(),
                  ),
                  validator: (value){
                    if (value == null || value.isEmpty){
                      return "Tu dois completer ce texte";
                    }
                    return null;
                  },
                ),
              ),

              Row(
                mainAxisSize: MainAxisSize.min,
              children: [
                Column(
                  children: [
              const Text('Poids'),
              SizedBox(
                width: 100,
                height: 200,
                child: SelectorWheel(
                  childCount: 241,
                  diameterRatio: 3.5,
                  convertIndexToValue: (int index) {
                    // This is just to illustrate, that the index can be converted
                    // to any value. In this case, we are converting the index to
                    // a quarter of a pound.
                    final quarter = (index +60) / 2;

                    return SelectorWheelValue(
                      // The label is what is displayed on the selector wheel
                      label: '${quarter.toString()} kg',
                      value: quarter,
                      index: index,
                    );
                  },
                  onValueChanged: (SelectorWheelValue<double> value) {
                    // print the value that was selected
                    setState(() {
                      selectedPoids = value.value;
                    });
                      },
                    ),
                  ),
                ],
              ),
                Column(
                  children: [
                    const Text('Taille'),
                    SizedBox(
                      width: 100,
                      height: 200,
                      child: SelectorWheel(
                        childCount: 121,
                        diameterRatio: 3.5,
                        convertIndexToValue: (int index) {
                          final height = index + 130;
                         // final quarter = (index +130) /1;

                          return SelectorWheelValue(
                            // The label is what is displayed on the selector wheel
                            label: '${height.toString()} cm',
                            value: height,
                            index: index,
                          );
                        },
                        onValueChanged: (SelectorWheelValue<int> value) {
                          // print the value that was selected
                          setState(() {
                            selectedTaille = value.value;
                          });
                        },
                      ),
                    ),
                  ],
                ),
              ],
              ),
              SizedBox(
                width: double.infinity,
                height: 50,
                child: ElevatedButton(
                  onPressed: () {
                    if (_formKey.currentState!.validate()) {
                      ScaffoldMessenger.of(context).showSnackBar(
                        const SnackBar(content: Text("envoi en cours...")),
                      );
                      FocusScope.of(context).requestFocus(FocusNode());

                      // Get the selected "Poids" and "Taille" values
                      double poids = selectedPoids;
                      int taille = selectedTaille;

                      // Call the onSubmit callback with the desired index
                      widget.onSubmit(3);
                    }
                  },
                  child: const Text("Envoyer"),
                ),


              ),
            ],
          )
      ),
    );
  }
}

historique.dart(我想在其中显示值,特别是我想在DetailsScreen中显示它们

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

class historique extends StatelessWidget {
  final double poids;
  final int taille;
  final List<Map<String, dynamic>> courses = [
    {
      "name": "Course 1",
      "date": "20/03/2024",
      //"logo": "course1",
      "distance": 12967,
      "temps": 7384
    },
    {
      "name": "Course 2",
      "date": "06/03/2024",
      // "logo": "course2",
      "distance": 17413,
      "temps": 13854
    },
    {
      "name": "Course 3",
      "date": "27/02/2024",
      //   "logo": "course3",
      "distance": 4967,
      "temps": 3891
    },
  ];

  historique({required this.poids, required this.taille, Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    // Your build method remains the same
    return Scaffold(

        body: Column(
          children: [
            Expanded(
                child:
                ListView.builder(
                  itemCount: courses.length,
                  itemBuilder: (context, index) {
                    final course = courses[index];
                    final logo = course['logo'];
                    final name = course['name'];
                    final date = course['date'];

                    return InkWell(
                      onTap: () => Navigator.of(context).push(
                        MaterialPageRoute(
                            builder: (context) => DetailsScreen(
                              poids: poids,
                              taille: taille,

                            ),
                            settings: RouteSettings(
                                arguments: course
                            )
                        ),

                      ),
                      child: Card(
                        child: ListTile(
                          leading: Image.asset("assets/images/course2.png"),
                          title: Text(name),
                          subtitle: Text('course du $date'),
                          trailing: const Icon(Icons.more_vert),
                        ),
                      ),
                    );
                  },
                )
            ),
          ],
        )
    );
  }
}

class DetailsScreen extends StatelessWidget {

  final double poids;
  final int taille;

  const DetailsScreen({Key? key, required this.poids, required this.taille}) : super(key: key);

  @override
  Widget build(BuildContext context) {

    var course = ModalRoute.of(context)!.settings.arguments  as Map<String,dynamic>;

    int hours = course['temps'] ~/ 3600;
    int minutes = (course['temps'] ~/ 60) % 60;
    int seconds = course['temps'] % 60;


    return Scaffold(
      appBar: AppBar(
        title:
           Text("${course['name']}"),
      ),
      body: SafeArea(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,

          children: [
            UnconstrainedBox(

              child: Card(
                color: Colors.lightBlueAccent,
                  child:
                  Text(
                    " date : ${course['date']} ",
                    style: const TextStyle(
                        fontSize: 24,
                        //fontFamily: 'Poppins'
                    ),
                  ),
              ),
            ),
            const SizedBox(
              height: 15,
              width: 100,
            ),
            UnconstrainedBox(
              child: Card(
                color: Colors.lightBlueAccent,
                child:
                Text(
                  " distance : ${course['distance']}m \n  temps : $hours:$minutes'$seconds ",
                  style: const TextStyle(
                      fontSize: 24,
                     //  fontFamily: 'Poppins'
                  ),
                ) ,
              ),
            ),
            const SizedBox(
              height: 15,
              width: 100,
            ),
            UnconstrainedBox(
              child: Card(
                color: Colors.lightBlueAccent,
                child:
                Text(
                  " taille : $taille \n  temps : $poids ",
                  style: const TextStyle(
                    fontSize: 24,
                    //  fontFamily: 'Poppins'
                  ),
                ) ,
              ),
            ),
              ],
        ),
      ),
    );
  }
}

flutter
1个回答
0
投票

问题是你的变量(

selectedPoids
selectedTaille
)是在你的build方法中声明的:

@override
Widget build(BuildContext context) {
double selectedPoids = 0.0; // within the build method -- not the class
int selectedTaille = 0;
...

这意味着,每次您的

build
方法重新触发时,它都会重新评估变量。

因此,当您稍后调用

setState
并触发重建时:

 onValueChanged: (SelectorWheelValue<double> value) {
    setState(() {
    selectedPoids = value.value;
});

回到步骤 1。

要解决此问题,请在

State
类中声明变量:

class _UserProfileState extends State<UserProfile> {
  final _formKey = GlobalKey<FormState>();
  double selectedPoids = 0.0; // declare them within the state
  int selectedTaille = 0;
  final profilNameController = TextEditingController();
  final tailleController = TextEditingController();
© www.soinside.com 2019 - 2024. All rights reserved.