颤振-垂直拖动时更改高度 [英] Flutter - Change Height on vertical drag

查看:92
本文介绍了颤振-垂直拖动时更改高度的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Currently I am trying to develop a BottomSheet that expands to a specific size. When that size is reached, the user should be able to drag the BottomSheet a little bit up. I have implmented the GestureDetector inside the BottomSheet, so that I am able to detect a vertical drag. The drag function is called, but unfortunately it is not changing the size of the 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");
                  },
                )
              ],
            ),
        ),
      ),
    );


推荐答案

这是如何拖动的完整示例

This is a complete example of how you can drag around with your modal bottom sheet.

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

The idea is to wrap the content of the sheet by a stream builder ,and update the stream when drag occurs. let me know if you need further explanation.

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'),
                  )),
                );

              });

            }),
      ),
    );
  }
}

这篇关于颤振-垂直拖动时更改高度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆