Fiutter- 案例3 (推荐页面)

前言

推荐页面是Home页面的一个子页面,里面会使用到Loading,列表,API数据请求相关只是

Home页面

微信图片_20220604124922.jpg
微信图片_20220604124927.jpg

Loading

加载框一般会出现在页面请求网络数据,或者进行耗时操作,对用户的感官体验清切对页面也是一种保护,在页面没有完成之前不允许用户操作,这里我们使用了一个第三方依赖去展示loading

需要在你的pubspec.yaml文件中加入loading_indicator_view: ^1.1.0

  flutter:
    sdk: flutter

  cupertino_icons: ^1.0.2
  loading_indicator_view: ^1.1.0

然后点击Pub get进行依赖下载就可以正常使用了

class SuggestPageState extends State {
  List data = List.empty(growable: true);
  var isLoading = true;

  Widget getContent() {
    if (isLoading) {
      return Container(alignment: Alignment.center,child: BallPulseIndicator(ballColor: Colors.green));
    } else {
      return ListView.builder(
        itemBuilder: (BuildContext context, int index) {
          return SuggestItem(data[index]);
        },
        itemCount: data.length,
      );
    }
  }

  @override
  Widget build(BuildContext context) {
    return Column(children: [
      Expanded(flex:1,child: getContent()),
    ],);
  }
}

如果isLoadingtrue的情况下,我们展示Loading,否则我们展示列表数据,当然我们需要去获取列表数据并且在获取到列表数据之后将isLoading设置为false

列表数据

首先我们需要创建一个列表的Item Widget

class SuggestItem extends StatefulWidget {
  SuggestModel data;

  SuggestItem(this.data);

  @override
  State createState() {
    return SuggestItemState(data);
  }
}

class SuggestItemState extends State {
  SuggestModel data;

  SuggestItemState(this.data);

  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.white,
      child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
        Row(
          children: [
            Container(
              child: Padding(
                padding: EdgeInsets.all(10),
                child: Container(
                  clipBehavior: Clip.hardEdge,
                  height: 30,
                  width: 30,
                  decoration: BoxDecoration(
                      borderRadius: BorderRadius.all(Radius.circular(15))),
                  child: Image.network(
                      "https://upload.jianshu.io/users/upload_avatars/25609565/55f1d4c5-f80b-497c-946f-8ab642a2929e.jpg?imageMogr2/auto-orient/strip|imageView2/1/w/300/h/300/format/webps"),
                ),
              ),
            ),
            Text('Mike', style: TextStyle(fontSize: 11)),
            Spacer(),
            Padding(
                padding: EdgeInsets.all(10),
                child: Icon(Icons.arrow_forward_outlined,
                    size: 15, color: Colors.grey))
          ],
        ),
        Padding(
          padding: EdgeInsets.only(left: 10),
          child: Row(
            children: [
              Container(
                padding: EdgeInsets.all(5),
                decoration: BoxDecoration(
                    borderRadius: BorderRadius.all(Radius.circular(15)),
                    color: Color(0x0f00FF00)),
                child: Row(
                  children: [
                    Icon(
                      Icons.offline_pin,
                      color: Colors.green,
                      size: 15,
                    ),
                    Padding(
                      padding: EdgeInsets.only(left: 5, right: 5),
                      child: GestureDetector(
                        onTap: () => {
                          //Jump to Topic Page
                          Navigator.pushNamed(context, '/chooseTopic')
                        },
                        child: Text(
                          '2022观影记录',
                          style: TextStyle(color: Colors.green, fontSize: 12),
                        ),
                      ),
                    )
                  ],
                ),
              ),
              Spacer()
            ],
          ),
        ),
        Padding(
            padding: EdgeInsets.all(10), child: Text('万物方来,万物方去,永远的转着存在的轮子')),
        Padding(
          padding: EdgeInsets.only(left: 10, right: 10),
          child: Row(
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: [
              Flexible(
                flex: 1,
                child: Container(
                  height: 120,
                  clipBehavior: Clip.hardEdge,
                  decoration: BoxDecoration(
                      borderRadius: BorderRadius.only(
                          topLeft: Radius.circular(5),
                          bottomLeft: Radius.circular(5))),
                  child: Image.network(
                      "https://img1.doubanio.com/view/photo/l/public/p2624374019.webp",
                      fit: BoxFit.cover),
                ),
              ),
              Container(
                width: 5,
              ),
              Flexible(
                flex: 1,
                child: Container(
                  height: 120,
                  child: Image.network(
                      "https://img9.doubanio.com/view/photo/l/public/p2561886965.webp",
                      fit: BoxFit.cover),
                ),
              ),
              Container(
                width: 5,
              ),
              Flexible(
                fit: FlexFit.tight,
                flex: 1,
                child: Container(
                  height: 120,
                  clipBehavior: Clip.hardEdge,
                  decoration: BoxDecoration(
                      borderRadius: BorderRadius.only(
                          topRight: Radius.circular(5),
                          bottomRight: Radius.circular(5))),
                  child: Image.network(
                      "https://img1.doubanio.com/view/photo/l/public/p2612697967.webp",
                      fit: BoxFit.cover),
                ),
              )
            ],
          ),
        ),
        Container(
          padding: EdgeInsets.all(10),
          child: Row(
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            crossAxisAlignment: CrossAxisAlignment.center,
            children: [
              Spacer(),
              Icon(
                Icons.thumb_up_alt_outlined,
                color: Colors.grey,
              ),
              Text(
                '553',
                style: TextStyle(color: Colors.grey),
              ),
              Spacer(),
              Icon(Icons.messenger_outline, color: Colors.grey),
              Text('35', style: TextStyle(color: Colors.grey)),
              Spacer(),
              Icon(Icons.folder_shared_outlined, color: Colors.grey),
              Text('36', style: TextStyle(color: Colors.grey)),
              Spacer(),
            ],
          ),
        ),
        Container(
          height: 10,
          alignment: Alignment.center,
          color: Color(0x10000000),
        )
      ]),
    );
  }
}

这里虽然有传递了SuggestModel但是没有使用,还是使用了静态数据,纯粹是因为我懒....想在未来的将来补上

数据请求

添加http请求依赖

http: ^0.12.2 

SuggestPage中增加请求数据的函数

由于豆瓣API最近无法使用,所以直接call了百度达到一个异步请求的动作,然后请求完成之后构建了假数据,并且刷新了状态

  Future getSuggestInfo() async {
    var client = http.Client();
    var response = await client.get("https://www.baidu.com");
    print(response.body);
    List imgs = List.empty(growable: true);
    imgs.add("");
    imgs.add("");
    imgs.add("");
    data.add(SuggestModel(photo: "111",tab: "2022观影记录",message: "万物方来,万物方去,永远的转着存在的轮子",imgRes: imgs));
    data.add(SuggestModel(photo: "111",tab: "2022观影记录",message: "万物方来,万物方去,永远的转着存在的轮子",imgRes: imgs));
    data.add(SuggestModel(photo: "111",tab: "2022观影记录",message: "万物方来,万物方去,永远的转着存在的轮子",imgRes: imgs));
    isLoading = false;
    setState(() {});
  }

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

在实际用切换的过程中发现每次切换到推荐页面时都会进行API请求,因为我们将API请求写在了initState函数中,为了让页面的状体持久化,我们可以添加

class SuggestPageState extends State with AutomaticKeepAliveClientMixin
  @override
  bool get wantKeepAlive => true;

这样就可以保持页面状态,在Tab来回切换时不会多次call API

欢迎关注Mike的

Android 知识整理

你可能感兴趣的:(Fiutter- 案例3 (推荐页面))