颤振-垂直拖动时更改高度

时间:2018-12-01 14:33:56

标签: android ios dart flutter

当前,我正在尝试开发一种扩展到特定大小的BottomSheet。达到该大小后,用户应该可以将BottomSheet向上拖动一点。我将GestureDetector嵌入了BottomSheet内,以便能够检测到垂直拖曳。拖动函数被调用,但是不幸的是它没有改变BottomSheet的大小。

这是我的代码:

//These values are outside of the classes
double initial;
double _kShoppingMenuHeight;


//My custom BottomSheet with rounded corner
Future<T> showRoundedBottomSheet<T> ({
  @required BuildContext context,
  @required Widget child,
  double height
}) {
  assert(context != null);
  assert(child != null);
  return showModalBottomSheet(          
    context: context,            
    builder: (BuildContext context){
      return new Container(
        height: (height != null
          ? height
          : 400.0
        ),
        color: Color(0xFF737373),            
        child: new Container(
          decoration: new BoxDecoration(
            color: Colors.white,
            borderRadius: new BorderRadius.only(
              topLeft: const Radius.circular(5.0),
              topRight: const Radius.circular(5.0)
            )
          ),
          child: Builder(
            builder: (BuildContext context){
              return child;
            },
          )
        ),
      );
    }
  );
}

//The function that opens the BottomSheet
// this is in another class
return showRoundedBottomSheet(
      context: context,
      height: _kShoppingMenuHeight,
      //Make bottomsheet draggable and fixed at specific point
      child: ShoppingMenu(
        title: _title("Ihre Listen"),
        items: items
      )
    );


//The stateful widget with the content
return GestureDetector(
      onVerticalDragStart: (DragStartDetails details){
        initial = details.globalPosition.dy;
      },
      onVerticalDragUpdate: (DragUpdateDetails details){

        setState(() {
          _kShoppingMenuHeight = MediaQuery.of(context).size.height / 2 - details.globalPosition.dy;
          if(_kShoppingMenuHeight.isNegative) _kShoppingMenuHeight = _kShoppingMenuHeight * (-1);
        });

      },
      onVerticalDragEnd: (DragEndDetails details){

      },
      child: NotificationListener<OverscrollIndicatorNotification>(
        onNotification: (overscroll){
          overscroll.disallowGlow();
        },        
        child: ConstrainedBox(
          constraints: BoxConstraints(
            minHeight: _kShoppingMenuHeight
          ),
          child: ListView( 
              physics: NeverScrollableScrollPhysics(),             
              children: <Widget>[
                Padding(
                  padding: EdgeInsets.only(top: 30.0, left: 10.0),
                  child: Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: <Widget>[
                      Padding(
                        padding: EdgeInsets.only(bottom: 10.0),
                        child: widget.title,
                      ),
                      Column(
                        children: widget.items
                      )
                    ],
                  ),
                ),
                Divider(),
                GestureDetector(
                  child: ListTile(
                    leading: Icon(Icons.add, color: Colors.black54),
                    title: Text(
                      "Neue Liste erstellen"
                    ),
                  ),            
                  onTap: (){
                    Navigator.pop(context, "neue Liste");
                  },
                ),
                Divider(),
                GestureDetector(
                  child: ListTile(
                    leading: Icon(OMIcons.smsFailed, color: Colors.black54),
                    title: Text(
                      "Feedback geben"
                    ),
                  ),            
                  onTap: (){
                    Navigator.pop(context, "feedback");
                  },
                )
              ],
            ),
        ),
      ),
    );

2 个答案:

答案 0 :(得分:2)

这是一个完整的示例,说明如何拖动模态底部工作表。

此想法是通过流构建器包装工作表的内容,并在发生拖动时更新流。让我知道您是否需要进一步的解释。

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

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('My App'),
        ),
        body: MyWidget(),
      ),
    );
  }
}

StreamController<double> controller = StreamController.broadcast();


class MyWidget extends StatefulWidget{
  @override
  _MyWidgetState createState() => _MyWidgetState();
}

class _MyWidgetState extends State<MyWidget>  {
  double position;
  @override
  Widget build(BuildContext context) {
    return Container(
      child: Center(
        child: RaisedButton(
            child: Text('Show Buttom Sheet'),
            onPressed: () {
              showModalBottomSheet(context: context, builder: (context){
                return StreamBuilder(
                  stream: controller.stream,
                  builder:(context,snapshot) => GestureDetector(
                    onVerticalDragUpdate: (DragUpdateDetails details){
                      position = MediaQuery.of(context).size.height- details.globalPosition.dy;
                      print('position dy = ${position}');

                      position.isNegative?Navigator.pop(context)

                      :controller.add(position);

                    },
                    behavior: HitTestBehavior.translucent,
                      child:
                      Container(
                    color: Colors.red,
                    height: snapshot.hasData ? snapshot.data:200.0,
                    width: double.infinity,
                    child: Text('Child'),
                  )),
                );

              });

            }),
      ),
    );
  }
}

答案 1 :(得分:0)

我认为setState()调用了错误的小部件。

setState()需要在包含脚手架的小部件上调用,因为底部表单属于脚手架本身。

继承的小部件可能是解决方案