dart 如何使PageView的高度取活动页面所需的高度?

bq3bfh9z  于 11个月前  发布在  其他
关注(0)|答案(2)|浏览(89)

Column中有一个PageView。这个PageView是一个块,它应该具有活动页面所需的最小高度。
例如,如果第一个页面的高度为300px,剩余的页面为500px,并且活动页面是第一个页面,那么PageView本身的高度应该为300px。
值得一提的是,为了让PageView存在于Column中,必须指定PageView的固定高度,否则Flutter SDK将抛出未绑定高度异常。
这样的行为是如何实现的?

iezvtpos

iezvtpos1#

**免责声明:**这是我对这个小挑战的(一小时)看法。可能有更好的解决方案来做到这一点,或者我没有考虑到一些事情。请确保测试好这个解决方案。如果其他读者发现了错误,请确保在评论中指出它,或者提出替代解决方案作为另一个答案。

我创建了一个通用的小部件来解决这个问题。它有两个限制,你需要注意:
1.如果你把一个不支持getDryLayout的小部件放到子对象中,它将不起作用。

  • 它为每个布局做两次子布局。如果你有更复杂的小部件(或者更确切地说是渲染对象)树,这个解决方案很可能对你来说不够好(性能)。
  • 对于第一次运行,它根据某个常数(_firstLayoutMaxHeight)将孩子放置在最大高度处,以便孩子可以告诉他们的大小。如果你的孩子比这个高,你需要相应地调整它(或者更好地找到一个更好,更集中的解决方案)。

如果你把问题缩小到某个特定的东西上,比如一个特定的图像页面视图,那么解决这个特定的问题就会容易得多。
下面是解决方案视频、它的用法和我编写的小部件(feel free to use it)的代码,沿着一些解释:
x1c 0d1x的数据

import 'dart:ui';

import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';

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

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

  @override
  State<Home> createState() => _HomeState();
}

class _HomeState extends State<Home> {
  final _controller = PageController();

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('PageView adaptive height'),
      ),
      body: Column(
        children: [
          PageViewHeightAdaptable(
            controller: _controller,
            children: [
              Container(height: 100, width: 50, color: Colors.red),
              Container(
                height: 300,
                color: Colors.green,
                child: const AspectRatio(
                  aspectRatio: 1,
                  child: Placeholder(),
                ),
              ),
              Container(height: 200, color: Colors.blue),
              Container(height: 400, color: Colors.red),
              Container(height: 600, color: Colors.blue),
            ],
          ),
          const FlutterLogo(),
        ],
      ),
    );
  }
}

个字符
是时候解释一下了
我在里面创建了一个PageView,它将它们各自的子节点放在堆栈中,其中SizedBox定义了子节点的大小,第二个Positioned是实际的PageView的子节点,用_SizeAware我收集孩子们想要的身高(来自无限高度约束下的干式布局)它被保存到一个map中。_SizingContainer在第一次运行时将子对象布局,导致回调被触发。map将根据子对象的大小进行更新。_SizingContainer有了这些新的尺寸,因为我们总是通过引用来修改和传递这个map。然后,我们第二次运行layout,这一次我们使用当前的滑动/动画页面的进度,并使用该进度在两个显示的子对象的尺寸之间进行线性插值,并使用插值作为子对象PageView的高度。

7bsow1i6

7bsow1i62#

像这样的?
https://imgur.com/gallery/RVypJZe
我使用了你的300,500值,页面在按钮上改变。我只是使用一个有状态的小部件来更新高度,我希望你能明白!

import 'package:flutter/material.dart';
import 'dart:math';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: MyStatefulWidget(),
    );
  }
}

class MyStatefulWidget extends StatefulWidget {
  @override
  _MyStatefulWidgetState createState() => _MyStatefulWidgetState();
}

class _MyStatefulWidgetState extends State<MyStatefulWidget> {
  List<double> pageViewHeights = List.generate(10, (index) => index == 0 ? 300.0 : 500.0);

  int currentIndex = 0;

  void updatePageViewHeight() {
    if (currentIndex < pageViewHeights.length - 1) {
      setState(() {
        currentIndex++;
      });
    } else {
      // Reset to the first index if we reach the end of the list
      setState(() {
        currentIndex = 0;
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('PageView Height Update'),
      ),
      body: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          Container(
            height: pageViewHeights[currentIndex],
            color: Colors.blue, // You can remove or customize the color as needed
            alignment: Alignment.center,
            child: Text(
              'Content for Index $currentIndex',
              style: TextStyle(color: Colors.white),
            ),
          ),
          SizedBox(height: 20.0),
          ElevatedButton(
            onPressed: updatePageViewHeight,
            child: Text('Next Page'),
          ),
        ],
      ),
    );
  }
}

字符串

相关问题