欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Flutter自適用高度PageView的實現(xiàn)方案

 更新時間:2024年08月19日 09:19:47   作者:一笑輪回~  
在?Flutter?中,PageView?是一個非常常用的組件,能夠?qū)崿F(xiàn)多個頁面的滑動切換,這篇文章主要介紹了Flutter-自適用高度PageView,需要的朋友可以參考下

需求

在 Flutter 中,PageView 是一個非常常用的組件,能夠?qū)崿F(xiàn)多個頁面的滑動切換。然而,默認(rèn)的 PageView 高度是固定的,這在展示不同高度的頁面時,可能會導(dǎo)致不必要的空白或內(nèi)容裁剪問題。為了使 PageView 能夠根據(jù)每個頁面的內(nèi)容高度動態(tài)調(diào)整,我們需要一個自適應(yīng)高度的 PageView 實現(xiàn)。

效果

本方案的 PageView 可以根據(jù)每個頁面內(nèi)容的高度自動調(diào)整,保證每個頁面的內(nèi)容在其實際高度內(nèi)完整顯示,并且在頁面滑動時,使用平滑的過渡效果。具體來說:

  • 每個頁面的內(nèi)容高度不同,PageView 能夠動態(tài)調(diào)整高度。
  • 頁面切換時,高度變化平滑,不會造成突兀的視覺效果。

實現(xiàn)思路

1. 測量每個頁面的高度

首先,我們需要為每個頁面添加一個高度測量的機(jī)制,測量頁面內(nèi)容的高度。在 Flutter 中,我們可以通過 GlobalKeyRenderBox 獲取每個 Widget 的實際高度。

2. 動態(tài)調(diào)整 PageView 高度

在頁面滑動時,我們需要根據(jù)滑動的進(jìn)度動態(tài)計算當(dāng)前 PageView 的高度。這就需要在 PageView 的滑動過程中實時更新高度,使得高度隨滑動位置逐步過渡。

3. 動態(tài)高度過渡

我們可以使用 AnimatedContainer 來平滑過渡 PageView 的高度,避免切換時高度變化過于突兀。通過監(jiān)聽 PageView 的滑動狀態(tài),實時調(diào)整容器高度。

實現(xiàn)代碼

1. 高度測量組件 HeightMeasureWidget

這個組件負(fù)責(zé)測量每個頁面的高度,并將測量結(jié)果通過回調(diào)傳遞出去。

import 'package:flutter/material.dart';
class HeightMeasureWidget extends StatefulWidget {
  final Widget child;
  final Function(double height) onHeightChanged;
  const HeightMeasureWidget(
      {super.key, required this.child, required this.onHeightChanged});
  @override
  HeightMeasureState createState() => HeightMeasureState();
}
class HeightMeasureState extends State<HeightMeasureWidget> {
  final GlobalKey _key = GlobalKey();
  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addPostFrameCallback((_) {
      _measureHeight();
    });
  }
  void _measureHeight() {
    final RenderBox? renderBox =
        _key.currentContext!.findRenderObject() as RenderBox?;
    if (renderBox != null) {
      widget.onHeightChanged(renderBox.size.height);
    }
  }
  @override
  Widget build(BuildContext context) {
    return Container(
      key: _key,
      child: widget.child,
    );
  }
}

2. 自適應(yīng)高度的 AutoHeightPageView

這個組件使用了前面創(chuàng)建的 HeightMeasureWidget 來測量每個頁面的高度,然后根據(jù)滑動進(jìn)度調(diào)整高度。

import 'package:flutter/material.dart';
import 'measure_height_widget.dart';
class AutoHeightPageView extends StatefulWidget {
  final List<Widget> children;
  final PageController pageController;
  const AutoHeightPageView({
    Key? key,
    required this.children,
    required this.pageController,
  }) : super(key: key);
  @override
  AutoHeightPageViewState createState() => AutoHeightPageViewState();
}
class AutoHeightPageViewState extends State<AutoHeightPageView> {
  final List<double> _heights = [];
  double _currentHeight = 0;
  @override
  void initState() {
    super.initState();
    widget.pageController.addListener(_updateHeight);
  }
  void _updateHeight() {
    if (widget.pageController.position.haveDimensions && _heights.isNotEmpty) {
      double page = widget.pageController.page ?? 0.0;
      int index = page.floor();
      int nextIndex = (index + 1) < _heights.length ? index + 1 : index;
      double percent = page - index;
      double height =
          _heights[index] + (_heights[nextIndex] - _heights[index]) * percent;
      setState(() {
        _currentHeight = height;
      });
    }
  }
  @override
  Widget build(BuildContext context) {
    var isMeasureHeight =
        _heights.length == widget.children.length ? false : true;
    return Column(
      children: [
        Stack(
          children: [
            Visibility(
              visible: isMeasureHeight,
              child: Stack(
                children: widget.children
                    .map((e) => HeightMeasureWidget(
                          child: e,
                          onHeightChanged: (height) {
                            _heights.add(height);
                            if (_heights.length == widget.children.length) {
                              setState(() {
                                _currentHeight = _heights[0];
                              });
                            }
                          },
                        ))
                    .toList(),
              ),
            ),
            if (!isMeasureHeight)
              AnimatedContainer(
                duration: const Duration(milliseconds: 200),
                height: _currentHeight,
                curve: Curves.easeOut,
                child: PageView(
                  controller: widget.pageController,
                  children: widget.children,
                ),
              ),
          ],
        )
      ],
    );
  }
  @override
  void dispose() {
    widget.pageController.dispose();
    super.dispose();
  }
}

3. 使用示例 AutoHeightPageViewPage

該頁面演示了如何使用自適應(yīng)高度的 PageView,通過內(nèi)容高度的動態(tài)調(diào)整,確保 PageView 始終適應(yīng)當(dāng)前頁面的高度。

import 'package:flutter/material.dart';
import 'package:flutter_xy/r.dart';
import 'package:flutter_xy/xydemo/vp/pageview/auto_height_page_view.dart';
class AutoHeightPageViewPage extends StatefulWidget {
  const AutoHeightPageViewPage({Key? key}) : super(key: key);
  @override
  State<StatefulWidget> createState() => AutoHeightPageViewState();
}
class AutoHeightPageViewState extends State<AutoHeightPageViewPage> {
  final PageController _pageController = PageController();
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('自適用高度PageView'),
      ),
      body: Container(
        color: Colors.white,
        child: SingleChildScrollView(
          child: Column(
            children: [
              AutoHeightPageView(
                pageController: _pageController,
                children: [
                  Container(
                    color: Colors.white,
                    child: ListView(
                      shrinkWrap: true,
                      physics: const NeverScrollableScrollPhysics(),
                      children: [
                        Container(
                          color: Colors.red,
                          height: 50,
                          alignment: Alignment.center,
                          child: const Text("第一個界面"),
                        ),
                        Container(
                          color: Colors.yellow,
                          height: 50,
                          alignment: Alignment.center,
                          child: const Text("第一個界面"),
                        ),
                        Container(
                          color: Colors.blue,
                          height: 50,
                          alignment: Alignment.center,
                          child: const Text("第一個界面"),
                        ),
                      ],
                    ),
                  ),
                  Container(
                      color: Colors.green,
                      height: 250,
                      child: const Center(child: Text('第二個界面'))),
                ],
              ),
              Image.asset(
                R.vp_content_jpg,
                width: MediaQuery.of(context).size.width,
                fit: BoxFit.fill,
              ),
            ],
          ),
        ),
      ),
    );
  }
}

總結(jié)

通過本方案,我們實現(xiàn)了一個自適應(yīng)高度的 PageView,它能夠根據(jù)每個頁面的內(nèi)容高度進(jìn)行動態(tài)調(diào)整。該實現(xiàn)依賴于對每個頁面內(nèi)容的測量,并使用 AnimatedContainer 來平滑地過渡高度變化。這樣可以確保頁面切換時,用戶體驗更加自然流暢,避免了內(nèi)容被裁剪或空白區(qū)域的出現(xiàn)。這種自適應(yīng)高度的 PageView 非常適合用于不同頁面內(nèi)容高度不一致的場景。

詳情:github.com/yixiaolunhui/flutter_xy

到此這篇關(guān)于Flutter自適用高度PageView的實現(xiàn)方案的文章就介紹到這了,更多相關(guān)Flutter PageView內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論