代码之家  ›  专栏  ›  技术社区  ›  user2233706

ListView小部件在缩放时不完全可见

  •  0
  • user2233706  · 技术社区  · 3 年前

    当我缩放水平 ListView 小部件,我观察到当小部件一直向右滚动时,只有一部分列表项可见:

    import 'dart:ui';
    
    import 'package:flutter/material.dart';
    
    void main() {
      runApp(MyApp());
    }
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        final sideLength = 50.0;
        final scale = 2.0;
    
        return MaterialApp(
            scrollBehavior: MyCustomScrollBehavior(),
            home: Scaffold(
                body: Transform.scale(
              scale: scale,
              alignment: Alignment(-1, -1),
              child: Container(
                  height: sideLength * scale,
                  child: ListView.builder(
                    itemCount: 20,
                    scrollDirection: Axis.horizontal,
                    itemBuilder: (context, index) => Container(
                        width: sideLength,
                        height: sideLength,
                        child: Text(index.toString()),
                        decoration: BoxDecoration(
                            border: Border.all(width: 3, color: Colors.red))),
                  )),
            )));
      }
    }
    
    class MyCustomScrollBehavior extends MaterialScrollBehavior {
      // Override behavior methods and getters like dragDevices
      @override
      Set<PointerDeviceKind> get dragDevices => {
            PointerDeviceKind.touch,
            PointerDeviceKind.mouse,
          };
    }
    

    在Pixel 2模拟器上,当我向右滚动时,只有前16个项目可见。例如

    enter image description here

    当刻度为1或如果 Transform.scale 小部件不在那里,所有20个项目都可见。

    我观察到以下行为:

    项目总数 最后一项可滚动到
    8. 4.
    10 6.
    20 16
    30 26
    50 46

    所以最后4项似乎总是被遗漏了。

    最终,我的目标是创建一个响应小部件,根据屏幕的尺寸进行缩放,所以我正在寻找一个通用的解决方案。

    自定义滚动行为仅用于在dartpad.dev上进行水平滚动,根据 this answer .

    0 回复  |  直到 3 年前
        1
  •  0
  •   Mhmd Zawi    3 年前

    使改变 只会影响孩子应该如何绘画。

    另一方面 规模 自变量乘以x轴和y轴。

    例如 :想象一下,一位摄影师正在拍摄一张包含一棵树的风景照片,现在如果摄影师离树更近,树的上部就会稍微离开照片。

    尝试添加 衬料 边缘 容器 并观察小部件如何受到 规模 . 然后你就会知道如何操作它。

    body: Transform.scale(
                  scale: scale,
                  alignment: Alignment(0, -5),
                  child: Container(
                      height: sideLength * scale,
                      margin: EdgeInsets.only(left: 100, right: 100),
                      child: ListView.builder(
    
        2
  •  0
  •   Dharman Aman Gojariya    3 年前

    此处的宽度和高度由 媒体查询

    小部件构建(BuildContext上下文){

    return MaterialApp(
        scrollBehavior: MyCustomScrollBehavior(),
        home: Scaffold(
            body: Transform.scale(
          scale: scale,
          alignment: Alignment(-1, -1),
          child: Container(
              height: sideLength * scale,
              child: ListView.builder(
                itemCount: 20,
                scrollDirection: Axis.horizontal,
                itemBuilder: (context, index) => Container(
                    width: MediaQuery.of(context).size.width*0.90 ,
                    height: MediaQuery.of(context).size.height*0.80 ,
                    child: Text(index.toString()),
                    decoration: BoxDecoration(
                        border: Border.all(width: 3, color: Colors.red))),
              )),
        )));
    

    }

        3
  •  0
  •   user2233706    3 年前

    我通过以下方式解决了这个问题:

    • 背景 itemCount 设置为比所需项目计数更高的值。这允许您滚动到中的最后一个所需项目 ListView
    • 有一个滚动控制器,用于检查您是否已超过视口中最后一个可见的所需项目。如果是,请跳到视口中最后一个可能的滚动偏移
    import 'dart:ui';
    
    import 'package:flutter/material.dart';
    
    void main() {
      runApp(MyApp());
    }
    
    class MyApp extends StatelessWidget {
      final ScrollController _scrollController = ScrollController();
      static const actualTotalItems = 20;
      static const sideLength = 50.0;
      static const scale = 2.0;
    
      MyApp() {
        _scrollController.addListener(() {
          if (_scrollController.offset > sideLength * actualTotalItems - _scrollController.position.viewportDimension / scale) {
            _scrollController.jumpTo(sideLength * actualTotalItems - _scrollController.position.viewportDimension / scale);
          }
        });
      }
    
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
            scrollBehavior: MyCustomScrollBehavior(),
            home: Scaffold(
                body: Container(
                    transform: Matrix4.diagonal3Values(scale, scale, 1),
                    height: sideLength * scale,
                    child: ListView.builder(
                        itemCount: actualTotalItems * 2,
                        scrollDirection: Axis.horizontal,
                        controller: _scrollController,
                        itemBuilder: (context, index) => Container(
                            width: sideLength,
                            height: sideLength,
                            child: Text(index.toString()),
                            decoration: BoxDecoration(border: Border.all(width: 3, color: Colors.red)))))));
      }
    }
    
    class MyCustomScrollBehavior extends MaterialScrollBehavior {
      // Override behavior methods and getters like dragDevices
      @override
      Set<PointerDeviceKind> get dragDevices => {
            PointerDeviceKind.touch,
            PointerDeviceKind.mouse,
          };
    }
    

    我使用缩放小部件 transform 中的属性 Container 有一个较小的小部件树,但这对解决方案没有影响。Transform小部件本可以像在OP中一样使用。