当前位置: 首页 > article >正文

基于Flutter的图片浏览器的实现

一  效果展示:

 1. 图片展示:

      

 

2.混色,平铺,拉伸,原图展示

        

      

二  实验准备:

    1.在包结构中创建images包来存放我们用到的图片,在pubspec.yaml中声明路径:

    2. 检查虚拟机是否正常运行:

三  详细设计:

大体流程:

特别注意:

我们创建继承自State_MyHomePageState类的用处是

  1. 状态管理: State 对象是与 StatefulWidget 相关联的状态的持有者。通过继承自State,可以在这个对象中存储和管理与用户界面相关的数据。

  2. 生命周期方法: State 类提供了一系列生命周期方法,例如 initStatedidUpdateWidgetbuilddispose 等。这些方法允许在不同阶段执行特定的操作,例如在初始化状态、更新部件时、构建部件树、销毁状态等。

  3. 动态更新: 通过调用 setState 方法,可以通知Flutter框架重新构建UI。这使得在用户与应用交互时,能够根据状态的变化动态更新UI,提供交互性和实时性。

  4. 保存和恢复状态: State 对象可以保存和恢复其状态。这对于在应用生命周期内保留数据状态,以及在设备方向切换或应用关闭后恢复状态非常有用。

  5. 构建UI: build 方法是构建用户界面的地方。通过覆盖 build 方法,可以定义在状态更改时如何构建和渲染UI。

  6. 数据封装: 将相关的状态和逻辑封装在State类中有助于提高代码的组织性和可读性。这样,每个部件的状态都可以独立管理,降低了代码的复杂度。

  7. 优化性能: State 对象的状态是惰性创建的,当部件首次插入到树中时,State 对象才会被创建。这有助于优化应用性能。

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

功能实现:

功能一:图片展示:

组件:

Container: 用于创建包含图片的容器。

Scaffold: 提供应用程序的基本结构,包括主体区域。

Column: 用于在垂直方向上排列不同的小部件。

属性和方法:

Container的width和height属性: 设置容器的宽度和高度。

Container的color属性: 设置容器的背景颜色。

Container的child属性: 设置容器中包含的子部件。

DecorationImage的image属性: 设置Image.asset的图片来源。

DecorationImage的repeat属性: 设置图片在容器中的重复方式。

Container imgContainer = Container(
  width: MediaQuery.of(context).size.width,
  height: MediaQuery.of(context).size.height / 3,
  color: Colors.amberAccent,
  child: Container(
    decoration: BoxDecoration(
      image: DecorationImage(
        image: AssetImage(lists[index]),
        repeat: ImageRepeat.repeat,
      ),
    ),
  ),
);

功能二:效果选择 :

组件:

RadioListTile: 用于显示单选列表项。

属性和方法:

value属性: 表示当前选项的值。

groupValue属性: 表示所在组的当前选中值。

title属性: 列表项的主要文本。

subtitle属性: 列表项的副标题文本。

onChanged回调: 在用户选择该项时触发的函数。

RadioListTile(
  value: 0,
  groupValue: selected,
  title: Text('混色'),
  subtitle: Slider(
    value: colorsValue,
    min: 0,
    max: 255,
    onChanged: (value) {
      setState(() {
        colorsValue = value;
      });
    },
  ),
  onChanged: (value) {
    setState(() {
      selected = value ?? 0;
    });
  },
);

功能三:混色效果 :

组件:

Container: 用于包裹混色效果的图片。

ColorFiltered: 用于应用颜色混合效果。

属性和方法:

colorFilter属性: 设置ColorFiltered的颜色混合滤镜。

Color.fromARGB方法: 创建一个颜色对象。

round()方法: 将浮点数四舍五入为最接近的整数。

ColorFiltered(
  colorFilter: ColorFilter.mode(
    Color.fromARGB(255, colorsValue.round(), colorsValue.round(), colorsValue.round()),
    BlendMode.colorDodge,
  ),
  child: Image.asset(lists[index]),
);

功能四:平铺效果:

组件:

Container: 用于包裹平铺效果的图片。

属性和方法:

DecorationImage的repeat属性: 设置图片在容器中的重复方式。

round()方法: 将浮点数四舍五入为最接近的整数。

Container(
  width: MediaQuery.of(context).size.width,
  height: MediaQuery.of(context).size.height / 3,
  color: Colors.amberAccent,
  child: Container(
    decoration: BoxDecoration(
      image: DecorationImage(
        image: AssetImage(lists[index]),
        repeat: ImageRepeat.repeat,
      ),
    ),
  ),
);

功能五:颜色调整:

组件:

Slider: 用于提供滑动条以调整颜色值。

属性和方法:

value属性: 表示当前滑块的值。

min和max属性: 设置滑块的最小和最大值。

onChanged回调: 在滑动条值变化时触发的函数。

Slider(
  value: colorsValue,
  min: 0,
  max: 255,
  onChanged: (value) {
    setState(() {
      colorsValue = value;
    });
  },
);

功能六:图片切换 :

组件:

ElevatedButton: 用于显示提升的按钮。

属性和方法:

onPressed回调: 在按钮被点击时触发的函数。

ElevatedButton(
  child: Text('向前'),
  onPressed: () {
    setState(() {
      if (index > 0) index--;
    });
  },
);
ElevatedButton(
   child: Text('向后'),
      onPressed: () {
         setState(() {
         if (index < lists.length - 1) index++;
      });
   },
),

功能七:拉伸图片

组件:

Container 组件:

用途: 用于创建一个矩形的可视容器,可以包含子组件,并设置容器的样式和尺寸。

相关属性:

width:容器的宽度,设置为屏幕的宽度。

height:容器的高度,设置为屏幕高度的三分之一。

color:容器的颜色,设置为 Colors.amberAccent

Image.asset 组件:

用途: 用于显示应用内的图片资源。

相关属性:

lists[index]:图片的路径,从预定义的列表中选择。

fit:用于指定图片的填充方式,这里设置为 BoxFit.fill,表示填充整个容器。

mgContainer = Container(
        width: MediaQuery.of(context).size.width,
        height: MediaQuery.of(context).size.height / 3,
        color: Colors.amberAccent,
        child: Image.asset(
          lists[index],
          fit: BoxFit.fill,
        ),
      );

四 完整代码

import 'package:flutter/material.dart';
void main() {
  runApp(MyApp());
}
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: MyHomePage(),
    );
  }
}
class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
  int? selected = 0; // 默认选中混色
  List<String> lists = ['images/p1.jpg', 'images/p2.jpg', 'images/p3.jpg', 'images/p4.jpg'];
  int index = 0;
  double colorsValue = 0.0;
  BoxFit fitType = BoxFit.fill; // 用于控制图片的填充方式
  @override
  Widget build(BuildContext context) {
    Container imgContainer;

    if (selected == 1) {
      // 如果是平铺效果,将 Image.asset 放在 Container 中
      imgContainer = Container(
        width: MediaQuery.of(context).size.width,
        height: MediaQuery.of(context).size.height / 3,
        color: Colors.amberAccent,
        child: Container(
          decoration: BoxDecoration(
            image: DecorationImage(
              image: AssetImage(lists[index]),
              repeat: ImageRepeat.repeat,
            ),
          ),
        ),
      );
    } else if (selected == 2) {
      // 如果是拉伸原图,将图片的填充方式设置为拉伸
      imgContainer = Container(
        width: MediaQuery.of(context).size.width,
        height: MediaQuery.of(context).size.height / 3,
        color: Colors.amberAccent,
        child: Image.asset(
          lists[index],
          fit: BoxFit.fill,
        ),
      );
    } else {
      // 否则应用混色效果
      imgContainer = Container(
        width: MediaQuery.of(context).size.width,
        height: MediaQuery.of(context).size.height / 3,
        color: Colors.amberAccent,
        child: ColorFiltered(
          colorFilter: ColorFilter.mode(
            Color.fromARGB(255, colorsValue.round(), colorsValue.round(), colorsValue.round()),
            BlendMode.colorDodge,
          ),
          child: Image.asset(
            lists[index],
            fit: fitType, // 使用BoxFit属性来控制图片的填充方式
          ),
        ),
      );
    }

    return Scaffold(
      body: Column(
        children: <Widget>[
          imgContainer,
          RadioListTile(
            value: 0,
            groupValue: selected,
            title: Text('混色'),
            subtitle: Slider(
              value: colorsValue,
              min: 0,
              max: 255,
              onChanged: (value) {
                setState(() {
                  colorsValue = value;
                });
              },
            ),
            onChanged: (value) {
              setState(() {
                selected = value ?? 0;
                fitType = BoxFit.fill; // 选择混色时,将图片的填充方式设置为拉伸
              });
            },
          ),
          RadioListTile(
            value: 1,
            groupValue: selected,
            title: Text('平铺'),
            subtitle: Text('按XY方向平铺在显示区域'),
            onChanged: (value) {
              setState(() {
                selected = value ?? 0;
                fitType = BoxFit.fill; // 选择平铺时,将图片的填充方式设置为拉伸
              });
            },
          ),
          RadioListTile(
            value: 2,
            groupValue: selected,
            title: Text('拉伸原图'), // 选择拉伸原图时,将图片的填充方式设置为拉伸
            onChanged: (value) {
              setState(() {
                selected = value ?? 0;
                fitType = BoxFit.fill;
              });
            },
          ),
          RadioListTile(
            value: 3,
            groupValue: selected,
            title: Text('显示原图'), // 新增:显示原图
            onChanged: (value) {
              setState(() {
                selected = value ?? 0;
                fitType = BoxFit.contain; // 选择显示原图时,将图片的填充方式设置为保持宽高比适应容器
              });
            },
          ),
          Row(
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: <Widget>[
              ElevatedButton(
                child: Text('向前'),
                onPressed: () {
                  setState(() {
                    if (index > 0) index--;
                  });
                },
              ),
              ElevatedButton(
                child: Text('向后'),
                onPressed: () {
                  setState(() {
                    if (index < lists.length - 1) index++;
                  });
                },
              ),
            ],
          ),
        ],
      ),
    );
  }
}


http://www.kler.cn/a/145666.html

相关文章:

  • 【C】本地变量与全局变量
  • 【面试】Java 记录一次面试过程 三年工作经验
  • 使用 Box2D 库开发愤怒的小鸟游戏
  • 自然语言处理(NLP)领域相关模型概述
  • 2025年最新汽车零部件企业销售项目管理解决方案
  • python转转商超书籍信息爬虫
  • 【极客技术】真假GPT-4?微调 Llama 2 以替代 GPT-3.5/4 已然可行!
  • 【数据中台】开源项目(2)-Dbus系统架构
  • 【Docker】安装Redis 通俗易懂 亲测没有任何问题 只需三步
  • 使用 HTML、CSS 和 JavaScript 创建图像滑块
  • 【c++j继承】
  • mysql MHA配置文件
  • TypeScript中的枚举是什么?
  • OpenGL 绘制旋转球(Qt)
  • HarmonyOS ArkTS Video组件的使用(七)
  • 文件重命名不求人:批量重命名的技巧,告别手动修改文件名
  • 2311skia,06编解码图像上
  • PHP echo和print 语句
  • 可以在Playgrounds或Xcode Command Line Tool开始学习Swift
  • Screen操作
  • vscode在运行c语言时,无法scanf输入
  • 2018年11月8日 Go生态洞察:参与2018年Go用户调查
  • SpringBoot——定制错误页面及原理
  • leetcode刷题详解五
  • 乐观锁解决库存超卖问题
  • 【超强笔记软件】Obsidian如何实现免费无限流量无套路云同步?