Flutter 使用重用代码从 rest 中获取数据

Posted

技术标签:

【中文标题】Flutter 使用重用代码从 rest 中获取数据【英文标题】:Flutter fetch data from rest with reuse code 【发布时间】:2020-11-20 10:00:14 【问题描述】:

我尝试重用此代码:“https://github.com/rajayogan/flutterui-plants”,我将使用 rest api 获取数据。 我不知道该怎么做。 有人请帮助或解释。 提前谢谢。 最好的问候

【问题讨论】:

【参考方案1】:

我尝试用代码解释我的问题: 在 flutterui-plants /plantlist.dart 我们有这个代码:

Widget build(BuildContext context) 
    return ListView(
      children: <Widget>[
        Container(
          height: 350.0,
          child: ListView(
            padding: EdgeInsets.only(left: 25.0),
            controller: _scrollController,
            scrollDirection: Axis.horizontal,
            children: <Widget>[
              getPlantCard(
                  'assets/whiteplant.png', '25', 'OUTDOOR', 'Aloe Vera'),
              SizedBox(width: 15.0),
              getPlantCard('assets/smallplant.png', '25', 'INDOOR', 'Ficus'),
              SizedBox(width: 15.0),
              getPlantCard('assets/smallplant.png', '25', 'INDOOR', 'Ficus'),
              SizedBox(width: 15.0),
            ],
          ),
        ),
        Padding(
          padding: EdgeInsets.only(left: 25.0, top: 10.0),
          child: Text(
            'Description',
            style: TextStyle(
                fontFamily: 'Montserrat',
                color: Colors.black,
                fontSize: 17.0,
                fontWeight: FontWeight.w500),
          ),
        ),
        Padding(
          padding: EdgeInsets.only(left: 25.0, top: 10.0),
          child: Text(
            description,
            style: TextStyle(
              fontFamily: 'Montserrat',
              fontSize: 12.0,
            ),
          ),
        )
      ],
    );
  

  getPlantCard(
      String imgPath, String price, String plantType, String plantName) 
    return Stack(
      children: <Widget>[
        Container(
          height: 325.0,
          width: 225.0,
          child: Container(
            decoration: BoxDecoration(
                borderRadius: BorderRadius.circular(10.0),
                color: Color(0xFF399D63)),
            height: 250.0,
            width: 225.0,
            child: Column(
              children: <Widget>[
                Row(
                  mainAxisAlignment: MainAxisAlignment.end,
                  children: <Widget>[
                    Column(
                      children: <Widget>[
                        SizedBox(height: 10.0),
                        Text(
                          'FROM',
                          style: TextStyle(
                              fontFamily: 'Montserrat',
                              fontSize: 12.0,
                              fontWeight: FontWeight.w600,
                              color: Color(0xFF8AC7A4)),
                        ),
                        Text(
                          '\$' + price,
                          style: TextStyle(
                              fontFamily: 'Montserrat',
                              fontSize: 20.0,
                              fontWeight: FontWeight.w400,
                              color: Colors.white),
                        )
                      ],
                    ),
                    SizedBox(width: 10.0)
                  ],
                ),
                Image(
                  image: AssetImage(imgPath),
                  height: 165.0,
                ),
                Row(
                  children: <Widget>[
                    SizedBox(width: 25.0),
                    Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: <Widget>[
                        Text(
                          plantType,
                          style: TextStyle(
                              fontFamily: 'Montserrat',
                              fontSize: 12.0,
                              fontWeight: FontWeight.w600,
                              color: Color(0xFF8AC7A4)),
                        ),
                        Text(
                          plantName,
                          style: TextStyle(
                              fontFamily: 'Montserrat',
                              fontSize: 20.0,
                              fontWeight: FontWeight.w600,
                              color: Colors.white),
                        )
                      ],
                    ),
                  ],
                ),
                SizedBox(height: 10.0),
                Row(
                  children: <Widget>[
                    SizedBox(width: 25.0),
                    Container(
                      height: 30.0,
                      width: 30.0,
                      decoration: BoxDecoration(
                          border: Border.all(
                              color: Color(0xFF8AC7A4),
                              style: BorderStyle.solid,
                              width: 0.5),
                          borderRadius: BorderRadius.circular(5.0),
                          color: Color(0xFF399D63)),
                      child: Icon(Icons.wb_sunny,
                          color: Colors.white.withOpacity(0.4), size: 20.0),
                    ),
                    SizedBox(width: 15.0),
                    Container(
                      height: 30.0,
                      width: 30.0,
                      decoration: BoxDecoration(
                          border: Border.all(
                              color: Color(0xFF8AC7A4),
                              style: BorderStyle.solid,
                              width: 0.5),
                          borderRadius: BorderRadius.circular(5.0),
                          color: Color(0xFF399D63)),
                      child: Icon(Icons.branding_watermark,
                          color: Colors.white.withOpacity(0.4), size: 20.0),
                    ),
                    SizedBox(width: 15.0),
                    Container(
                      height: 30.0,
                      width: 30.0,
                      decoration: BoxDecoration(
                          border: Border.all(
                              color: Color(0xFF8AC7A4),
                              style: BorderStyle.solid,
                              width: 0.5),
                          borderRadius: BorderRadius.circular(5.0),
                          color: Color(0xFF399D63)),
                      child: Icon(Icons.hot_tub,
                          color: Colors.white.withOpacity(0.4), size: 20.0),
                    ),
                    SizedBox(width: 10.0),
                    InkWell(
                      onTap: () 
                        Navigator.of(context).push(MaterialPageRoute(
                          builder: (context) => PlantDetail()
                        ));
                      ,
                      child: Container(
                        height: 30.0,
                        width: 30.0,
                        decoration: BoxDecoration(color: Color(0xFF399D63)),
                        child: Icon(Icons.help_outline,
                            color: Colors.white.withOpacity(0.4), size: 20.0),
                      ),
                    )
                  ],
                )
              ],
            ),
          ),
        ),
        Padding(
          padding: EdgeInsets.only(left: 90.0, top: 300.0),
          child: Container(
            height: 50.0,
            width: 50.0,
            decoration: BoxDecoration(
                borderRadius: BorderRadius.circular(25.0), color: Colors.black),
            child:
                Center(child: Icon(Icons.shopping_cart, color: Colors.white)),
          ),
        )
      ],
    );
  

我试图像这样获取数据: 我添加此代码

List<Product> parseProducts(String responseBody)  
   final parsed = json.decode(responseBody).cast<Map<String, dynamic>>(); 
   return parsed.map<Product>((json) =>Product.fromMap(json)).toList(); 
 

Future<List<Product>> fetchProducts() async  
   final response = await http.get('http://192.168.1.12:8000/plants/',headers: 
     "Authorization": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE1OTYxODM2NjUsImlhdCI6MTU5NjA5NzI2MCwic3ViIjoyfQ.Hz8gbT0bgaj7rNhs4SYl2I8iWxvn5sZ_liqXmHofgSE"
   ); 
   if (response.statusCode == 200)  
      return parseProducts(response.body); 
    else  
      throw Exception('Unable to fetch products from the REST API');
    

并替换此块

getPlantCard(
                      'assets/whiteplant.png', '25', 'OUTDOOR', 'Aloe Vera'),
                  SizedBox(width: 15.0),
                  getPlantCard('assets/smallplant.png', '25', 'INDOOR', 'Ficus'),
                  SizedBox(width: 15.0),
                  getPlantCard('assets/smallplant.png', '25', 'INDOOR', 'Ficus'),
                  SizedBox(width: 15.0),

通过这个

FutureBuilder<List<Product>>(
            future: product,
            builder: (context, snapshot) 
              if (snapshot.hasData) 
                 
                return getPlantCard('assets/'+snapshot.data[0].image,snapshot.data[0].price,snapshot.data[0].outorindoor,snapshot.data[0].name);
                
               else if (snapshot.hasError) 
                return Text("$snapshot.error");
              

              // By default, show a loading spinner.
              return CircularProgressIndicator();
            ),

它适用于一个结果,但如何拥有所有 getplant() 列表。

我希望这次我很清楚,并在此先感谢

【讨论】:

以上是关于Flutter 使用重用代码从 rest 中获取数据的主要内容,如果未能解决你的问题,请参考以下文章

用于从 REST API 获取状态并自动刷新的小部件的 Flutter 食谱?

Flutter - 如何在多个地方重用一些代码

使用 React Hooks 编写 REST API 时如何重用代码?

重用 Django Rest Framework Generic 视图来获取它的 QuerySet

从 REST API 实时更新 Flutter 应用数据

Flutter DropdownButton - 从 REST Web 服务填充项目