fluttercandies / extended_image

A powerful official extension library of image, which support placeholder(loading)/ failed state, cache network, zoom pan image, photo view, slide out page, editor(crop,rotate,flip), paint custom etc.
https://fluttercandies.github.io/extended_image/
MIT License
1.92k stars 502 forks source link

[Discussions] Swiping left and right pictures is not smooth #687

Closed Latrevion closed 2 weeks ago

Latrevion commented 3 months ago

Content

Version

extended_image: 8.2.1

Problems

I used this plugin to do the image preview function. But when I found that when I slid, the response was not timely. Swiping left and right is difficult

Platforms

Android 13

Device Model

Redmi Note 12T Pro

flutter info

[!] Flutter (Channel stable, 3.19.6, on Microsoft Windows [版本 10.0.22631.2428], locale zh-CN)
    ! Warning: `flutter` on your path resolves to C:\Users\admin\fvm\versions\3.19.6\bin\flutter, which is not inside
      your current Flutter SDK checkout at C:\Users\admin\fvm\default. Consider adding C:\Users\admin\fvm\default\bin to
      the front of your path.
    ! Warning: `dart` on your path resolves to C:\Users\admin\fvm\versions\3.19.6\bin\dart, which is not inside your
      current Flutter SDK checkout at C:\Users\admin\fvm\default. Consider adding C:\Users\admin\fvm\default\bin to the
      front of your path.
[√] Windows Version (Installed version of Windows is version 10 or higher)
[√] Android toolchain - develop for Android devices (Android SDK version 34.0.0)
[√] Chrome - develop for the web
[√] Visual Studio - develop Windows apps (Visual Studio Community 2022 17.7.3)
[√] Android Studio (version 2023.1)
[√] IntelliJ IDEA Community Edition (version 2023.2)
[√] Connected device (4 available)
[√] Network resources

demo

this is a demo about extended_image. It shows that swiping left on the image, or swiping right on the image is not smooth https://github.com/Latrevion/flutter_extended_image_demo

Example code

chat_picture_preview.dart

import 'package:extended_image/extended_image.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';

class ChatPicturePreview extends StatefulWidget {
  const ChatPicturePreview({
    super.key,
    this.currentIndex = 0,
    this.images = const [],
    this.heroTag,
    this.onTap,
    this.onLongPress,
  });

  final int currentIndex;
  final List<String> images;
  final String? heroTag;
  final Function()? onTap;
  final Function(String url)? onLongPress;

  @override
  ChatPicturePreviewState createState() => ChatPicturePreviewState();
}

class ChatPicturePreviewState extends State<ChatPicturePreview> {
  late final ExtendedPageController? controller;

  @override
  void initState() {
    super.initState();
    controller = widget.images.length > 1
        ? ExtendedPageController(
            initialPage: widget.currentIndex, pageSpacing: 50)
        : null;
  }

  @override
  void dispose() async {
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    final systemPadding = MediaQuery.of(context).padding;
    return Padding(
      padding: systemPadding,
      child: ExtendedImageSlidePage(
        slideAxis: SlideAxis.vertical,
        slidePageBackgroundHandler: (offset, pageSize) =>
            defaultSlidePageBackgroundHandler(
          color: Colors.black,
          offset: offset,
          pageSize: pageSize,
        ),
        child: MetaHero(
          heroTag: widget.heroTag,
          onTap: widget.onTap ?? () => Get.back(),
          onLongPress: () {
            final index = controller?.page?.round() ?? 0;
            widget.onLongPress?.call(widget.images[index]);
          },
          child: _childView,
        ),
      ),
    );
  }

  Widget get _childView {
    return widget.images.length == 1
        ? _networkGestureImage(widget.images[0])
        : _pageView;
  }

  Widget get _pageView => ExtendedImageGesturePageView.builder(
        controller: controller,
        onPageChanged: (int index) {},
        itemCount: widget.images.length,
        itemBuilder: (BuildContext context, int index) {
          return _networkGestureImage(widget.images.elementAt(index));
        },
      );

  Widget _networkGestureImage(String url) => ExtendedImage.network(
        url,
        fit: BoxFit.contain,
        mode: ExtendedImageMode.gesture,
        clearMemoryCacheWhenDispose: true,
        clearMemoryCacheIfFailed: true,
        handleLoadingProgress: true,
        enableSlideOutPage: false,
        onDoubleTap: (ExtendedImageGestureState state) async {},
        initGestureConfigHandler: (ExtendedImageState state) {
          return GestureConfig(
            minScale: 1,
            animationMinScale: 1,
            inPageView: true,
            initialScale: 1.0,
            maxScale: 5.0,
            animationMaxScale: 6.0,
            speed: 1,
            inertialSpeed: 600.0,
            initialAlignment: InitialAlignment.center,
          );
        },
        loadStateChanged: (ExtendedImageState state) {
          switch (state.extendedImageLoadState) {
            case LoadState.loading:
              {
                final ImageChunkEvent? loadingProgress = state.loadingProgress;
                final double? progress =
                    loadingProgress?.expectedTotalBytes != null
                        ? loadingProgress!.cumulativeBytesLoaded /
                            loadingProgress.expectedTotalBytes!
                        : null;

                return SizedBox(
                  width: 15.0,
                  height: 15.0,
                  child: Center(
                    child: CircularProgressIndicator(
                      color: const Color(0xffE8B339),
                      strokeWidth: 1.5,
                      value: progress ?? 0,
                    ),
                  ),
                );
              }
            case LoadState.completed:
              return null;
            case LoadState.failed:
              state.imageProvider.evict();
              return null;
          }
        },
      );
}

class MetaHero extends StatelessWidget {
  const MetaHero({
    Key? key,
    required this.heroTag,
    required this.child,
    this.onTap,
    this.onLongPress,
  }) : super(key: key);
  final Widget child;
  final String? heroTag;
  final Function()? onTap;
  final Function()? onLongPress;

  @override
  Widget build(BuildContext context) {
    final view = GestureDetector(
      behavior: HitTestBehavior.translucent,
      onTap: onTap,
      onLongPress: onLongPress,
      child: child,
    );
    return heroTag == null ? view : Hero(tag: heroTag!, child: view);
  }
}

main.dart

import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:extended_image_demo/widgets/chat_picture_preview.dart';

void main() {
  runApp(const GetMaterialApp(
    home: Home(),
  ));
}

class Controller extends GetxController {
  List<String> pictureUrls = [
    'https://img.zcool.cn/community/010d5c5b9d17c9a8012099c8781b7e.jpg@1280w_1l_2o_100sh.jpg',
    'https://boot-img.xuexi.cn/image/1006/process/b5e3a02d382649ff8565323f48320b36.jpg',
    'https://ts1.cn.mm.bing.net/th/id/R-C.d2b3a4779fd2b9af70103d485bc8b664?rik=Xm7zutXMpsp91Q&riu=http%3a%2f%2fup.deskcity.org%2fpic_source%2fd2%2fb3%2fa4%2fd2b3a4779fd2b9af70103d485bc8b664.jpg&ehk=%2fh%2fipXq8Ihn81SbQdkphnzweLFLUGfD1%2fXncDcbLgRE%3d&risl=&pid=ImgRaw&r=0',
    'https://img.zcool.cn/community/011f205c1df754a8012029ac2b3998.jpg@3000w_1l_0o_100sh.jpg',
    'https://tse4-mm.cn.bing.net/th/id/OIP-C.ISBPvQsr4cj54OhIP0dPpwHaLG?w=115&h=180&c=7&r=0&o=5&pid=1.7',
    'https://img.zcool.cn/community/0104d155fdc4416ac7251df855d682.jpg@3000w_1l_0o_100sh.jpg',
    'https://img.cgmol.com/excellentwork/20150729/191501_20150729103856ql7wk9qchh2lijy.jpg',
    'https://bpic.588ku.com/back_pic/06/11/77/75621df811753bb.jpg',
    'https://scpic.chinaz.net/files/pic/pic9/202009/apic27883.jpg',
    'https://img.tukuppt.com/ad_preview/00/18/86/5c99f1b30e47d.jpg!/fw/780',
    'https://img.zcool.cn/community/0104d155fdc4416ac7251df855d682.jpg@1280w_1l_2o_100sh.jpg',
    'https://ts1.cn.mm.bing.net/th/id/R-C.0bd5ff90452c9181a68df772e16cca47?rik=FbE%2bGrVs0MiStg&riu=http%3a%2f%2fpic.bizhi360.com%2fbbpic%2f43%2f10143.jpg&ehk=QmTn7S8Mfd4QeGCNl0mfbU%2bnxGEAMNe5YQeg4kKBIrE%3d&risl=&pid=ImgRaw&r=0',
    'https://pic.616pic.com/bg_w1180/00/00/81/zi58oHApHm.jpg!/fw/880',
    'https://img-baofun.zhhainiao.com/pcwallpaper_ugc_mobile/preview_jpg/81cfd45f881b9ef4721d552e5a78d196.jpg',
    'https://bpic.588ku.com/back_pic/06/09/78/78616e9763b39e4.jpg'
  ];

  //Preview the images
  void previewUrlPicture(
    List<String> urls, {
    int currentIndex = 0,
    String? heroTag,
    context,
  }) =>
      navigator
          ?.push(MaterialPageRoute(
        builder: (BuildContext context) => GestureDetector(
          onTap: () {
            Get.back();
          },
          child: ChatPicturePreview(
            currentIndex: currentIndex,
            images: urls,
            heroTag: heroTag,
            onLongPress: (pictureUrl) {
              //Do nothing
            },
          ),
        ),
      ))
          .then((value) {
        //Do nothing
      });
}

class Home extends StatelessWidget {
  const Home({super.key});

  @override
  Widget build(context) {
    final Controller c = Get.put(Controller());

https://github.com/fluttercandies/extended_image/assets/80438697/d0b808ae-32f2-487e-a6a7-f5b729dc6053

    return Scaffold(
        appBar: AppBar(title: const Center(child: Text('previews picture'))),
        body: Center(
          child: ElevatedButton(
            child: const Text("preview pictures"),
            onPressed: () {
              c.previewUrlPicture(c.pictureUrls);
            },
          ),
        ));
  }
}

https://github.com/fluttercandies/extended_image/assets/80438697/c21c7c94-57c9-40c3-99c4-fa75ae5c5689

jwlim94 commented 3 months ago

I see the same thing. IOS 17

Latrevion commented 2 months ago

I see the same thing. IOS 17

Do you have a solution?

zmtzawqlp commented 2 weeks ago

please update to lastest version