简体   繁体   English

如何将单选按钮值获取到 int 并在 flutter 中计算

[英]How to get radio button value to int and calculate in flutter

这是这个练习的输出 I just started to learn Flutter/Dart as my lecturer ask me to do some simple mobile app of e-ticket where the user need to choose from the radio button the movie that have value price for each radio button.我刚开始学习 Flutter/Dart,因为我的讲师让我做一些简单的电子票移动应用程序,用户需要从单选按钮中选择每个单选按钮都有价值的电影。 Then the user need to input quantity value then click the submit button where the result of calculation need to be shown in another result page.然后用户需要输入数量值,然后单击提交按钮,计算结果需要显示在另一个结果页面中。 Below is the picture of the assignment and some code that i have done.下面是作业的图片和我完成的一些代码。 But i got stuck in the calculation part where i did not find any solution to this.但是我陷入了计算部分,我没有找到任何解决方案。 hope anyone can help me with this.希望任何人都可以帮助我。

main dart main dart主要 dart主要 dart

import 'package:flutter/material.dart';
import 'result.dart';
import 'customer.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}
enum SingingCharacter { avengers, batman, kimetsu }

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key, required this.title}) : super(key: key);
  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {

  final txtName= TextEditingController();
  final txtEmail = TextEditingController();
  final txtQuantity = TextEditingController();
  SingingCharacter? _character = SingingCharacter.avengers;

  void _gotoResultScreen(){

    Customer c= Customer(txtName.text, txtEmail.text, int.parse(txtQuantity.text));

    Navigator.push(
      context,
      MaterialPageRoute(
          builder: (context) => ResultPage(
            title:"Result Screen",
            content:"Congratulation! You've reached this page",
            customer: c,)
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(

        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text('Name'),
            TextField(
              controller: txtName,
            ),
            Text('Email'),
            TextField(
              controller: txtEmail,
            ),

            Text('Choose a movie:'),
            ListTile(
              title: const Text('AVENGERS(RM20)'),
              leading: Radio<SingingCharacter>(
                value: SingingCharacter.avengers,
                groupValue: _character,
                onChanged: (SingingCharacter? value) {
                  setState(() {
                    _character = value;
                  });
                },
              ),
            ),
            ListTile(
              title: const Text('BATMAN(RM10)'),
              leading: Radio<SingingCharacter>(
                  value: SingingCharacter.batman,
                  groupValue: _character,
                  onChanged: (SingingCharacter? value) {
                    setState(() {
                      _character = value;
                    });
                  }
              ),
            ),

            ListTile(
              title: const Text('KIMETSU NO YAIBA(RM12)'),
              leading: Radio<SingingCharacter>(
                  value: SingingCharacter.kimetsu,
                  groupValue: _character,
                  onChanged: (SingingCharacter? value) {
                    setState(() {
                      _character = value;
                    });
                  }
              ),
            ),

            Text('quantity'),
            TextField(
              controller: txtQuantity,
            ),

            RaisedButton(
              onPressed:_gotoResultScreen,
              //do something
              child: new Text('Calculate'),
            ),
          ],
        ),
      ),
    );
  }
}

result.dart结果.dart

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

class ResultPage extends StatefulWidget {
  const ResultPage({Key? key, required this.title, required this.content, required this.customer}) : super(key: key);

  final String title;
  final String content;
  final Customer customer;

  @override
  State<ResultPage> createState() => _ResultPageState();
}

class _ResultPageState extends State<ResultPage> {

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(widget.content,),
            Text("Name:" + widget.customer.name),
            Text("Email: " + widget.customer.email),
            Text("Quantity:" + widget.customer.quantity.toString()),
          ],
        ),
      ),
    );
  }
}

customer.dart客户.dart

  class Customer {
  final String name;
  final String email;
  final int quantity;



  const Customer(this.name, this.email, this.quantity);
}

You can use Map<String, int> to store the movie name and its price.您可以使用Map<String, int>来存储电影名称及其价格。 Then create the List<Map<String, int>> and use the .map() function on this list to covert the list into listTile .然后创建List<Map<String, int>>并在此列表上使用.map() function 将列表转换为listTile

You should pass necessary arguments to result page.您应该将必要的 arguments 传递到结果页面。 You passed Customer, that is ok.你通过了客户,没关系。 But movie info is missing.但是缺少电影信息。 For example:例如:

Navigator.push(
  context,
  MaterialPageRoute(
      builder: (context) => ResultPage(
        title:"Result Screen",
        content:"Congratulation! You've reached this page",
        customer: c,
        movieName: ...,
        price: ...,
      )
  ),
);

And of course you should edit Result page accordingly.当然,您应该相应地编辑结果页面。

After go to result page. go后到结果页。 Use price data and multiply quantity.使用价格数据并乘以数量。 This is gonna be final price.这将是最终价格。

However, this is not a good approach, Instead of using this kind of solutions, I recommend create a Movie class like Customer.但是,这不是一个好方法,我建议不要使用这种解决方案,而是创建一个像客户这样的电影 class。 Also quantity info should not be a field of Customer, it should be field of Movie class.另外 quantity info 不应该是 Customer 的字段,它应该是 Movie class 的字段。

You can calculate the price like this.您可以这样计算价格。

Let's say your _character value is SingingCharacter.avengers假设您的 _character 值为 SingingCharacter.avengers

int price = getPriceFromCharacter(_character) * int.parse(txtQuantity.text);

getPriceFromCharacter(SingingCharacter? character) {
 switch(character) { 
   case SingingCharacter.avengers: { 
     return 20;
   } 
   case SingingCharacter.batman: { 
     return 10;
   } 
   case SingingCharacter.kimetsu: { 
     return 12;
   } 
  } 
}
void _gotoResultScreen(){
  int price = getPriceFromCharacter(_character) * int.parse(txtQuantity.text);
  Customer c= Customer(txtName.text, txtEmail.text, int.parse(txtQuantity.text));

  Navigator.push(
   context,
  MaterialPageRoute(
      builder: (context) => ResultPage(
        title:"Result Screen",
        content:"Congratulation! You've reached this page",
        customer: c,)
  ),
);

} }

This is the answer to the solution above.这是上述解决方案的答案。 main.dart主要.dart

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

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(title: 'eTicket'),
    );
  }
}

enum ticketName {Avengers,Batman,Kimetsu}

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key, required this.title}) : super(key: key);

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {

  final TextEditingController _name = new TextEditingController();
  final TextEditingController _email = new TextEditingController();
  final TextEditingController _quantity = new TextEditingController();

  final formKey = GlobalKey<FormState>();
  String name = "";
  String email =  "";
  String quantity = "";
  String movieName = "";
  String ticketPrice = "";


  ticketName? _movieName = ticketName.Avengers;


  @override
  Widget build(BuildContext context) {

    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Form(
          key: formKey,
          child: Padding(
            padding: const EdgeInsets.symmetric (
              horizontal: 20,),
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,

              children: <Widget>[
                const Text('Name',textAlign: TextAlign.left),

                const Padding (
                  padding: EdgeInsets.symmetric(vertical: 5.0),
                ),

                TextFormField(
                  validator: (value) {
                    if(value!.isEmpty ){
                      return 'Please Enter Your Name';
                    }
                  },
                  onSaved: (value){
                    name = value!;
                  },
                  controller: _name,
                  decoration: InputDecoration(
                      hintText: '',
                      filled: true,
                      fillColor: Colors.black.withOpacity (0.2),
                      border: OutlineInputBorder(
                          borderSide: BorderSide.none,
                          borderRadius: BorderRadius.circular (10))),
                ),
                const SizedBox(
                  height: 5,
                ),

                const Padding (
                  padding: EdgeInsets.symmetric(vertical: 5.0),
                ),

                const Text('Email',textAlign: TextAlign.left),

                const Padding (
                  padding: EdgeInsets.symmetric(vertical: 5.0),
                ),

                TextFormField(
                  validator: (value) {
                    if(value!.isEmpty || !value.contains('@') || !value.contains('.com'))
                    {
                      return 'Email is Invalid';
                    }
                  },
                  onSaved: (value){
                    email = value!;
                  },
                  controller: _email,
                  decoration: InputDecoration(
                      hintText: '',
                      filled: true,
                      fillColor: Colors.black.withOpacity (0.2),
                      border: OutlineInputBorder(
                          borderSide: BorderSide.none,
                          borderRadius: BorderRadius.circular (10))),
                ),
                const SizedBox(
                  height: 5,
                ),

                const Padding (
                  padding: EdgeInsets.symmetric(vertical: 10.0),
                ),


                //add radio button here
                const Text("Choose a Movie: "),

                const Padding (
                  padding: EdgeInsets.symmetric(vertical: 10.0),
                ),

                Row(children: [

                  Radio(

                    value: ticketName.Avengers,
                    groupValue: _movieName,
                    onChanged: (ticketName?value){
                      setState(() {
                        _movieName = value;
                        movieName = 'Avengers (RM 20.00)';
                        ticketPrice = '20';
                      });
                    },

                  ),
                  const SizedBox (width: 5.0,),
                  const Text("Avengers (RM 20.00)"),
                ],),
                Row(children: [
                  //add radio button here
                  Radio(
                    value: ticketName.Batman,
                    groupValue: _movieName,
                    onChanged: (ticketName? value){
                      setState(() {
                        _movieName = value;
                        movieName = 'Batman (RM 10.00) ';
                        ticketPrice = '10';
                      });
                    },
                  ),
                  const SizedBox (width: 5.0,),
                  const Text("Batman (RM 10.00)"),
                ],),
                Row(children: [
                  //add radio button here
                  Radio(
                    value: ticketName.Kimetsu,
                    groupValue: _movieName,
                    onChanged: (ticketName? value){
                      setState(() {
                        _movieName = value;
                        movieName = 'Kimetsu No Yaiba (RM 12.00) ';
                        ticketPrice = '12';
                      });
                    },

                  ),
                  const SizedBox (width: 5.0,),
                  const Text("Kimetsu No Yaiba (RM 12.00)"),
                ],),


                const Padding (
                  padding: EdgeInsets.symmetric(vertical: 10.0),
                ),

                const Text('Quantity',textAlign: TextAlign.left),

                const Padding (
                  padding: EdgeInsets.symmetric(vertical: 5.0),
                ),

                TextFormField(
                  validator: (value) {
                    if(value!.isEmpty || value.length < 0){
                      return 'Please Enter the Correct Quantity';
                    }
                  },
                  onSaved: (value){
                    var quantity = int.parse(value!);
                  },
                  controller: _quantity,
                  decoration: InputDecoration(
                      hintText: 'Quantity',
                      filled: true,
                      fillColor: Colors.black.withOpacity (0.2),
                      border: OutlineInputBorder(
                          borderSide: BorderSide.none,
                          borderRadius: BorderRadius.circular (10))),
                ),
                const SizedBox(
                  height: 5,
                ),

                const Padding (
                  padding: EdgeInsets.symmetric(vertical: 10.0),
                ),

                ElevatedButton(
                  onPressed: (){
                    final isValid = formKey.currentState?.validate();
                    if(isValid!=null) {
                      formKey.currentState!.save();
                      Navigator.push(
                          context, MaterialPageRoute(builder: (context) => calculatePrice(name: _name.text, movieName: movieName, ticketPrice: ticketPrice, email: _email.text, quantity: _quantity.text)));
                    }
                  },
                  child: const Text('Calculate'),
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }
}

calculate.dart计算.dart

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

class calculatePrice extends StatelessWidget {

  late String name, email, movieName, ticketPrice, quantity;


  calculatePrice({required this.name, required this.email, required this.quantity, required this.movieName, required this.ticketPrice});


  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("eTicket"),
      ),
      body: Center(
          child: Padding(
            padding: const EdgeInsets.symmetric (
              horizontal: 20,),
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center ,
              crossAxisAlignment: CrossAxisAlignment.start,

              children: <Widget>[
                Text('Name : $name'),
                const Padding ( padding: EdgeInsets.symmetric(vertical: 5.0),),
                Text('Email $email'),
                const Padding ( padding: EdgeInsets.symmetric(vertical: 5.0),),
                Text('Movie : $movieName'),
                const Padding ( padding: EdgeInsets.symmetric(vertical: 5.0),),
                Text('Quantity $quantity'),
                const Padding ( padding: EdgeInsets.symmetric(vertical: 5.0),),
                Text('Total Price : ${int.parse(quantity) * int.parse(ticketPrice) }'),
                const Padding ( padding: EdgeInsets.symmetric(vertical: 10.0),),

                ElevatedButton(
                  onPressed: (){
                    Navigator.push(
                        context, MaterialPageRoute(builder: (context) =>  const MyApp()));
                  },
                  child: const Text('Back'),
                ),
              ],
            ),
          )
      ),
    );
  }
}

This is the answer based on the above code.这是基于上述代码的答案。 Thank you for the suggestion and helps from the others.感谢您的建议和其他人的帮助。

main.dart主要.dart

import 'package:flutter/material.dart';
import 'result.dart';
import 'customer.dart';
import 'movie.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'e-Ticket',
      theme: ThemeData(
        primarySwatch: Colors.green,
      ),
      home: const MyHomePage(title: 'Movie e-Ticket'),
    );
  }
}

enum SingingCharacter { avengers, batman, kimetsu }

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key, required this.title}) : super(key: key);
  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  final txtName = TextEditingController();
  final txtEmail = TextEditingController();
  final txtQuantity = TextEditingController();
  SingingCharacter? _character = SingingCharacter.avengers;

  getPriceFromCharacter(SingingCharacter? character, int quantity) {
    switch (character) {
      case SingingCharacter.avengers:
        {
          return 20 * quantity;
        }
      case SingingCharacter.batman:
        {
          return 10 * quantity;
        }
      case SingingCharacter.kimetsu:
        {
          return 12 * quantity;
        }
    }
  }

  getMovieName(SingingCharacter? character) {
    switch (character) {
      case SingingCharacter.avengers:
        {
          return "Avengers";
        }
      case SingingCharacter.batman:
        {
          return "Batman";
        }
      case SingingCharacter.kimetsu:
        {
          return "Kimetsu";
        }
    }
  }

  // this to go to result screen and show the result
  void _gotoResultScreen() {
    int price = getPriceFromCharacter(_character, int.parse(txtQuantity.text));
    String movieName = getMovieName(_character);
    Customer c = Customer(txtName.text, txtEmail.text);
    Movie m = Movie(int.parse(txtQuantity.text), price, movieName);

    Navigator.push(
      context,
      MaterialPageRoute(
          builder: (context) => ResultPage(
            title: "Total Price",
            content: "Here is your details",
            customer: c,
            movie: m,
          )),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.spaceEvenly,
          children: <Widget>[
            const Text('Name', textAlign: TextAlign.left),


            TextField(
              controller: txtName,
              decoration: InputDecoration(
                hintText: '',
                filled: true,
                fillColor: Colors.green.withOpacity(0.2),
                border: OutlineInputBorder(
                  borderRadius: BorderRadius.circular(10),
                  borderSide: BorderSide.none
                )
              ),
            ),
            const Text('Email'),
            TextField(
              controller: txtEmail,
              decoration: InputDecoration(
              hintText: '',
              filled: true,
              fillColor: Colors.green.withOpacity(0.2),
              border: OutlineInputBorder(
                borderRadius: BorderRadius.circular(10),
                borderSide: BorderSide.none
            ),)
            ),

            // This is for radio button in list tile
            const Text('Choose a movie:'),
            ListTile(
              title: const Text('AVENGERS(RM20)'),
              leading: Radio<SingingCharacter>(
                value: SingingCharacter.avengers,
                groupValue: _character,
                onChanged: (SingingCharacter? value) {
                  setState(() {
                    _character = value;
                  });
                },
              ),
            ),

            ListTile(
              title: const Text('BATMAN(RM10)'),
              leading: Radio<SingingCharacter>(
                  value: SingingCharacter.batman,
                  groupValue: _character,
                  onChanged: (SingingCharacter? value) {
                    setState(() {
                      _character = value;
                    });
                  }),
            ),

            ListTile(
              title: const Text('KIMETSU NO YAIBA(RM12)'),
              leading: Radio<SingingCharacter>(
                  value: SingingCharacter.kimetsu,
                  groupValue: _character,
                  onChanged: (SingingCharacter? value) {
                    setState(() {
                      _character = value;
                    });
                  }),
            ),

            // Input Quantity of the movie
            const Text('quantity'),
            TextField(
              controller: txtQuantity,
              decoration: InputDecoration(
                hintText: '',
                filled: true,
                fillColor: Colors.green.withOpacity(0.2),
                border: OutlineInputBorder(
                  borderSide: BorderSide.none,
                  borderRadius: BorderRadius.circular(10)
                )
              ),
            ),

            // When user click calculate Button
            ElevatedButton(
              onPressed: _gotoResultScreen,
              child: const Text('Calculate'),
            ),
          ],
        ),
      ),
    );
  }
}

movie.dart电影.dart

class Movie {
  final int quantity;
  final int totalPrice;
  final String movieName;

  const Movie( this.quantity,this.totalPrice,this.movieName);
}

result.dart结果.dart

import 'package:e_tickets/main.dart';
import 'package:flutter/material.dart';
import 'customer.dart';
import 'movie.dart';

class ResultPage extends StatefulWidget {
  const ResultPage({Key? key, required this.title, required this.content, required this.customer, required this.movie}) : super(key: key);

  final String title;
  final String content;
  final Customer customer;
  final Movie movie;

  @override
  State<ResultPage> createState() => _ResultPageState();
}

class _ResultPageState extends State<ResultPage> {

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          crossAxisAlignment: CrossAxisAlignment.start,

          children: <Widget>[
            Text(widget.content,),
            const Padding ( padding: EdgeInsets.symmetric(vertical: 5.0),),
            Text("Name: " + widget.customer.name),
            const Padding ( padding: EdgeInsets.symmetric(vertical: 5.0),),
            Text("Email: " + widget.customer.email),
            const Padding ( padding: EdgeInsets.symmetric(vertical: 5.0),),
            Text("Quantity: " + widget.movie.quantity.toString()),
            const Padding ( padding: EdgeInsets.symmetric(vertical: 5.0),),
            Text("Movie Name: " + widget.movie.movieName),
            const Padding ( padding: EdgeInsets.symmetric(vertical: 5.0),),
            Text("Total Price: RM" + widget.movie.totalPrice.toString()),
            const Padding ( padding: EdgeInsets.symmetric(vertical: 5.0),),

            ElevatedButton(
              onPressed: (){
                Navigator.push(
                    context, MaterialPageRoute(builder: (context) =>  const MyApp()));
              },
              child: const Text('Back'),
            ),
          ],
        ),
      ),
    );
  }
}

customer.dart客户.dart

class Customer {
  final String name;
  final String email;

  const Customer(this.name, this.email);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM