flutter 列表展示

来源:https://www.cnblogs.com/shuangzikun/archive/2019/04/28/taotao_flutter_loading_app_story.html
-Advertisement-
Play Games

內容: 1、列表展示 2、輪播圖 3、其他 本次的內容也是在上一節的基礎上進行操作 我們就搞這個story模塊。 目錄: story.dart story主頁面 story_item.dart 構造列表頁面 裡面涉及到兩個公共庫 touch_callback.dart 觸摸回調 story_data ...


內容:

1、列表展示

2、輪播圖

3、其他

本次的內容也是在上一節的基礎上進行操作

我們就搞這個story模塊。

目錄

 

story.dart  story主頁面

import 'package:flutter/material.dart';

import 'story_data.dart';
import 'story_item.dart';
void main() => runApp(Story());

class Story extends StatefulWidget {
  @override
  _Story  createState() => new _Story();
}

class _Story extends State<Story> {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      body: ListView.builder(
        itemCount: storyData.length,
        // 構造列表項
        itemBuilder: (BuildContext context, int index) {
          // 傳入MessageData返回列表項
          return new StoryItem(storyData[index]);
        },
      ),
    );
  }
}

 story_item.dart  構造列表頁面

import 'package:flutter/material.dart';
import 'story_data.dart';
import 'package:date_format/date_format.dart';
import '../common/touch_callback.dart';
import 'story_content.dart';
class StoryItem extends StatelessWidget {
  final StoryData story;
  StoryItem(this.story);
  void main(){
    print(this.story);
  }
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Container(
      decoration: BoxDecoration(
        color: Colors.white,
        // 底部邊
        border:
        Border(bottom: BorderSide(width: 0.5, color: Color(0xFFd9d9d9))),
      ),
      height: 64.0,
      // 按下回調處理空實現
      child: TouchCallBack(
        child: Row(
          crossAxisAlignment: CrossAxisAlignment.center,
          children: <Widget>[
            // 展示頭像
            Container(
              // 頭像左右留一定外邊距
              margin: const EdgeInsets.only(left: 13.0, right: 13.0),
              child: Image.asset(story.image, width: 48.0, height: 48.0,),
            ),
            Expanded(
              // 主標題和子標題採用垂直佈局image/message_normal.png
              child: Column(
                // 垂直方向居中佈局
                mainAxisAlignment: MainAxisAlignment.center,
                // 水平方向靠左對齊
                crossAxisAlignment: CrossAxisAlignment.start,
                children: <Widget>[
                  Text(
                    story.title,
                    style: TextStyle(fontSize: 16.0, color:Color(0xFF353535)),
                    maxLines: 1,
                  ),
                  Padding(
                    padding: const EdgeInsets.only(top: 8.0),
                  ),
                  Text(
                    story.subTitle,
                    style: TextStyle(fontSize: 14.0, color:Color(0xFF9a9a9a)),
                    maxLines: 1,
                    // 顯示不完的文本用省略號來顯示
                    overflow: TextOverflow.ellipsis,
                  ),
                ],
              ),
            ),
          ],
        ),
        onPressed: () {
          // 跳轉到新的頁面
          Navigator.push(context, new MaterialPageRoute(builder: (BuildContext context){
            return new StoryContent(story);
          }));
        },
      ),
    );
  }
}

裡面涉及到兩個公共庫

touch_callback.dart  觸摸回調

import 'package:flutter/material.dart';

// 觸摸回調組件

class TouchCallBack extends StatefulWidget{

  // 子組件
  final Widget child;

  // 回調函數
  final VoidCallback onPressed;
  final bool isfeed;

  // 背景色
  final Color background;

  // 傳入參數列表
  TouchCallBack({Key key,
    @required this.child,
    @required this.onPressed,
    this.isfeed:true,
    this.background:const Color(0xffd8d8d8),
  }):super(key: key);
  @override
  TouchState createState() => TouchState();

}

class TouchState extends State<TouchCallBack> {
  Color color = Colors.transparent;
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    // 返回GestureDetector
    return GestureDetector(
      // 使用container容器包裹
      child: Container(
        color: color,
        child: widget.child,
      ),
      // onTap 回調
      onTap: widget.onPressed,
      onPanDown: (d) {
        if(widget.isfeed == false) return;
        setState(() {
          color = widget.background;
        });
      },
      onPanCancel: () {
        setState(() {
          color = Colors.transparent;
        });
      },
    );
  }
}

story_data.dart  模擬數據

// 聊天數據
class StoryData {
  // id
  var id;

  // 頭像
  String image;

  // 主標題
  String title;

  // 副標題
  String subTitle;

  // 描述
  String description;

  // 圖集
  List imageList;

  StoryData( this.id,  this.image, this.title, this.subTitle , this.description, this.imageList);

}

List<StoryData> storyData = [
  new StoryData(
    1,
    'images/story/01/cover.jpg',
    'episode.1',
    'プロローグ',
    '因為黑沼爽子的外表看起來很陰沉,所以大家給她取了個“貞子”的外號,對想跟大家打成一片的爽子來說,個性開朗活潑又是大家中心人物的風早翔太就成了爽子心中憧憬的對象。在結業式前,爽子心中憧憬的對象風早約了爽子參加試膽大會。',
    [
      'images/story/01/01.jpg',
      'images/story/01/02.jpg',
      'images/story/01/03.jpg',
      'images/story/01/04.jpg',
      'images/story/01/05.jpg',
      'images/story/01/06.jpg',
    ]
  ),
  new StoryData(
    2,
    'images/story/02/cover.jpg',
    'episode.2',
    '席替え',
    '在大雨中淋的全身濕透的爽子到了學校,看到她這幅模樣的同學們都感到無比的害怕,但是卻因為這個機會,讓爽子和吉田千鶴,矢野有了說話的機會,而爽子也很感謝風早很溫柔的對待她。爽子也決定要趁這次換座位的機會下定決心要和坐在隔壁的同學好好相處,可是…。',
    [
      'images/story/02/01.jpg',
      'images/story/02/02.jpg',
      'images/story/02/03.jpg',
      'images/story/02/04.jpg',
      'images/story/02/05.jpg',
    ]
  ),
  new StoryData(
    3,
    'images/story/03/cover.jpg',
    'episode.3',
    '放課後',
    '終於可以和自己憧憬的同學自然的說早安。正當爽子正在為這件事感動的時候,這學期代理班導的副班導荒井一市(通稱:阿瓶)登場了,阿瓶正想要擅自決定誰來製作出席簿時,不想看到大家困擾的爽子就舉起了手…。',
    []
  ),
  new StoryData(
    4,
    'images/story/04/cover.jpg',
    'episode.4',
    '',
    '因為千鶴和矢野的關係,爽子終於再次嘗到幸福的滋味。可是在學校中突然開始傳出中傷千鶴和矢野的流言。雖然千鶴和矢野一開始聽到傳出謠言的人是爽子的時候是一笑置之不太相信,可是…。',
    []
  ),
  new StoryData(
    5,
    'images/story/05/cover.jpg',
    'episode.5',
    '決意',
    '爽子以為千鶴和矢野的流言是因為自己的關係,而感到自責,所以為了不要再讓千鶴和矢野受到傷害,決定回到獨來獨往的自己,而且也和風早保持距離以免風早也受到牽連。但是千鶴和矢野卻被爽子突然冷漠的態度感到迷惘,一直拚命想找出答案。而風早則為了確定爽子的心意決定直接找上爽子…。',
    []
  ),
  new StoryData(
    6,
    'images/story/06/cover.jpg',
    'episode.6',
    '友達',
    '爽子無意間在女生廁所內聽到同年級的在談論千鶴和矢野的謠言,爽子為了要澄清誤會,卻引起了大騒動,連爽子的同班同學們也都說謠言是爽子傳的,但是卻遭到風早強烈的否定。就在這個時候千鶴和矢野登場了…。',
    []
  )
];

story_content.dart 故事詳情

import 'package:flutter/material.dart';
import 'story_data.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:carousel_slider/carousel_slider.dart';
//import 'dart:math';
class StoryContent extends StatefulWidget {
  final StoryData story;
  StoryContent(this.story);
//  StoryContent({Key key}) : super(key: key);
  @override
  _StoryContent createState() => new _StoryContent(story);
}
class _StoryContent extends State<StoryContent> {
  // 獲取參數story
  final StoryData story;
  _StoryContent(this.story);
  String  number = '124';
  String  defaultIcon = '0';
  void main() {
    print(1);
  }
  void _change() {
    setState(() {
      number = defaultIcon == '0'? (int.parse(number) + 1).toString(): (int.parse(number) - 1).toString();
      defaultIcon = defaultIcon == '0' ? '1': '0';
    });
    print(story.imageList);
  }
  @override
  Widget build(BuildContext context) {
    ScreenUtil.instance = ScreenUtil(width: 750, height: 1334)..init(context);
    // TODO: implement build
    return Scaffold(
      appBar: new AppBar(
        leading:
            IconButton(icon: Icon(Icons.arrow_back),
            onPressed: () {
              Navigator.pop(context); // 返回
            }
        ),
      ),
      body: new Container(
        alignment: Alignment.center,
        decoration: BoxDecoration(
            image: DecorationImage(
              image: AssetImage('images/bg/flower_one.jpg'),
              fit: BoxFit.cover,
            )),
        child: new Column(
          crossAxisAlignment: CrossAxisAlignment.center,
          children: <Widget>[
            new Container(
              alignment: Alignment.center,
              width: double.infinity,
              margin: const EdgeInsets.only(top: 30.0, bottom: 10.0),
              child: Text(
                story.title + story.subTitle,
                style: TextStyle(
                  fontWeight: FontWeight.bold,
                  fontSize: 20.0,
                ),
              ),
            ),
            new Container(
             decoration: new BoxDecoration(
                border: new Border.all(width: 1.0, color: Colors.pink),
                color: Colors.grey,
                borderRadius: new BorderRadius.all(new Radius.circular(4.0)),
              ),
              width: ScreenUtil().setWidth(700),
              child: story.imageList.length != 0 ? new CarouselSlider(
                  items: story.imageList.map((i) {
                    return  new Builder(
                      builder: (BuildContext context) {
                        return new Container(
                            width:  MediaQuery.of(context).size.width ,
//                            margin: new EdgeInsets.only(left: 0, right: 1.0),
                            decoration: new BoxDecoration(
                                color: Colors.amber
                            ),
                            child:  new Image.asset(
                              i,
                              fit: BoxFit.fill,
                            ),
                        );
                      },
                    );
                  }).toList(),
                  height: 180.0,
                  autoPlay: false
              ) : Image.asset(story.image, fit:BoxFit.fill),
            ),
            new Container(
              margin: const EdgeInsets.only(top: 10.0, bottom: 10.0),
              alignment: Alignment.center,
              width: ScreenUtil().setWidth(700),
              child: Text(
                  story.description,
                  style: TextStyle(
                      letterSpacing: 2.0,
//                      wordSpacing: 15.0,
                  ),

              ),
            ),
            // 收藏
            new Container(
              margin: const EdgeInsets.only(top: 4.0, bottom: 10.0),
              alignment: Alignment.bottomCenter,
              width: ScreenUtil().setWidth(700),
              child: new Row(
                  children: <Widget>[
                    new IconButton(
                      icon: defaultIcon == '0' ? const Icon(Icons.favorite_border, color: Colors.red) : const Icon(Icons.favorite, color: Colors.red),
                      onPressed: _change,
                    ),
                    new Text(
                      number.toString(),
                    ),
                  ],
              ),
            )
          ],
        ),
      ),
    );
  }
}

輪播插件

使用方法:

import 'package:carousel_slider/carousel_slider.dart';
import 'package:flutter/material.dart';

class Page2 extends StatelessWidget {
  final imagesList = [
    'xxxx.jpg',
    'xxxx1.jpg',
    'xxxx1.jpg',
    ]
  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text("carousel"),
      ),
      body: new CarouselSlider(
          items: imagesList.map((image) {
            return new Builder(
              builder: (BuildContext context) {
                return new Container(
                    width: MediaQuery.of(context).size.width,
                    decoration: new BoxDecoration(
                        color: Colors.amber
                    ),
                    child: new Image.assert(
                     image
                      fit: BoxFit.fill,
                    )
                );
              },
            );
          }).toList(),
          height: 180.0,
          autoPlay: false //自動播放
      )
    );
  }
}    

這裡有個註意的地方,實時更新數據,渲染頁面

setState(() {
      number = defaultIcon == '0'? (int.parse(number) + 1).toString(): (int.parse(number) - 1).toString();
      defaultIcon = defaultIcon == '0' ? '1': '0';
});

截圖:

 

 

  


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • Python基礎之字元串的知識;包括初識字元串,字元串的操作函數,字元串操作函數實操,字元串的切片等。 ...
  • Flask中使用cookie和session 設置cookie from flask import Flask,Response app = Flask(__name__) @app.route('/index') def index(): response = Response("設置cookie ...
  • 4.28日自我總結 一.關於python 二.PyCharm的安裝註意事項 1.激活碼 可以網上找 2.對於當中的Python的設置 對於python的路徑不能選擇系統預設,要手動輸入python.exe的路徑 3.字體設置以及快捷設置 點擊File→setting或者alt+ctrl+s 4.常用 ...
  • 準備工作 1.隨便準備一個項目工程,在本地用Pipenv創建一個虛擬環境並生成Pipfile和pipfile.lock文件,如下: 2.準備一臺伺服器,我這裡使用阿裡雲的ECS SSH連接上 Pycharm同步項目到伺服器 Tools Deployment Configuration 新增一個SFT ...
  • 1.pom.xml 2.UserConsumerDemoApplication.java 3.UserClient.java 4.UserFController.java ...
  • 基礎博弈論 博弈論,又稱對策論,是現代數學的一個分支,強調一個對策,看起來十分深奧,好像古代那些軍師的計謀。的確,博弈論是一門非常深奧的學科,在生活中也有不少運用,但作為信息學奧賽選手,我們沒有必要去專業的學習博弈論,只需要知道一些常見的博弈論以及它的結論和證明即可。 1、 巴什博弈 : 這是一個最 ...
  • 前言 Python虛擬環境是一個虛擬化,從電腦獨立開闢出來的環境。在這個虛擬環境中,我們可以pip安裝各個項目不同的依賴包,從全局中隔離出來,利於管理。 傳統的Python虛擬環境有virtualenv,使用pip freeze requirements.txt 導出依賴。現在又有了一個新神器 Pi ...
  • 1 路由 1.1app.url_map 查看所有路由 from flask import Flask app = Flask(__name__) @app.route('/') def hello_world(): """定義視圖函數""" print(app.url_map) return "he ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...