简体   繁体   中英

Nested Gesture Does not change on Tap

I am currently working on the ui stuff for the appliction, so the thing is i have one gesture as a parent that swipes up and down and based on it the position of the widgets gets changed but the problem is the child gesture does not get any precedence when tapped on it it gives the precedence. So my tree structure is Pageview.builder which has single widget with topmost parent as Gesturedetector and the children accrodingly, Can any one tell me what i am doing wrong or any improvements to get the gesture for each. Below is the sample code that i have been working on:

import 'dart:math';
import 'package:LocationAnimation/Model/device_model.dart';
import 'package:LocationAnimation/SplashPage/splash_page.dart';
import 'package:LocationAnimation/widgets/device_function_widget.dart';

import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:google_fonts/google_fonts.dart';

import 'Model/device_model.dart' as devices;
import 'Model/locations_model.dart' as locations;
import 'extensions/capitalize.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'HAL',
      home: MyHomePage(),
    );
  }
}

class SampleList {
  final String locationName;

  SampleList({this.locationName});
}

class MyHomePage extends StatefulWidget {
  @override
  State createState() => new MyHomePageState();
}

class MyHomePageState extends State<MyHomePage> with TickerProviderStateMixin {
  final _controller = new PageController();

  final _kArrowColor = Colors.black.withOpacity(0.8);

  bool _isSwipe = false;
  bool _isLoading = false;

  var list = [
    SampleList(locationName: 'Living Room'),
    SampleList(locationName: 'Bed Room'),
    SampleList(locationName: 'Back Porch Lights'),
    SampleList(locationName: 'Basement Porch Lights'),
    SampleList(locationName: 'Sample Room'),
  ];

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      body: new IconTheme(
        data: new IconThemeData(color: _kArrowColor),
        child: new Stack(
          children: <Widget>[
            new PageView.builder(
              physics: _isSwipe
                  ? NeverScrollableScrollPhysics()
                  : AlwaysScrollableScrollPhysics(),
              controller: _controller,
              itemCount: list.length,
              itemBuilder: (BuildContext context, int index) {
                return LocationDetails(
                  isLoading: _isLoading,
                  item: list[index],
                  onSwipeDown: () {
                    setState(() {
                      _isSwipe = false;
                    });
                  },
                  onSwipeUp: () {
                    setState(() {
                      _isSwipe = true;
                    });
                  },
                );
              },
            ),
          ],
        ),
      ),
    );
  }
}

class LocationDetails extends StatefulWidget {
  final bool isLoading;
  SampleList item;
  final Function() onSwipeUp;
  final Function() onSwipeDown;
  LocationDetails(
      {Key key, this.item, this.onSwipeUp, this.onSwipeDown, this.isLoading})
      : super(key: key);

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

class _LocationDetailsState extends State<LocationDetails> {
  DragStartDetails startVerticalDragDetails;
  DragUpdateDetails updateVerticalDragDetails;
  bool moveWidget = false;
  bool dismissSwipeText = true;

  bool _isRotate = false;
  int currentSelectedIndex = 0;
  bool ignoreChildGestures = true;
  bool _isSwpie = false;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: Container(
          child: GestureDetector(
            onTap: () {
              print('Tap');
            },
            onVerticalDragStart: (dragDetails) {
              startVerticalDragDetails = dragDetails;
            },
            onVerticalDragUpdate: (dragDetails) {
              updateVerticalDragDetails = dragDetails;
            },
            onVerticalDragEnd: (endDetails) {
              double dx = updateVerticalDragDetails.globalPosition.dx -
                  startVerticalDragDetails.globalPosition.dx;
              double dy = updateVerticalDragDetails.globalPosition.dy -
                  startVerticalDragDetails.globalPosition.dy;
              double velocity = endDetails.primaryVelocity;

              //Convert values to be positive
              if (dx < 0) dx = -dx;
              if (dy < 0) dy = -dy;

              if (velocity < 0) {
                widget.onSwipeUp();
                print('drag up');

                setState(() {
                  moveWidget = true;
                  _isSwpie = true;
                });
              } else {
                widget.onSwipeDown();
                print(' drag down');
                setState(() {
                  moveWidget = false;
                  _isSwpie = false;
                });
              }
            },
            child: Container(
                height: MediaQuery.of(context).size.height,
                width: MediaQuery.of(context).size.width,
                decoration: new BoxDecoration(
                  image: new DecorationImage(
                    colorFilter: ColorFilter.mode(
                        Colors.black.withOpacity(0.8), BlendMode.srcOver),
                    image: /* moveWidget
                              ? */
                        AssetImage(
                      'Assets/backgroundImage.jpg',
                    ),
                    /*  : NetworkImage(widget.samplePage.networkImage), */
                    fit: BoxFit.fill,
                  ),
                ),
                child:
                    /*  widget.isLoading
                    ? Center(
                        child: CircularProgressIndicator(),
                      )
                    : */
                    Stack(
                  children: <Widget>[
                    AnimatedOpacity(
                      opacity: moveWidget ? 0 : 1,
                      duration: Duration(microseconds: 100),
                      child: Padding(
                        padding: const EdgeInsets.all(20.0),
                        child: Row(
                          mainAxisAlignment: MainAxisAlignment.spaceBetween,
                          children: <Widget>[
                            Column(
                              children: <Widget>[
                                Icon(
                                  Icons.power_settings_new,
                                  color: Colors.white,
                                  size: 30,
                                ),
                                Icon(
                                  Icons.more_horiz,
                                  color: Colors.white,
                                  size: 25,
                                )
                              ],
                            ),
                            Row(
                              children: <Widget>[
                                Column(
                                  children: <Widget>[
                                    Text(
                                      'Inside Temp',
                                      style: TextStyle(
                                          color: Colors.white, fontSize: 18),
                                    ),
                                    SizedBox(
                                      height: 5,
                                    ),
                                    Row(
                                      children: <Widget>[
                                        Icon(
                                          Icons.ac_unit,
                                          color: Colors.white,
                                          size: 20,
                                        ),
                                        SizedBox(
                                          width: 10,
                                        ),
                                        Text(
                                          '19 C',
                                          style: TextStyle(color: Colors.white),
                                        ),
                                      ],
                                    )
                                  ],
                                ),
                                SizedBox(
                                  width: 10,
                                ),
                                Column(
                                  children: <Widget>[
                                    Text(
                                      'Outside Temp',
                                      style: TextStyle(
                                          color: Colors.white, fontSize: 18),
                                    ),
                                    SizedBox(
                                      height: 5,
                                    ),
                                    Row(
                                      children: <Widget>[
                                        Icon(
                                          Icons.ac_unit,
                                          color: Colors.white,
                                          size: 20,
                                        ),
                                        SizedBox(
                                          width: 10,
                                        ),
                                        Text(
                                          '19 C',
                                          style: TextStyle(color: Colors.white),
                                        ),
                                      ],
                                    )
                                  ],
                                ),
                              ],
                            )
                          ],
                        ),
                      ),
                    ),
                    AnimatedPositioned(
                      onEnd: () {
                        setState(() {
                          dismissSwipeText = !dismissSwipeText;
                          //print(dismissSwipeText);
                        });
                      },
                      curve: Curves.ease,
                      duration: Duration(milliseconds: 700),
                      bottom: moveWidget
                          ? 10
                          : MediaQuery.of(context).size.height * 0.18,
                      left: 10.0,
                      right: 0.0,
                      top: moveWidget
                          ? 50
                          : MediaQuery.of(context).size.height * 0.75,
                      child: AnimatedOpacity(
                        opacity: dismissSwipeText ? 1 : 0,
                        duration: Duration(milliseconds: 500),
                        child: Text(
                          'Swipe up to customize',
                          style: TextStyle(color: Colors.white, fontSize: 20),
                        ),
                      ),
                    ),
                    AnimatedPositioned(
                      curve: Curves.ease,
                      duration: Duration(milliseconds: 700),
                      onEnd: () {
                        setState(() {
                          _isSwpie = true;
                        });
                      },
                      left: 10,
                      top: moveWidget
                          ? 80
                          : MediaQuery.of(context).size.height * 0.80,
                      child: Container(
                        width: MediaQuery.of(context).size.width * 0.97,
                        child: Row(
                          mainAxisAlignment: MainAxisAlignment.start,
                          children: <Widget>[
                            GestureDetector(
                              onTap: () {
                                setState(() {
                                  currentSelectedIndex = 0;
                                });
                              },
                              child: Container(
                                width: MediaQuery.of(context).size.width * 0.20,
                                height:
                                    MediaQuery.of(context).size.height * 0.10,
                                decoration: BoxDecoration(
                                  borderRadius: BorderRadius.circular(20),
                                  color: currentSelectedIndex == 0
                                      ? Colors.blue
                                      : Colors.grey[900],
                                ),
                                child: Center(
                                    child: Text(
                                  'Lights',
                                  style: GoogleFonts.lato(
                                      color: Colors.white,
                                      fontWeight: FontWeight.w700),
                                )),
                              ),
                            ),
                            Row(
                              children: <Widget>[
                                SizedBox(
                                  width: 10,
                                ),
                                GestureDetector(
                                  onTap: () {
                                    setState(() {
                                      currentSelectedIndex = 1;
                                    });
                                  },
                                  child: Container(
                                    width: MediaQuery.of(context).size.width *
                                        0.20,
                                    height: MediaQuery.of(context).size.height *
                                        0.10,
                                    decoration: BoxDecoration(
                                      borderRadius: BorderRadius.circular(20),
                                      color: currentSelectedIndex == 1
                                          ? Colors.blue
                                          : Colors.grey[900],
                                    ),
                                    child: Center(
                                        child: Text(
                                      'Applicanes',
                                      style: GoogleFonts.lato(
                                          color: Colors.white,
                                          fontWeight: FontWeight.w700),
                                    )),
                                  ),
                                ),
                              ],
                            ),
                            Row(
                              children: <Widget>[
                                SizedBox(
                                  width: 10,
                                ),
                                GestureDetector(
                                  onTap: () {
                                    setState(() {
                                      currentSelectedIndex = 2;
                                    });
                                  },
                                  child: Container(
                                    width: MediaQuery.of(context).size.width *
                                        0.20,
                                    height: MediaQuery.of(context).size.height *
                                        0.10,
                                    decoration: BoxDecoration(
                                      borderRadius: BorderRadius.circular(20),
                                      color: currentSelectedIndex == 2
                                          ? Colors.blue
                                          : Colors.grey[900],
                                    ),
                                    child: Center(
                                        child: Text(
                                      'Sensors',
                                      style: GoogleFonts.lato(
                                          color: Colors.white,
                                          fontWeight: FontWeight.w700),
                                    )),
                                  ),
                                ),
                              ],
                            ),
                            Row(
                              children: <Widget>[
                                SizedBox(
                                  width: 10,
                                ),
                                Container(
                                  width:
                                      MediaQuery.of(context).size.width * 0.20,
                                  height:
                                      MediaQuery.of(context).size.height * 0.10,
                                  decoration: BoxDecoration(
                                    borderRadius: BorderRadius.circular(20),
                                    color: Colors.grey[900],
                                  ),
                                  child: Center(
                                      child: Text(
                                    'Doors \n& Locks',
                                    style: GoogleFonts.lato(
                                        color: Colors.white,
                                        fontWeight: FontWeight.w700),
                                  )),
                                ),
                              ],
                            ),
                            SizedBox(
                              width: 10,
                            ),
                          ],
                        ),
                      ),
                    ),
                    AnimatedPositioned(
                      curve: Curves.ease,
                      duration: Duration(milliseconds: 400),
                      bottom: moveWidget
                          ? 10
                          : MediaQuery.of(context).size.height * 0.20,
                      left: 10.0,
                      right: 0.0,
                      top: moveWidget
                          ? 15
                          : MediaQuery.of(context).size.height * 0.70,
                      child: Text(
                        '${widget.item.locationName}',
                        style: TextStyle(fontSize: 30, color: Colors.white),
                      ),
                    ),
                  ],
                )),
          ),
        ),
      ),
    );
  }
}

You can add Color to the last AnimatedPositioned which use text widget.item.locationName in your code, like:

AnimatedPositioned(
  curve: Curves.ease,
  duration: Duration(milliseconds: 400),
  bottom: moveWidget
    ? 10
    : MediaQuery.of(context).size.height * 0.20,
  left: 10.0,
  right: 0.0,
  top: moveWidget
    ? 15
    : MediaQuery.of(context).size.height * 0.70,
  child: Container(
    color: Colors.white,
    Text(
      '${widget.item.locationName}',
      style: TextStyle(fontSize: 30, color: Colors.white),
    ),
  ),
),

You will see a white screen (the widget which blocking you) when you scroll up. You can fix it by 2 ways

  1. Change the bottom 10 to a larger number

  2. Move this part of AnimatedPositioned to Top of the Stack widget

The Nested Gesture should work probably as you expected.

First of All you are using multiple Scaffold in a single page which is not recommended. And remove the unwanted widgets from your tree which will help you to debug a way more better level. And Next you can try with passing a Callback function from parent to child which can eventually solve your problem

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM