Fiutter- 案例3 (推薦頁(yè)面)

前言

推薦頁(yè)面是Home頁(yè)面的一個(gè)子頁(yè)面,里面會(huì)使用到Loading,列表,API數(shù)據(jù)請(qǐng)求相關(guān)只是

Home頁(yè)面

微信圖片_20220604124922.jpg
微信圖片_20220604124927.jpg

Loading

加載框一般會(huì)出現(xiàn)在頁(yè)面請(qǐng)求網(wǎng)絡(luò)數(shù)據(jù),或者進(jìn)行耗時(shí)操作,對(duì)用戶的感官體驗(yàn)清切對(duì)頁(yè)面也是一種保護(hù),在頁(yè)面沒(méi)有完成之前不允許用戶操作,這里我們使用了一個(gè)第三方依賴去展示loading

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

  flutter:
    sdk: flutter

  cupertino_icons: ^1.0.2
  loading_indicator_view: ^1.1.0

然后點(diǎn)擊Pub get進(jìn)行依賴下載就可以正常使用了

class SuggestPageState extends State {
  List<SuggestModel> 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,否則我們展示列表數(shù)據(jù),當(dāng)然我們需要去獲取列表數(shù)據(jù)并且在獲取到列表數(shù)據(jù)之后將isLoading設(shè)置為false

列表數(shù)據(jù)

首先我們需要?jiǎng)?chuàng)建一個(gè)列表的Item Widget

class SuggestItem extends StatefulWidget {
  SuggestModel data;

  SuggestItem(this.data);

  @override
  State<StatefulWidget> 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('萬(wàn)物方來(lái),萬(wàn)物方去,永遠(yuǎn)的轉(zhuǎn)著存在的輪子')),
        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但是沒(méi)有使用,還是使用了靜態(tài)數(shù)據(jù),純粹是因?yàn)槲覒?...想在未來(lái)的將來(lái)補(bǔ)上

數(shù)據(jù)請(qǐng)求

添加http請(qǐng)求依賴

http: ^0.12.2 

SuggestPage中增加請(qǐng)求數(shù)據(jù)的函數(shù)

由于豆瓣API最近無(wú)法使用,所以直接call了百度達(dá)到一個(gè)異步請(qǐng)求的動(dòng)作,然后請(qǐng)求完成之后構(gòu)建了假數(shù)據(jù),并且刷新了狀態(tài)

  Future<void> getSuggestInfo() async {
    var client = http.Client();
    var response = await client.get("https://www.baidu.com");
    print(response.body);
    List<String> imgs = List.empty(growable: true);
    imgs.add("");
    imgs.add("");
    imgs.add("");
    data.add(SuggestModel(photo: "111",tab: "2022觀影記錄",message: "萬(wàn)物方來(lái),萬(wàn)物方去,永遠(yuǎn)的轉(zhuǎn)著存在的輪子",imgRes: imgs));
    data.add(SuggestModel(photo: "111",tab: "2022觀影記錄",message: "萬(wàn)物方來(lái),萬(wàn)物方去,永遠(yuǎn)的轉(zhuǎn)著存在的輪子",imgRes: imgs));
    data.add(SuggestModel(photo: "111",tab: "2022觀影記錄",message: "萬(wàn)物方來(lái),萬(wàn)物方去,永遠(yuǎn)的轉(zhuǎn)著存在的輪子",imgRes: imgs));
    isLoading = false;
    setState(() {});
  }

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

在實(shí)際用切換的過(guò)程中發(fā)現(xiàn)每次切換到推薦頁(yè)面時(shí)都會(huì)進(jìn)行API請(qǐng)求,因?yàn)槲覀儗PI請(qǐng)求寫(xiě)在了initState函數(shù)中,為了讓頁(yè)面的狀體持久化,我們可以添加

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

這樣就可以保持頁(yè)面狀態(tài),在Tab來(lái)回切換時(shí)不會(huì)多次call API

歡迎關(guān)注Mike的簡(jiǎn)書(shū)

Android 知識(shí)整理

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容