flutter 加载手机媒体图片并显示在原先页面

这是代码部分:

import 'package:flutter/material.dart';

import 'dart:io';

import 'package:image_picker/image_picker.dart';

void main() {

  runApp(const MyApp());

}

final ImagePicker _imagePicker = ImagePicker();

class MyApp extends StatelessWidget {

  const MyApp({super.key});

  // This widget is the root of your application.

  @override

  Widget build(BuildContext context) {

    return MaterialApp(

      debugShowCheckedModeBanner: false,

      title: 'Flutter Demo',

      theme: ThemeData(

        // This is the theme of your application.

        //

        // Try running your application with "flutter run". You'll see the

        // application has a blue toolbar. Then, without quitting the app, try

        // changing the primarySwatch below to Colors.green and then invoke

        // "hot reload" (press "r" in the console where you ran "flutter run",

        // or simply save your changes to "hot reload" in a Flutter IDE).

        // Notice that the counter didn't reset back to zero; the application

        // is not restarted.

        primarySwatch: Colors.blue,

      ),

      home: ImagePickerWidget(),

    );

  }

}

class ImagePickerWidget extends StatefulWidget {

  @override

  State<StatefulWidget> createState() {

    return _ImagePickerState();

  }

}

class _ImagePickerState extends State<ImagePickerWidget> {

  var _imgPath;

  List<XFile> imgArray = []; //这是个用来放照片的数组

//暂时先用XFile,还没有用File

  @override

  Widget build(BuildContext context) {

    return Scaffold(

        body: SingleChildScrollView(

            child: Container(

      height: 500,

      width: 400,

      child: Stack(

        children: [

          // _ImageView(imgPath: _imgPath),

          // _imageItem(imgpath: _imgPath),

          Center(

            //这是已选中的照片的显示

            child: imgArray.isNotEmpty

                ? Wrap(

                    spacing: 5,

                    runSpacing: 2,

                    children: imgArray

                        .map((item) => _imageItem(imgpath: item))

                        .toList(),

                  )

                : Text('您还没有添加图片'),

          ),

          Positioned(

            //这个是照相的按钮

            right: 10,

            bottom: 0,

            child: SizedBox(

              width: 50,

              height: 50,

              child: ClipOval(

                child: Container(

                  color: Colors.blue,

                  child: IconButton(

                    color: Colors.white,

                    onPressed: _showSheetAction, //下方弹出选择拍照还是相册的导航

                    icon: Icon(

                      Icons.photo_camera,

                      size: 30,

                    ),

                  ),

                ),

              ),

            ),

          ),

          // TextButton(

          //   onPressed: _takePhoto,

          //   child: Text("拍照"),

          // ),

          // TextButton(

          //   onPressed: _openGallery,

          //   child: Text("选择照片"),

          // ),

        ],

      ),

    )));

  }

  Widget _imageItem({required XFile imgpath}) {

    //已经可以显示了,但是如果不用list来显示的话删不掉图片

    //这是单个图片显示的组件

    return Stack(

      children: [

        ClipRRect(

            borderRadius: BorderRadius.circular(20),

            child: Container(

                height: 100,

                width: 100,

                child: Image.file(File(imgpath.path)) //这一步必须这么长,不然无法显示

                //主要关乎XFile和File的转化,还有一点点Image的

                )),

        Positioned(

          right: 5,

          top: 5,

          child: GestureDetector(

            onTap: () {

              setState(() {

                imgArray.remove(imgpath);

              });

            },

            child: ClipOval(

              child: Container(

                color: Colors.white.withOpacity(0.7),

                width: 20,

                height: 20,

                child: Icon(

                  Icons.close,

                  size: 20,

                ),

              ),

            ),

          ),

        ),

      ],

    );

  }

  /*拍照*/

  _takePhoto() async {

    Navigator.pop(context);

    var image = await _imagePicker.pickImage(source: ImageSource.camera);

    setState(() {

      _imgPath = image;

      print('在加入照片的时候,_imgPath类型是$_imgPath');

      // if (imgArray.length < 3) {

      imgArray.add(_imgPath); //不超过三个才能加入到照片数组中

      // }

    });

  }

  /*相册*/

  _openGallery() async {

    Navigator.pop(context);

    // var image = await _imagePicker.pickMultiImage();

    // var image = await _imagePicker.pickImage(

    //     source: ImageSource.gallery); //这个模式下可以一个一个加入,并且可以删除

    var image = await _imagePicker.pickMultiImage();

    setState(() {

      _imgPath = image;

      print('在加入照片的时候,_imgPath类型是$_imgPath');

      print('在加入照片的时候,image类型是$image  ,是XFile?');

      // if (imgArray.length < 3) {

      //   imgArray.add(_imgPath); //不超过三个才能加入到照片数组中

      // }

      if (imgArray.length + image.length <= 3)

        imgArray += image;

      else

        print('添加过多图片!');

    });

  }

  _showSheetAction() {

    showModalBottomSheet(

        context: context,

        builder: (context) => Container(

            height: 120,

            child: Column(

              children: [

                Expanded(

                  child: TextButton(

                      onPressed: () {

                        _takePhoto();

                      },

                      child: Container(

                        width: double.infinity,

                        height: double.infinity - 20,

                        child: Center(

                          child: Text(

                            '拍照',

                            style: TextStyle(color: Colors.black),

                          ),

                        ),

                      )),

                ),

                Divider(

                  height: 5,

                ),

                Expanded(

                  child: TextButton(

                      onPressed: () {

                        _openGallery();

                      },

                      child: Container(

                        width: double.infinity,

                        height: double.infinity - 20,

                        color: Colors.white24,

                        child: Center(

                          child: Text(

                            '从相册选取',

                            style: TextStyle(color: Colors.black),

                          ),

                        ),

                      )),

                )

              ],

            )));

  }

}


 

  // /*图片控件*/

  // Widget _ImageView({required XFile imgPath}) {

  //   if (imgPath == null) {

  //     return Center(

  //       child: Text("请选择图片或拍照"),

  //     );

  //   } else {

  //     print('imgPath的类型是 $imgPath');

  //     return Container(

  //         height: 50,

  //         width: 50,

  //         child: Image.file(File(imgPath.path)) //这一步必须这么长,不然无法显示

  //         );

  //   }

  // }

记得添加image_picker的依赖

或许还要dio的?不过都加上也无所谓

添加完依赖后,以上代码可以直接复制粘贴到main.dart文件中运行。

注意:个人设置了不能添加超过三个图片在页面中

借鉴了一下大佬的博客:

Flutter图片选择器——image_picker插件的使用 - 菠萝橙子丶 - 博客园

Flutter 图片选取 image_picker_nicepainkiller的博客-CSDN博客_flutter image_picker

Flutter从相册选择图片和相机拍照(image_picker)_XeonYu的博客-CSDN博客_flutter imagepicker

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
要实现异步请求网络数据并显示中demo,我们可以使用Flutter框架的http插件和状态管理来完成。 首先,我们需要在pubspec.yaml文件中添http插件的依赖。 ``` dependencies: flutter: sdk: flutter http: ^0.13.0 ``` 然后,在需要显示中的页面中,创建一个有状态的组件。在该组件的状态中定义一个布尔值isLoading来表示数据是否正在中。 ```dart import 'package:flutter/material.dart'; import 'package:http/http.dart' as http; import 'dart:convert'; class LoadingDemo extends StatefulWidget { @override _LoadingDemoState createState() => _LoadingDemoState(); } class _LoadingDemoState extends State<LoadingDemo> { bool isLoading = false; @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('Loading Demo'), ), body: Center( child: isLoading ? CircularProgressIndicator() : RaisedButton( child: Text('数据'), onPressed: () { fetchData(); }, ), ), ); } void fetchData() async { setState(() { isLoading = true; }); var response = await http.get('https://api.example.com/data'); if (response.statusCode == 200) { // 请求成功 var data = json.decode(response.body); // 处理数据 } else { // 请求失败 } setState(() { isLoading = false; }); } } ``` 在上述代码中,isLoading初始值为false,当点击数据按钮时,调用fetchData函数来请求数据。在请求数据时,将isLoading设置为true来显示动画,请求完成后再将其设置为false。 为了能够在Flutter显示动画,我们使用了CircularProgressIndicator小部件,它会在屏幕中间显示一个圆形的进度指示器。 通过上述代码,我们可以实现一个简单的中demo,用于异步请求网络数据并显示状态。当点击数据按钮时,会显示动画,请求完成后隐藏动画。只需简单几步即可实现这样的功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值