Flutter系列(九)ListView实现新闻列表和正文布局

news2024/11/16 17:36:15

基础工程:

Flutter系列(四)底部导航+顶部导航+图文列表完整代码_摸金青年v的博客-CSDN博客

相关文章:

Flutter系列(七)ListView 图文列表详解_flutter 图文列表_摸金青年v的博客-CSDN博客

一、前言

        本文用flutter实现新闻app,新闻列表新闻正文布局,效果展示如下图:

              

二、使用的组件

  1. ListView.separated     带分割线的ListView
  2. ListTile         设置每条新闻的布局
  3. Scrollbar      给它的子组件添加页面滚动条,展示浏览进度
  4. SingleChildScrollView      给它的子组件添加滚动效果,而且组合Expanded组件,可以添加固定在页面上顶部或底部的工具栏

三、完整代码

3.1 新闻列表   recommend.dart

import 'package:flutter/material.dart';
import 'package:flutter_play/animationUtile.dart';
import 'package:flutter_play/article.dart';

/*推荐页*/
class RecommendPage extends StatefulWidget {
  @override
  State<RecommendPage> createState() => _RecommendPage();
}

class _RecommendPage extends State<RecommendPage> {

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Scrollbar(
        child: ListView.separated(
          itemCount: listData.length,  //条目个数:获取数据的个数
          separatorBuilder: (context, index) { // <-- SEE HERE
            return const Divider();
          },  //分割线必要参数
          itemBuilder: (context, index) {
            return GestureDetector(
              onTap: (){
                Navigator.of(context).push(showPageFromRight(ArticlePage())); //点击跳转到新闻详情
              },
              child: ListTile(
                title: Text(listData[index]["title"]), //大标题
                subtitle: Column(
                  crossAxisAlignment: CrossAxisAlignment.start, //左对齐
                  children: [
                    const SizedBox(height: 12),  //设置title和subtitle的间距
                    Text(listData[index]["subtitle"], style: const TextStyle(fontSize: 12, color: Colors.grey)),
                  ],
                ),  //小标题
                trailing: Image.network(listData[index]["image"], fit: BoxFit.fill, width: 110, height: 90), //右侧图片
                visualDensity: const VisualDensity(vertical: 4), //增加item高度,优化布局,便于图片展示
                minVerticalPadding: 8, //组件内边距,title和分割线的垂直间距
              ),
            );
          },
        ),
      ),
    );
  }

  //数据
  List listData = [
    {
      "title": "一汽奔腾T90创新发售,10万级SUV市场多了个性化选择",
      "subtitle": "汽车圈",
      "image": "https://img-blog.csdnimg.cn/c6dfd375abf1433fa3a42951cc186a2b.jpeg",
    },
    {
      "title": "沐飒低于预售价上市,北京现代瞄准70%的大多数",
      "subtitle": "北京现代",
      "image": "https://img-blog.csdnimg.cn/678c0686dc694b65ad6b20693dbc35f1.jpeg",
    },
    {
      "title": "第二款奥特能平台车型上市,别克加速布局主流电动车市场",
      "subtitle": "电动车",
      "image": "https://img-blog.csdnimg.cn/63efe7acbac74e7ebce85e3801f948e3.jpeg",
    },
    {
      "title": "一汽奔腾T90创新发售,10万级SUV市场多了个性化选择",
      "subtitle": "汽车圈",
      "image": "https://img-blog.csdnimg.cn/c6dfd375abf1433fa3a42951cc186a2b.jpeg",
    },
    {
      "title": "沐飒低于预售价上市,北京现代瞄准70%的大多数",
      "subtitle": "北京现代",
      "image": "https://img-blog.csdnimg.cn/678c0686dc694b65ad6b20693dbc35f1.jpeg",
    },
    {
      "title": "第二款奥特能平台车型上市,别克加速布局主流电动车市场",
      "subtitle": "电动车",
      "image": "https://img-blog.csdnimg.cn/63efe7acbac74e7ebce85e3801f948e3.jpeg",
    },
    {
      "title": "一汽奔腾T90创新发售,10万级SUV市场多了个性化选择",
      "subtitle": "汽车圈",
      "image": "https://img-blog.csdnimg.cn/c6dfd375abf1433fa3a42951cc186a2b.jpeg",
    },
    {
      "title": "沐飒低于预售价上市,北京现代瞄准70%的大多数",
      "subtitle": "北京现代",
      "image": "https://img-blog.csdnimg.cn/c6dfd375abf1433fa3a42951cc186a2b.jpeg",
    },
    {
      "title": "第二款奥特能平台车型上市,别克加速布局主流电动车市场",
      "subtitle": "电动车",
      "image": "https://img-blog.csdnimg.cn/c6dfd375abf1433fa3a42951cc186a2b.jpeg",
    },
  ];

}

页面切换特效:右侧滑入工具类   animationUtile.dart

import 'package:flutter/material.dart';

/*动画效果-工具方法*/

/*页面切换动画-页面从屏幕右侧滑入
* @param statelessWidget 传入需要跳转的页面
* */
Route showPageFromRight(StatefulWidget statefulWidget) {
  return PageRouteBuilder(
    pageBuilder: (context, animation, secondaryAnimation) => statefulWidget,
    transitionsBuilder: (context, animation, secondaryAnimation, child) {
      var begin = const Offset(1.0, 0.0);  //页面进入的起点坐标
      var end = Offset.zero;    //页面进入的终点坐标
      const curve = Curves.ease;
      var tween = Tween(begin: begin, end: end).chain(CurveTween(curve: curve));
      return SlideTransition(
        position: animation.drive(tween),
        child: child,
      );
    },
  );
}

3.2 文章布局

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

/*新闻详情页*/
class ArticlePage extends StatefulWidget {
  @override
  State<ArticlePage> createState() => _ArticlePage();
}

class _ArticlePage extends State<ArticlePage> {

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        foregroundColor: Colors.black, //字体颜色
        backgroundColor: const Color(0xFFFBFBFB), //顶部背景色
        title: const Text('最新新闻', style: TextStyle(fontWeight: FontWeight.w300, fontSize: 15)),
        actions: [
          IconButton(
            onPressed: () {},
            icon: const Icon(Icons.more_horiz), //更多操作
          ),
        ],
      ),
      body: Scrollbar(
        child: Column(
          children: [
            Expanded(
              child: SingleChildScrollView(
                child: Column(
                  children: [
                    tile(),  //标题+作者+关注
                    picture(), //图片
                    articleContent(), // 文章内容
                    statement(), // 版权声明
                  ],
                ),
              ),
            ), //实现底部固定必需
            bottomFix() //底部固定栏(点赞+收藏+分享)
          ],
        ),
      ) //进度条
    );
  }

  /*标题+作者*/
  Container tile(){
    return Container(
        margin: const EdgeInsets.all(20),
        child: Column(
          children: [
            Text(data["title"]!, style: const TextStyle(fontWeight: FontWeight.w400, fontSize: 18, color: Colors.black)),
            Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween, //主轴(水平方向)两端对齐
              children: [
                Text(data["subtitle"]!, style: const TextStyle(fontWeight: FontWeight.w600, fontSize: 14, color: Colors.grey)),
                TextButton (
                  style: ButtonStyle(
                      minimumSize: MaterialStateProperty.all(const Size(64, 24)),  //按钮宽高设置
                      backgroundColor: MaterialStateProperty.all(Colors.blueAccent), //背景颜色
                      foregroundColor: MaterialStateProperty.all<Color>(Colors.white), //字体颜色
                      shape: MaterialStateProperty.all(RoundedRectangleBorder(borderRadius: BorderRadius.circular(8))), //圆角
                  ),//扁平风格按钮
                  child: const Text('关注'),
                  onPressed: () {

                  },
                ),
              ]
            )
          ],
        ),
    );
  }

  /*图片*/
  Padding picture(){
    return Padding(
      padding: const EdgeInsets.all(5),
      child: Image.network(data["image"]!, fit: BoxFit.fill, width: 500, height: 240), // 图片,
    );
  }

  /*文章内容*/
  Padding articleContent(){
    return Padding(
      padding: const EdgeInsets.all(20),
      child: Text(data["content"]!, style: const TextStyle(fontWeight: FontWeight.w300, fontSize: 16, color: Colors.black)),
    );
  }

  //数据
  var data = {
    "title" : "一汽奔腾T90创新发售,10万级SUV市场多了个性化选择",
    "subtitle": "汽车圈",
    "image": "https://img-blog.csdnimg.cn/c6dfd375abf1433fa3a42951cc186a2b.jpeg",
    "content": "财联社6月2日讯(编辑 卞纯)去年底人工智能(AI)聊天机器人ChatGPT的问世,在全球范围内掀起了一股AI热潮,并推动AI的发展步入“快车道”。根据一份行业报告,ChatGPT及其竞争对手谷歌Bard等AI工具的发布,将推动一场长达十年的AI繁荣,预计到2032年,生成式AI市场的营收规模将从去年的400亿美元增长逾30倍至1.3万亿美元。根据以曼迪普·辛格(Mandeep Singh)为首的彭博智库(Bloomberg Intelligence)分析师发布的一份新报告,未来十年生成式AI行业可能会以高达42%的复合速度高速增长。报告指出,生成式AI市场将首先由训练AI系统所必需的基础设施需求推动,到2032年,这方面的业务收入将达到2470亿美元;然后,增长动力来自使用AI模型、广告等服务的设备,到2032年,AI支持的数字广告业务收入将达1920亿美元,AI服务器的收入可能达1340亿美元。“未来十年,世界将看到AI领域的爆炸式增长,这有望从根本上改变科技行业的运作方式。” 辛格周四在一份声明中表示。“随着这项技术的发展,它将成为IT支出、广告支出和网络安全等领域中越来越重要的一部分。”自去年年底ChatGPT推出以来,对生成式AI的需求在全球范围内激增,这项技术有望颠覆从客户服务到银行业的一切。这一生成式AI产品使用来自互联网的大量数据样本来学习如何对指令做出反应,能够制作逼真的图像以及像真人一样回答问题。报告还称,亚马逊旗下云计算部门AWS、谷歌母公司Alphabet Inc.、英伟达公司和OpenAI的投资者微软很可能成为人工智能热潮的最大赢家。财联社6月2日讯(编辑 卞纯)去年底人工智能(AI)聊天机器人ChatGPT的问世,在全球范围内掀起了一股AI热潮,并推动AI的发展步入“快车道”。根据一份行业报告,ChatGPT及其竞争对手谷歌Bard等AI工具的发布,将推动一场长达十年的AI繁荣,预计到2032年,生成式AI市场的营收规模将从去年的400亿美元增长逾30倍至1.3万亿美元。根据以曼迪普·辛格(Mandeep Singh)为首的彭博智库(Bloomberg Intelligence)分析师发布的一份新报告,未来十年生成式AI行业可能会以高达42%的复合速度高速增长。报告指出,生成式AI市场将首先由训练AI系统所必需的基础设施需求推动,到2032年,这方面的业务收入将达到2470亿美元;然后,增长动力来自使用AI模型、广告等服务的设备,到2032年,AI支持的数字广告业务收入将达1920亿美元,AI服务器的收入可能达1340亿美元。“未来十年,世界将看到AI领域的爆炸式增长,这有望从根本上改变科技行业的运作方式。” 辛格周四在一份声明中表示。“随着这项技术的发展,它将成为IT支出、广告支出和网络安全等领域中越来越重要的一部分。”自去年年底ChatGPT推出以来,对生成式AI的需求在全球范围内激增,这项技术有望颠覆从客户服务到银行业的一切。这一生成式AI产品使用来自互联网的大量数据样本来学习如何对指令做出反应,能够制作逼真的图像以及像真人一样回答问题。报告还称,亚马逊旗下云计算部门AWS、谷歌母公司Alphabet Inc.、英伟达公司和OpenAI的投资者微软很可能成为人工智能热潮的最大赢家。"
  };

  /*版权声明*/
  Padding statement(){
    return const Padding(
      padding: EdgeInsets.all(20),
      child: Text('版权声明', style: TextStyle(fontWeight: FontWeight.w600, fontSize: 14, color: Colors.grey)),
    );
  }

  /*底部固定栏(点赞+收藏+分享)*/
  SizedBox bottomFix(){
    return SizedBox(
      width: 500,
      height: 50,
      child: ButtonBar(
        children: [
          IconButton(
            color: Colors.grey,
            icon: const Icon(CupertinoIcons.heart),
            onPressed:(){},
          ),
          IconButton(
            color: Colors.grey,
            icon: const Icon(Icons.star_border_outlined),
            onPressed:(){},
          ),
          IconButton(
            color: Colors.grey,
            icon: const Icon(Icons.share),
            onPressed:(){},
          ),
        ]
      ),
    );
  }

}

四、相关资料

4.1 解决的问题

1. 大标题和小标题的间距问题

想设置 ListTile 的 title 和 subtitle间距,在ListTile没有找到这个属性,后来发现 subtitle 是组件,可以通过如下方式设置间距

title: Text(listData[index]["title"]), //大标题
subtitle: Column(
       crossAxisAlignment: CrossAxisAlignment.start, //左对齐
       children: [
           const SizedBox(height: 12),  //设置title和subtitle的间距
           Text(listData[index]["subtitle"], style: const TextStyle(fontSize: 12, color: Colors.grey)),
       ],
),

4.2 图片素材

图片素材来源:https://pixabay.com/zh/    免版权图片网站

                

网络加载使用:

https://img-blog.csdnimg.cn/678c0686dc694b65ad6b20693dbc35f1.jpeg

https://img-blog.csdnimg.cn/63efe7acbac74e7ebce85e3801f948e3.jpeg

本文结束

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/676864.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

注册 Google 邮箱(最新:保姆级教程)

文章目录 1、我们使用浏览器打开谷歌邮箱官网&#xff08;gmail.google.com&#xff09;&#xff0c;进入谷歌邮箱的登录主页&#xff0c;我们点击左下方的创建账号按钮&#xff0c;选择个人用途 2、在进入的界面我们不要着急填写资料&#xff0c;我们先修改语言&#xff0c;点…

(2023,3D 场景生成器 Infinigen)使用程序化生成的无限逼真世界

Infinite PhotorealisticWorlds using Procedural Generation 公众号&#xff1a;EDPJ 目录 0. 摘要 1. 简介 2. 相关工作 3. 方法 4. 实验 参考 S. 总结 S.1 主要思想 S.2 方法 S.3 场景生成 0. 摘要 我们介绍 Infinigen&#xff0c;一个自然世界逼真 3D 场景的…

Verilog | 除法--试商法

试商法 采用试商法实现除法运算&#xff0c;对于32位的除法&#xff0c;需要至少32个时钟周期才能得到除法结果。下面是试商法的一般过程。 设被除数是m&#xff0c;除数是n&#xff0c;商保存在s中&#xff0c;被除数的位数是k&#xff0c;其计算步骤如下&#xff08;为了便…

leetcode814. 二叉树剪枝(java)

二叉树剪枝 leetcode814. 二叉树剪枝题目描述DFS 深度优先遍历 二叉树专题 leetcode814. 二叉树剪枝 来源&#xff1a;力扣&#xff08;LeetCode&#xff09; 链接&#xff1a;https://leetcode.cn/problems/binary-tree-pruning 题目描述 给你二叉树的根结点 root &#xff0c…

《机器学习公式推导与代码实现》chapter17-kmeans

《机器学习公式推导与代码实现》学习笔记&#xff0c;记录一下自己的学习过程&#xff0c;详细的内容请大家购买作者的书籍查阅。 聚类分析和k均值聚类算法 聚类分析(cluster analysis)是一类经典的无监督学习算法&#xff0c;在给定样本的情况下&#xff0c;聚类分析通过度量…

【半监督:交叉分辨率:解纠缠】

Cross-Resolution Semi-Supervised Adversarial Learning for Pansharpening &#xff08;用于泛锐化的交叉分辨率半监督对抗学习&#xff09; 现有的基于深度神经网络&#xff08;DNN&#xff09;的方法已经产生了良好的泛锐化图像。然而&#xff0c;监督DNN为基础的泛锐化方…

卷积是什么

参考&#xff1a; 【官方双语】那么……什么是卷积&#xff1f;https://www.bilibili.com/video/BV1Vd4y1e7pj/ [建议看完] x.1 一维卷积 一维卷积&#xff0c;即对于两个向量的卷积&#xff0c;就是将向量翻转后&#xff0c;从前向后滑动&#xff0c;相乘再相加。 x.2 二维卷…

Spring Boot启动原理

Spring Boot的自动配置为我们提供了快捷方便的方式来运行Spring应用&#xff0c;但很多开发者对其内部启动原理还不是很明白。这篇博客旨在解开Spring Boot的神秘面纱&#xff0c;帮助大家理解它的启动原理。 入口类和注解 我们的Spring Boot应用通常从一个主类开始&#xff…

感知机(Perceptron)底层原理

1.感知机&#xff08;Perceptron&#xff09;底层原理 声明&#xff1a;笔记来源于《白话机器学习的数学》 感知机是接受多个输入后将每个值与各自权重相乘&#xff0c;最后输出总和的模型。 单层感知机因过于简单&#xff0c;无法应用于实际问题&#xff0c;但它是神经网络和深…

8个很少用,但却很好用的 Python 库!

本文介绍一些我们可能很少听过&#xff0c;但是对于特定问题或者特定任务来说&#xff0c;可能会非常有帮助的 Python 库 技术交流 技术要学会分享、交流&#xff0c;不建议闭门造车。一个人可以走的很快、一堆人可以走的更远。 好的文章离不开粉丝的分享、推荐&#xff0c;文…

黑马程序员前端 Vue3 小兔鲜电商项目——(六)二级分类页

文章目录 二级路由配置模版代码配置路由关系跳转配置 面包屑导航实现封装接口渲染数据 分类基础列表实现准备接口渲染数据 列表筛选实现无限加载实现定制路由 scrollBehavior 二级路由配置 模版代码 创建 src\views\SubCategory\index.vue 文件&#xff0c;添加以下代码&…

云服务器部署企业版openGauss,本地Data Studio远程连接

1.下载安装包 在华为云上租一台服务器&#xff0c;操作系统选&#xff1a;openEuler 20.03 64bit (64-bit) 获取openGauss Server安装包&#xff0c;企业版&#xff1a;软件包链接 使用xshell连接服务器&#xff0c;准备软硬件安装环境。准备软硬件安装环境 教程 下载Data …

javaee 过滤器加cookie实现自动登录

思路 如上图&#xff0c;如果勾选了自动登录&#xff0c;在登录时&#xff0c;就将用户名和密码存储到cookie中&#xff0c;当下次访问首页时&#xff0c;过滤器先拦截请求&#xff0c;获取下cookie中的账号密码&#xff0c;然后如果cookie中的账号密码有效就将登录信息存储到…

Paddle FastDeploy 执行Cmake 时错误处理方法

1.Paddle FastDeploy 在cmake 时的命令执行报错处理 命令是参考官网的&#xff0c;如下: git clone https://github.com/PaddlePaddle/FastDeploy.git cd FastDeploy mkdir build && cd build cmake .. -G "Visual Studio 16 2019" -A x64 \-DENABLE_ORT_BA…

【MyBatis-Plus】入门案例与简介

1&#xff0c;MyBatisPlus入门案例与简介 1. 入门案例 MybatisPlus(简称MP)是基于MyBatis框架基础上开发的增强型工具&#xff0c;旨在简化开发、提供效率。 开发方式 基于MyBatis使用MyBatisPlus基于Spring使用MyBatisPlus基于SpringBoot使用MyBatisPlus SpringBoot刚刚我…

工资管理系统(学校期末作业)

一、 题目要求 1、需求分析 工资信息存放在文件中&#xff0c;提供文件的输入、输出等操作&#xff1b;要浏览&#xff0c;提供显示、排序操作&#xff1b;查询功能要求实现查找操作&#xff1b;提供键盘式选择菜单以实现功能选择。 2、总体设计 系统可分为信息输入、信息添…

洛谷 P2782 友好城市 排序 动态规划

题目描述 有一条横贯东西的大河&#xff0c;河有笔直的南北两岸&#xff0c;岸上各有位置各不相同的N个城市。北岸的每个城市有且仅有一个友好城市在南岸&#xff0c;而且不同城市的友好城市不相同。每对友好城市都向政府申请在河上开辟一条直线航道连接两个城市&#xff0c;但…

servlet 技能总结

Servlet介绍 Servlet是Server Applet的简称&#xff0c;称为服务端小程序&#xff0c;是JavaEE平台下的技术标准&#xff0c;基于Java语言编写的服务端程序。Web容器或应用服务器实现了Servlet标准所以Servlet需运行在Web容器或应用服务器中。Servlet主要功能在于能在服务器中执…

【前端技术】uni-app 01:快速开始

开个新坑&#xff0c;学习一下 uni-app&#xff0c;之后也想 uni-app 来做些事&#xff0c;虽然我主业是后端&#xff0c;但 uni-app 其作为一个高效生产力工具&#xff0c;个人认为非常有必要学习一下~ 目录 1 uni-app 介绍 1.1 uni-app 由来 1.2 为什么选择 uni-app 1.3 …

Win7 64位 VS2015及MinGW环境编译矢量库agg-2.5和cairo-1.14.6

书接上文&#xff0c;昨天装了MinGW&#xff0c;主要原因之一是要用到MSYS&#xff0c;所以顺手把FFMPEG又编译了一遍。 回到主题&#xff0c;其实我是想编译矢量库&#xff0c;因为最近要学习一些计算几何算法&#xff0c;所以找个方便的2D画图库就很重要。 说白了其实是懒得…