如何使用小部件值从有状态变为无状态

时间:2021-01-04 00:41:59

标签: flutter

我在使用第一页的值传递将值从第二页传输到第三页时遇到了困难。当我尝试使用我习惯于在有状态小部件中调用数据的常用方式时,它会在未定义时返回错误。

class restaurantLISTVIEW extends StatefulWidget {

  restaurantLISTVIEW({this.category});
  final String category;

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

在扩展状态内:(工作)

FloatingActionButton(
          onPressed: (){
            return showDialog(
              context: context,
              builder: (context){
                return AlertDialog(
                  content: Text(
                      '${widget.category}'
                  ),
                );
              },
            );
          },),

扩展无状态小部件时出错,返回空值:(不工作)

onTap: ()
            {
              Navigator.of(context).push(new MaterialPageRoute(builder: (BuildContext context)=> new SarapanPagi(list: list, index: i, category: category)));
            }

内扩展无状态:(不工作)

FloatingActionButton(
          onPressed: (){
            return showDialog(
              context: context,
              builder: (context){
                return AlertDialog(
                  content: Text(
                      '$category hellp'
                  ),
                );
              },
            );
          },),

enter image description here

第二页的完整代码:

import 'dart:convert';

import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'package:http/http.dart' as HTTP;
import 'breakfast.dart';

// ignore: camel_case_types
class restaurantLISTVIEW extends StatefulWidget {

  restaurantLISTVIEW({this.category});
  final String category;

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

// ignore: camel_case_types
class _restaurantLISTVIEWState extends State<restaurantLISTVIEW> {


  Future<List> getData() async{

var url = 'http://10.0.2.2/foodsystem/restaurantlist.php';
var data = {'product_type': 'xde pape ppon saje nk hantar value'};
var response = await http.post(url, body: json.encode(data));
//final response= await http.get("http://10.0.2.2/foodsystem/getdata.php");
return json.decode(response.body);}

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        iconTheme: IconThemeData(color: Colors.black),
    title: Row(
      mainAxisAlignment: MainAxisAlignment.spaceEvenly,
      children: [
        //Text("Restaurant's Owner Page"),
        Text('${widget.category}', textAlign: TextAlign.center, style: TextStyle(fontSize: 25, fontWeight: FontWeight.w700), ),
      ],
    ),
    centerTitle: false,
    //automaticallyImplyLeading: false,
  ),
  body:
  Padding(
    padding: const EdgeInsets.only(bottom: 20, left: 5, right: 5),
    child: Column(
      children: [
        SizedBox(height: 30,),
        Container(
          //decoration: BoxDecoration(border: Border.all(color: Colors.black, width: 4), borderRadius: BorderRadius.circular(15)),
          height: 600,
          child: FutureBuilder<List>(
            future: getData(),
            builder: (context, snapshot){
              if(snapshot.hasError) print(snapshot.error);

              return snapshot.hasData ?
              ItemList(list: snapshot.data,) :
              Center(child: CircularProgressIndicator(),);
            },
          ),
        ),
        FloatingActionButton(
          onPressed: (){
            return showDialog(
              context: context,
              builder: (context){
                return AlertDialog(
                  content: Text(
                      '${widget.category}'
                  ),
                );
              },
            );
          },
        ),
        SizedBox(height: 10,),
      ],
    ),
  ),
);
  }
}
class ItemList extends StatelessWidget {

  final List list;
  final String category;
  ItemList({this.list, this.category});
  @override
  Widget build(BuildContext context) {
    return SingleChildScrollView(
      child: Container(
        //color: Colors.red.shade100,
        height: 600,
        child: ListView.builder(
          itemCount: list==null ? 0 : list.length,
          itemBuilder: (context, i){
            return new Container(
              height: 200,
              child: new GestureDetector(
                onTap: ()
            {
              if(widget.category == "Breakfast"){
                Navigator.of(context).push(new MaterialPageRoute(builder: (BuildContext context)=> new SarapanPagi(list: list, index: i, category: category)));
              }
            },
            child: new Card(
              child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  Row(
                    children: [
                      Container(
                        constraints: BoxConstraints(minWidth: 180, maxWidth: 180),
                        child:
                        Column(
                          children: [
                            Text(list[i]["restaurant_name"], style: TextStyle(fontSize: 25, fontWeight: FontWeight.bold), textAlign: TextAlign.center,),
                            Text("Restaurant ID: ${list[i]["restaurant_id"]}", style: TextStyle(fontSize: 20,), textAlign: TextAlign.center,),
                          ],
                        ),
                      ),
                      Padding(
                        padding: const EdgeInsets.only(left :20.0),
                        child: Container(
                          constraints: BoxConstraints(minWidth: 150, maxWidth: 300),
                          child:
                          SizedBox(
                            width: 50,
                            child: Column(
                              children: [
                                Text("SSM: ${list[i]["restaurant_ssm"]}", textAlign: TextAlign.center, style: TextStyle(fontSize: 15),),
                                Text("Phone: ${list[i]["restaurant_phone"]}", textAlign: TextAlign.center, style: TextStyle(fontSize: 15),),
                                Text("Address: ${list[i]["restaurant_address"]}", textAlign: TextAlign.center, style: TextStyle(fontSize: 15),),
                              ],
                            ),
                          ),
                        ),
                      ),
                    ],
                  ),
                  Row(
                    children: [

                    ],
                  ),
                ],
              ),
            ),
          ),
        );
      },
    ),
  ),
);

第三页的全部代码:

import 'dart:convert';
import 'package:http/http.dart' as HTTP;
import 'package:flutter/material.dart';
//import 'globals.dart' as globals;

class SarapanPagi extends StatefulWidget {
  final List list;
  final int index;
  final String category;
  SarapanPagi({this.index,this.list,this.category});


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

class _SarapanPagiState extends State<SarapanPagi> {

  Future<List> getData() async{

    var url = 'http://10.0.2.2/foodsystem/breakfastlist.php';
    var data = {
      'product_type': 'Breakfast',
      'product_owner': widget.list[widget.index]['restaurant_id'],
    };
    var response = await http.post(url, body: json.encode(data));
    //final response= await http.get("http://10.0.2.2/foodsystem/getdata.php");
    return json.decode(response.body);}

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        iconTheme: IconThemeData(color: Colors.black),
    title: Row(
      mainAxisAlignment: MainAxisAlignment.start,
      children: [
        //Text("Restaurant's Owner Page"),
        Text(widget.list[widget.index]['restaurant_name'], textAlign: TextAlign.center, style: TextStyle(fontWeight: FontWeight.w700), ),
      ],
    ),
    centerTitle: false,
    //automaticallyImplyLeading: false,
  ),
  body:
  Padding(
    padding: const EdgeInsets.only(bottom: 20, left: 5, right: 5),
    child: Column(
      children: [
        SizedBox(height: 30,),
        Container(
          //decoration: BoxDecoration(border: Border.all(color: Colors.black, width: 4), borderRadius: BorderRadius.circular(15)),
          height: 600,
          child: FutureBuilder<List>(
            future: getData(),
            builder: (context, snapshot){
              if(snapshot.hasError) print(snapshot.error);

              return snapshot.hasData ?
              ItemList(list: snapshot.data,) :
              Center(child: CircularProgressIndicator(),);
            },
          ),
        ),
        SizedBox(height: 10,),
      ],
    ),
  ),
);
  }
}
class ItemList extends StatelessWidget {

  final List list;
  ItemList({this.list});
  @override
  Widget build(BuildContext context) {
return SingleChildScrollView(
  child: Container(
    //color: Colors.red.shade100,
    height: 600,
    child: ListView.builder(
      itemCount: list==null ? 0 : list.length,
      itemBuilder: (context, i){
        return new Container(
          height: 200,
          child: new GestureDetector(
            onTap: (){},
            child: new Card(
              child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  Row(
                    children: [
                      Padding(
                        padding: const EdgeInsets.all(8.0),
                        child: Image.asset(
                          "images/${list[i]['image']}",
                          width: 150,
                          height: 150,
                        ),
                      ),
                      Padding(
                        padding: const EdgeInsets.only(left: 20.0, bottom: 0),
                        child:
                        Column(
                          children: [
                            Text(list[i]["product_name"], textAlign: TextAlign.center, style: TextStyle(fontSize: 30),),
                            Text("Price RM : ${list[i]["product_price"]}", textAlign: TextAlign.center, style: TextStyle(fontSize: 25),),
                            RaisedButton(
                                shape: RoundedRectangleBorder(borderRadius: new BorderRadius.circular(40.0)),
                                color: Colors.red.shade300,
                                child: Text("Add to Cart", style: TextStyle(fontWeight: FontWeight.bold),),
                                onPressed: (){},
                            )
                          ],
                        ),
                      ),
                    ],
                  ),
                  /*ListTile(
                    title: Text(list[i]["product_name"], textAlign: TextAlign.center, style: TextStyle(fontSize: 30),),
                    leading:
                    Image.asset(
                      "images/${list[i]['image']}",
                      width: 100,
                      height: 100,
                    ),
                    subtitle: Text("Price RM : ${list[i]["product_price"]}", textAlign: TextAlign.center, style: TextStyle(fontSize: 25),),
                  ),*/
                ],
              ),
            ),
          ),
        );
      },
    ),
  ),
);

3 个答案:

答案 0 :(得分:2)

您没有在 widget.category 页面中使用 restaurantLISTVIEW,而是在 ItemList 小部件中使用,这就是您收到该错误的原因。 像这样调整您的 ItemList 小部件

class ItemList extends StatelessWidget {
  final List list;
  final String category;

  ItemList({this.list, this.category});
}

因此,您在 ItemList 中的导航线必须是

Navigator.of(context).push(new MaterialPageRoute(builder: (BuildContext context)=> new SarapanPagi(list: list, index: i, category: category)));

另外,在SarapanPagi页面中,类别的变量类型不是int by String

答案 1 :(得分:1)

您不是在 restaurantLISTVIEW 页面中使用 widget.category,而是在 ItemList 小部件中,

答案 2 :(得分:0)

我提出的解决方案是:

第二页有状态小部件类上的这段代码,需要通过添加类别的值来改进。

    ItemList(list: snapshot.data,)

改进的代码: 此代码将小部件类别中的值存储转发到第二个页面,从有状态小部件进入无状态小部件。

ItemList(list: snapshot.data,category: widget.category) :