Вложенный жест не изменяется при нажатии

#android #ios #flutter

#Android #iOS #трепетание

Вопрос:

В настоящее время я работаю над пользовательским интерфейсом для приложения, поэтому дело в том, что у меня есть один родительский жест, который перемещается вверх и вниз, и на его основе изменяется положение виджетов, но проблема в том, что дочерний жест не получает никакого приоритета при нажатии на него, он дает приоритет. Итак, моя древовидная структура — это Pageview.builder, который имеет один виджет с самым верхним родителем в качестве Gesturedetector и дочерними элементами соответственно, может ли кто-нибудь сказать мне, что я делаю неправильно, или какие-либо улучшения, чтобы получить жест для каждого. Ниже приведен пример кода, над которым я работал:

 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 namp; 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),
                      ),
                    ),
                  ],
                )),
          ),
        ),
      ),
    );
  }
}

  

Ответ №1:

Вы можете добавить цвет к последнему AnimatedPositioned , который использует текст widget.item.LocationName в вашем коде, например:

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

При прокрутке вверх вы увидите белый экран (виджет, который вас блокирует). Вы можете исправить это двумя способами

  1. Измените нижние 10 на большее число

  2. Переместите эту часть AnimatedPositioned виджета в начало стека

Вложенный жест должен работать, вероятно, так, как вы ожидали.

Ответ №2:

Прежде всего, вы используете несколько каркасов на одной странице, что не рекомендуется. И удалите ненужные виджеты из вашего дерева, что поможет вам отлаживать путь на более высоком уровне. И затем вы можете попробовать передать функцию обратного вызова от родительского элемента к дочернему, что в конечном итоге может решить вашу проблему