Flutter

Flutter 控件高度动态变化(Container)

2020-08-06  本文已影响0人  fordG
@override
  Widget build(BuildContext context) {
    print("HeightReporterBuild");
    Widget tmp = new GestureDetector(
      child: child,
      onTap: () {
        print('Height is ${context.size.height}');
      },
    );

    Future.delayed(Duration(milliseconds: 200)).then((e) {
      _height = context.size.height;
      debugPrint('Height is ${context.size.height}');
    });

    return tmp;
  }

通过上面的代码测试发现,如果外层组件设置了高度, 那么获取的组件的高度就是外层设置的高度, 因为我们需要动态的高度,如果没有设置高度就可以准确的获取到组件的高度, 但是我的需求里面一开始必须是一个固定的高度, 如果按照这个来做的话, 一开始就完全展开然后缩回去变成固定高度, 不太那个

所以我变化了一下思路, 我们在container里面放了一个SingleChildScrollView把组件放到了滚动组件里面, 然后不让SingleChildScrollView滚动, 主要的问题在这里, 在SingleChildScrollView里面外层的组件设置了高度,SingleChildScrollView也可以获取到你想要的组件的高度,这就解决了一开始固定高度, 还可以获取到你想要展示的组件的高度, 然后通过点击事件取改变animation来改变container的高度,达到上面的效果

import 'package:flutter/material.dart';
import 'package:CutDown/height_reporter.dart';

GlobalKey<_CutDownWidgetState> cutDownWidgetKey = GlobalKey();
// ignore: must_be_immutable
class CutDownWidget extends StatefulWidget{
  double defaultHeight;
  Widget child;

  CutDownWidget({Key key, this.defaultHeight, this.child}) : super(key: key);
  @override
  _CutDownWidgetState createState() => _CutDownWidgetState();
}

class _CutDownWidgetState extends State<CutDownWidget> with SingleTickerProviderStateMixin{

  AnimationController animationController;
  Animation animation;
  Animation curve;
  ScrollController scrollController;
  double reallyHeight;
  HeightReporter childCopy;
  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    scrollController = ScrollController();
    animationController = AnimationController(
        duration: const Duration(milliseconds: 300), vsync: this);
    curve = new CurvedAnimation(parent: animationController, curve: Curves.easeInOut);
    animation = new Tween(begin: widget.defaultHeight, end: reallyHeight).animate(curve);
  }

  widgetCutDown(){

    if(reallyHeight == null){
      print(childCopy.getHeight().toString());
      reallyHeight = childCopy.getHeight();
      animation = new Tween(begin: widget.defaultHeight, end: reallyHeight).animate(curve)..addListener(() {
        setState(()=>{});
      });
    }
    if(animation.value == widget.defaultHeight){
      animationController.forward();
    }else{
      animationController.reverse();
    }

    /*if(animation.value == widget.defaultHeight){

    }else{
      animationController.reverse();
    }*/
  }

  @override
  Widget build(BuildContext context) {
    if(childCopy == null){
      childCopy = HeightReporter(child: widget.child);
    }
    return ClipRRect(
      borderRadius: BorderRadius.circular(10),
      child: Container(
        height: animation.value,
        child: SingleChildScrollView(
          child: childCopy,
          physics: NeverScrollableScrollPhysics(),
          controller: scrollController,
        ),
      ),
    );
  }
}

import 'package:flutter/material.dart';

class HeightReporter extends StatelessWidget {
  final Widget child;

  HeightReporter({this.child});

  double _height;

  double getHeight() {
    return _height;
  }


  @override
  Widget build(BuildContext context) {
    print("HeightReporterBuild");
    Widget tmp = new GestureDetector(
      child: child,
      onTap: () {
        print('Height is ${context.size.height}');
      },
    );

    Future.delayed(Duration(milliseconds: 200)).then((e) {
      _height = context.size.height;
      debugPrint('Height is ${context.size.height}');
    });

    return tmp;
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

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

class _MyHomePageState extends State<MyHomePage> {
  String leadText = "展开";
  CutDownWidget cutDownWidget;
  double defaultHeight = 80.0;
  @override
  Widget build(BuildContext context) {
    if (cutDownWidget == null) {
      cutDownWidget = _cutDown();
    }
    return Scaffold(
        appBar: AppBar(
          title: Text(widget.title),
          actions: [
            GestureDetector(
              onTap: () {
                cutDownWidgetKey.currentState.widgetCutDown();
              },
              child: Container(
                alignment: Alignment.center,
                height: 44,
                width: 44,
                child: Text(leadText),
              ),
            )
          ],
        ),
        body: SingleChildScrollView(
          child: Column(
            children: [
              Container(
                margin: EdgeInsets.all(15),
                child: cutDownWidget,
              ),
              Container(
                height: 1000,
              )
            ],
          ),
        ));
  }

  Widget _cutDown(){
    return CutDownWidget(
      key: cutDownWidgetKey,
      defaultHeight: defaultHeight,
      child:  Container(
        child: Column(
          children: [
            Container(
              color: Colors.red,
              child: Padding(
                padding: EdgeInsets.all(30),
                child: Text("CutDownWidgetCutDownWidgetCutDownWidgetCutDownWidgetCutDownWidgetCutDownWidgetCutDownWidgetCutDownWidgetCutDownWidgetCutDownWidgetCutDownWidgetCutDownWidgetCutDownWidgetCutDownWidgetCutDownWidgetCutDownWidget"),
              ),
            )
          ],
        ),
      ),

    );
  }
}
上一篇下一篇

猜你喜欢

热点阅读