Flutter:长按图片可放大预览,如Instagram [英] Flutter: Long Press on picture to get zoomed preview like Instagram

查看:678
本文介绍了Flutter:长按图片可放大预览,如Instagram的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我当前有一个图片网格,并且我想实现instagram中的一项功能:如果长按其中一张图片,则会在屏幕中间显示该图片的较大版本。如果您停止按该按钮,图像就会消失。

so I am currently having a grid of pictures and I want to implement a feature from instagram: If you longPress on one of the pictures, you get a a larger version of that picture appearing in the middle of the screen. If you stop pressing, the image dissapears.

我确实不需要代码,但是我想不出应该使用哪个小部件。

I don't really need the code for that, but I just can't think of which widgets I should use.

也许有这样的包装吗?如果没有,我该如何使用Flutter标准小部件?也许使用了出现在longPress上的对话框?

Is there maybe a package for something like this? If not then how can I do it with Flutter standard widgets? Maybe using a dialog that appears on the longPress ?

推荐答案

以下是改进的版本,类似于与模糊的Instagram完全相同的用户体验

Here's the improved vewrsion that resembles the same exact UX as of Instagram with blurred background.

我们可以使用的组合来实现有状态的小工具 Stack BackdropFliter ,这是示例代码-

We can achieve this using a combination of Stateful Widget, Stack and BackdropFliter, here is the sample code -

import 'dart:ui';

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Counter Demo',
      theme: ThemeData.light(),
      home: Scaffold(
        appBar: AppBar(
          backgroundColor: Colors.blueGrey,
          centerTitle: true,
          title: Text("Demo App"),
        ),
        body: Stacked(),
      ),
    );
  }
}

class Stacked extends StatefulWidget {
  @override
  _StackedState createState() => _StackedState();
}

class _StackedState extends State<Stacked> {
  final List<String> images = [
    "1.jpg",
    "2.jpg",
    "3.jpg",
    "4.jpg",
    "5.jpg",
    "6.jpg",
    "7.jpg",
    "8.jpg",
    "9.jpg",
    "10.jpg",
  ];

  bool _showPreview = false;
  String _image = "assets/images/1.jpg";

  @override
  Widget build(BuildContext context) {
    return SafeArea(
        child: Stack(
      children: [
        GridView.builder(
          itemCount: images.length,
          gridDelegate:
              SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2),
          itemBuilder: (BuildContext context, int index) {
            return GestureDetector(
              onLongPress: () {
                setState(() {
                  _showPreview = true;
                  _image = "assets/images/${images[index]}";
                });
              },
              onLongPressEnd: (details) {
                setState(() {
                  _showPreview = false;
                });
              },
              child: Padding(
                padding: const EdgeInsets.all(4.0),
                child: Card(
                  elevation: 4,
                  shape: RoundedRectangleBorder(
                    borderRadius: BorderRadius.circular(5.0),
                  ),
                  clipBehavior: Clip.hardEdge,
                  child: Image.asset("assets/images/${images[index]}"),
                ),
              ),
            );
          },
        ),
        if (_showPreview) ...[
          BackdropFilter(
            filter: ImageFilter.blur(
              sigmaX: 5.0,
              sigmaY: 5.0,
            ),
            child: Container(
              color: Colors.white.withOpacity(0.6),
            ),
          ),
          Container(
            child: Center(
              child: ClipRRect(
                borderRadius: BorderRadius.circular(10.0),
                child: Image.asset(
                  _image,
                  height: 300,
                  width: 300,
                ),
              ),
            ),
          ),
        ],
      ],
    ));
  }
}

这只是一个基线示例,您可以无限制地修改它

This is just a baseline example and there are endless possibilities you can modify this to achieve behavior you want.

另一种简单方法是我们可以使用StatefulWidget和IndexedStack来构建它-

Another simple way is we can build this by using StatefulWidget and IndexedStack -

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Counter Demo',
      theme: ThemeData.light(),
      home: Scaffold(
        appBar: AppBar(
          backgroundColor: Colors.blueGrey,
          centerTitle: true,
          title: Text("Demo App"),
        ),
        body: Body(),
      ),
    );
  }
}

class Body extends StatefulWidget {
  @override
  _BodyState createState() => _BodyState();
}

class _BodyState extends State<Body> {
  final List<String> images = [
    "1.jpg",
    "2.jpg",
    "3.jpg",
    "4.jpg",
    "5.jpg",
    "6.jpg",
    "7.jpg",
    "8.jpg",
    "9.jpg",
    "10.jpg",
  ];

  int _index = 0;
  String _image = "assets/images/1.jpg";

  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: IndexedStack(
        index: _index,
        children: [
          GridView.builder(
            itemCount: images.length,
            gridDelegate:
                SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2),
            itemBuilder: (BuildContext context, int index) {
              return GestureDetector(
                onLongPress: () {
                  setState(() {
                    _index = 1;
                    _image = "assets/images/${images[index]}";
                  });
                },
                onLongPressEnd: (details) {
                  setState(() {
                    _index = 0;
                  });
                },
                child: Padding(
                  padding: const EdgeInsets.all(4.0),
                  child: Card(
                    elevation: 4,
                    shape: RoundedRectangleBorder(
                      borderRadius: BorderRadius.circular(5.0),
                    ),
                    clipBehavior: Clip.hardEdge,
                    child: Image.asset("assets/images/${images[index]}"),
                  ),
                ),
              );
            },
          ),
          Container(
            decoration: BoxDecoration(
              color: Colors.white.withOpacity(0.2),
            ),
            child: Center(
              child: ConstrainedBox(
                constraints: BoxConstraints(
                  maxHeight: 400,
                  maxWidth: 400,
                ),
                child: Image.asset(
                  _image,
                ),
              ),
            ),
          )
        ],
      ),
    );
  }
}

您可以检查上述代码的输出此处

You can check output for above code here.

这篇关于Flutter:长按图片可放大预览,如Instagram的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆