吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 1557|回复: 13
收起左侧

[讨论] Flutter 领券联盟特惠推荐列表

[复制链接]
debug_cat 发表于 2020-8-25 14:23
## 效果图
![图片描述]()

### 分析组成控件
1:列表控件,类似Android listview,recyclerview。等列表控件
2:ios的uiTableview
以上是整体。

#### 分析item:
![图片描述]()

我们在写ui之前,先规划好怎么布局它,分析之后,可以确定,
整体:垂直Android:LinearLayout => Column
图片:ImageView => Image
文字:TextView => Text
水平布局:Android:LinearLayout => Row

以上是Android类比flutter控件。
我们需要学习这些控件,如何使用。比如文字大小,颜色,边距等

····
··
·        这里就自学完成了。😀
··
····

点击事件:GestureDetector

最里面的构造就是这样了。
![图片描述]()





#### 网络获取数据
还记得上一篇文章吗,使用原生网络工具,请求数据。
```language
  var baseUrl = 'https://api.sunofbeach.net/shop/onSell/1';

```
我们请求上面的数据。
用浏览打开,然后得到json。
把这个json转成dart bean : UnionOnSellEntity
上一篇中我们有具体教程转的,使用as插件。这里就不说了。

![图片描述]()


#### 全部代码
```language
UnionOnSellEntity
class UnionOnSellEntity with JsonConvert<UnionOnSellEntity> {
        bool success;
        int code;
        String message;
        UnionOnSellData data;
}

class UnionOnSellData with JsonConvert<UnionOnSellData> {
        @JSONField(name: "tbk_dg_optimus_material_response")
        UnionOnSellDataTbkDgOptimusMaterialResponse tbkDgOptimusMaterialResponse;
}

class UnionOnSellDataTbkDgOptimusMaterialResponse with JsonConvert<UnionOnSellDataTbkDgOptimusMaterialResponse> {
        @JSONField(name: "is_default")
        String isDefault;
        @JSONField(name: "result_list")
        UnionOnSellDataTbkDgOptimusMaterialResponseResultList resultList;
        @JSONField(name: "request_id")
        String requestId;
}

class UnionOnSellDataTbkDgOptimusMaterialResponseResultList with JsonConvert<UnionOnSellDataTbkDgOptimusMaterialResponseResultList> {
        @JSONField(name: "map_data")
        List<UnionOnSellDataTbkDgOptimusMaterialResponseResultListMapData> mapData;
}

class UnionOnSellDataTbkDgOptimusMaterialResponseResultListMapData with JsonConvert<UnionOnSellDataTbkDgOptimusMaterialResponseResultListMapData> {
        @JSONField(name: "category_id")
        int categoryId;
        @JSONField(name: "category_name")
        String categoryName;
        @JSONField(name: "click_url")
        String clickUrl;
        @JSONField(name: "commission_rate")
        String commissionRate;
        @JSONField(name: "coupon_amount")
        int couponAmount;
        @JSONField(name: "coupon_click_url")
        String couponClickUrl;
        @JSONField(name: "coupon_end_time")
        String couponEndTime;
        @JSONField(name: "coupon_info")
        String couponInfo;
        @JSONField(name: "coupon_remain_count")
        int couponRemainCount;
        @JSONField(name: "coupon_share_url")
        String couponShareUrl;
        @JSONField(name: "coupon_start_fee")
        String couponStartFee;
        @JSONField(name: "coupon_start_time")
        String couponStartTime;
        @JSONField(name: "coupon_total_count")
        int couponTotalCount;
        @JSONField(name: "item_description")
        String itemDescription;
        @JSONField(name: "item_id")
        int itemId;
        @JSONField(name: "level_one_category_id")
        int levelOneCategoryId;
        @JSONField(name: "level_one_category_name")
        String levelOneCategoryName;
        String nick;
        @JSONField(name: "pict_url")
        String pictUrl;
        @JSONField(name: "seller_id")
        int sellerId;
        @JSONField(name: "shop_title")
        String shopTitle;
        @JSONField(name: "small_images")
        UnionOnSellDataTbkDgOptimusMaterialResponseResultListMapDataSmallImages smallImages;
        String title;
        @JSONField(name: "user_type")
        int userType;
        int volume;
        @JSONField(name: "zk_final_price")
        String zkFinalPrice;
}

class UnionOnSellDataTbkDgOptimusMaterialResponseResultListMapDataSmallImages with JsonConvert<UnionOnSellDataTbkDgOptimusMaterialResponseResultListMapDataSmallImages> {
        List<String> string;
}

```
#### 页面代码
```language
class Recommend extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('特惠推荐'),
      ),
      body: RecommendPage(),
    );
  }
}

class RecommendPage extends StatefulWidget {
  RecommendPage({Key key}) : super(key: key);

  @override
  _RecommendPageState createState() => new _RecommendPageState();
}

class _RecommendPageState extends State<RecommendPage>
    with AutomaticKeepAliveClientMixin {
  @override
  bool get wantKeepAlive => true;

  @override
  void initState() {
    super.initState();
    _getUnionRecommend();
  }

  var baseUrl = 'https://api.sunofbeach.net/shop/onSell/1';

  List<UnionOnSellDataTbkDgOptimusMaterialResponseResultListMapData> mList =
      List();

  _getUnionRecommend() async {
    var url = baseUrl;
    var httpClient = new HttpClient();
    List<UnionOnSellDataTbkDgOptimusMaterialResponseResultListMapData> tempList;
    try {
      var request = await httpClient.getUrl(Uri.parse(url));
      var response = await request.close();
      if (response.statusCode == HttpStatus.OK) {
        var json = await response.transform(utf8.decoder).join();
        Map<String, dynamic> map = jsonDecode(json);
        //json 转 data bean
        var entity = UnionOnSellEntity().fromJson(map);

        tempList = entity.data.tbkDgOptimusMaterialResponse.resultList.mapData;
      } else {
        print("request error");
      }
    } catch (exception) {
      print("request error");
    }
    if (!mounted) return;
    setState(() {
      //请求成功之后,赋值列表中,就可以刷新grid view了.
      mList = tempList;
    });
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      body: GridView.builder(
          itemCount: mList?.length ?? 0,
          gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
            //2列
            crossAxisCount: 2,
            //间距0
            mainAxisSpacing: 0,
            //间距0
            crossAxisSpacing: 0,
            //子 view的比例宽高比
            childAspectRatio: 0.65,
          ),
          itemBuilder: (context, index) {
            if (mList == null) {
              return Text("");
            }
            var item = mList[index];
            var imageUrl = item == null ? "" : "https:" + item.pictUrl;
            var itemTitle = item == null ? "" : item.title;
            //点击事件需要用手势包裹
            return GestureDetector(
              //整个card效果
              child: Card(
                child: Container(
                  margin: EdgeInsets.all(5),
                  //整个item的垂直布局
                  child: Column(
                    children: <Widget>[
                      //图片
                      Image.network(imageUrl),
                      //标题
                      Container(
                        margin: EdgeInsets.fromLTRB(2, 10, 15, 2),
                        child: Text(
                          itemTitle,
                          style: TextStyle(
                              fontSize: 16,
                              color: ColorsUtil.hexColor(0x000814)),
                        ),
                      ),
                      //水平布局包含左边的黄色价格,右边的原价
                      Row(
                        children: <Widget>[
                          Container(
                            margin: EdgeInsets.fromLTRB(2, 5, 0, 10),
                            //黄色价格
                            child: Text(
                              "¥" +
                                  (double.parse(item.zkFinalPrice) -
                                          item.couponAmount)
                                      .toStringAsFixed(2)
                                      .toString(),
                              style: TextStyle(
                                  color: ColorsUtil.hexColor(0xFF8500),
                                  fontSize: 15),
                            ),
                          ),
                          Container(
                            margin: EdgeInsets.fromLTRB(5, 5, 0, 10),
                            child: Text(
                              "原价价:" +
                                  (double.parse(item.zkFinalPrice))
                                      .toStringAsFixed(2)
                                      .toString(),
                              style: TextStyle(
                                  color: ColorsUtil.hexColor(0x666666),
                                  fontSize: 13,
                                  //中横线
                                  decoration: TextDecoration.lineThrough,
                                  decorationColor:
                                      ColorsUtil.hexColor(0x454646)),
                            ),
                          )
                        ],
                      )
                    ],
                  ),
                ),
              ),
              onTap: () {
                setState(() {
                  //点击事件
                  itemClick(index);
                });
              },
            );
          }),
    );
  }

  void itemClick(int index) {
    var item = mList[index];
    //进入领券详情页面.你可以先把这里的代码注释,因为你没有接下来的页面.
    Navigator.push(
      context,
      MaterialPageRoute(
        builder: (context) => TicketDetail(),
        settings: RouteSettings(
          arguments: TicketArgs(
            item.title,
            item.couponClickUrl == null ? item.clickUrl : item.couponClickUrl,
            "https:" + item.pictUrl,
          ),
        ),
      ),
    );
  }
}

```

![图片描述]()
在你的app入口,替换成

```language
Recommend
```

运行app,就能看的效果了。
```language
配置文件记得增加这个权限
<uses-permission android:name="android.permission.INTERNET" />
```

flutter新手分享,大佬轻喷
以上~

免费评分

参与人数 2吾爱币 +2 热心值 +2 收起 理由
深渊莫冥 + 1 + 1 我很赞同!
mo211683 + 1 + 1 用心讨论,共获提升!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

深渊莫冥 发表于 2020-8-25 14:43
我是这个学期学的flutter,楼主很棒,加油
jzw12345 发表于 2020-8-25 14:53
正己 发表于 2020-8-25 15:14
建议代码用代码块包起来,这样看起来比较美观
 楼主| debug_cat 发表于 2020-8-25 16:25
深渊莫冥 发表于 2020-8-25 14:43
我是这个学期学的flutter,楼主很棒,加油

我是在工作之余学习的,哈哈,加油
 楼主| debug_cat 发表于 2020-8-25 16:27
jzw12345 发表于 2020-8-25 14:53
不错,感谢分享。

感谢阅读,谢谢你
986244073 发表于 2020-8-25 16:45
可以分享下api吗
爱你分享 发表于 2020-8-25 16:55
有零基础的教程么
YI封夕 发表于 2020-8-25 17:41
看不懂
不过,支持楼主
yangcg8 发表于 2020-8-27 16:18
值得借鉴的思路,谢谢分享
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-26 14:48

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表