Эффект пульсации работает при длительном нажатии в плитке списка

#flutter #flutter-layout

#трепетание #флаттер-макет

Вопрос:

Я обернул виджет плитки списка виджетом жестов, потому что я хочу выполнить некоторый код при обратном вызове onLongPressStart и onLongPressEnd. Но из-за этого эффект ripple не работает при длительном нажатии. Это рабочий файл для простого нажатия. Когда я удаляю эти обратные вызовы из виджета жестов, эффект пульсации срабатывает. Как я могу исправить эту проблему?

Вот пример того, что я делаю:

 GestureDetector(

                    onLongPressStart: (value){
                      //do something
                    },
                    onLongPressEnd: (value){
                      //do something
                    },
                    child: ListTile(
                      title: Text("Title"),
                      onTap: (){
                        // do something
                      },
                    ),
                  ),
  

Комментарии:

1. итак, вы хотите запустить эффект пульсации при длительном нажатии или что-то еще?

2. Нет, на самом деле эффект ripple отображается так, как будто это простая вкладка, после чего виджет не нажимается. Я хочу показать, что плитка все еще нажата (ее цвет фона должен измениться)

3. извините, я понятия не имею, чего вы действительно хотите достичь

4. Я хочу, чтобы «пока виджет нажат, его цвет фона должен оставаться измененным. Например: если плитка белая после нажатия виджета, она должна отображаться серым цветом. После завершения длительного нажатия цвет должен измениться на белый »

5. итак, пульсация начинается, если вы нажимаете пальцем, и исчезает, когда вы отпускаете палец? итак, почему мы вообще говорим о длительном нажатии ? или вы имеете в виду, что пульсация начинается при длительном нажатии?

Ответ №1:

Возможно, вы можете использовать эту структуру. Длительное нажатие вызывает «цвет всплеска» и дает цвет. Если вы сохраняете непрозрачность цвета в поле «контейнер» на низком уровне, «цвет всплеска» не будет потерян.

 InkWell(
    splashColor: Colors.blue,
    onTap: () {
        print('Clicked');
    },
    child: Container(
        color: Colors.grey.withOpacity(0.2),
        child: ListTile(
            title: Text('Text'),
        ),
    ),
)
  

Ответ №2:

InkRipple сделал свое дело для меня. Вот код

 class PressRipple extends StatefulWidget {
    final Widget child;
    final VoidCallback onPress;

    PressRipple({
        Key key,
        this.child,
        @required this.onPress,
    }) : assert(onPress != null), super(key: key);

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

class _PressRippleState extends State<PressRipple> {
    InteractiveInkFeature _inkFeature;

    @override
    Widget build(BuildContext context) {
        return GestureDetector(
            behavior: HitTestBehavior.opaque,
        onTapDown: (d) {
        _inkFeature = InkRipple(
            position: d.localPosition,
        color: Colors.green,
        controller: Material.of(context),
        referenceBox: context.findRenderObject(),
        textDirection: TextDirection.ltr,
        containedInkWell: true,
        );
        widget.onPress();
    },
        onTapUp: (d) {
        _inkFeature.dispose();
    },
        child: widget.child,
        );
    }
}
  

А затем используйте его следующим образом

 SizedBox(
      width: 200,
      height: 200,
      child: Material(
        color: Colors.grey,
        child: PressRipple(
          onPress: () {
            print('on press callback');
          },
        ),
      ),
    ),
  

Спасибо @pskink за помощь

Комментарии:

1. Всегда ли это работает так, как ожидалось? Когда я попытался запустить этот код, при нескольких нажатиях весь контейнер становится зеленым и остается застрявшим.