Flutter可按压交互插件pressable的使用

发布于 1周前 作者 yibo5220 来自 Flutter

Flutter可按压交互插件pressable的使用

Pressable 是一个用于快速添加点击效果到你的Flutter小部件的插件。该插件支持多种点击效果,如Ripple(水波纹)、Scale(缩放)、Opacity(透明度变化)、Fill(填充颜色)以及自定义构建器。

使用方法

基本用法

以下是一些基本的使用示例:

Opacity 效果

Pressable.opacity(
  onPressed: () {
    print('Opacity pressed');
  },
  child: const ExampleButton(title: 'Opacity'),
)

支持的效果类型

  • Ripple (InkWell)
  • Scale
  • Opacity
  • Fill
  • Custom builder

默认主题

你可以使用 DefaultPressableTheme 继承控件来为子控件提供默认的 PressableTheme

DefaultPressableTheme(
  fillTheme: PressableFillTheme(
    fillColor: Colors.green.withOpacity(0.2),
  ),
  child: Pressable.fill(
    onPressed: () {},
    child: const ExampleButton(title: 'Default theme'),
  ),
),

平台特定的Pressable主题

你可以使用 Pressable.platform() 构造函数为每个平台指定主题。

Pressable.platform(
  onPressed: () {},
  ios: const PressableTheme.opacity(),
  android: const PressableTheme.ripple(),
  child: const ExampleButton(title: 'Platform'),
),

完整示例代码

下面是一个完整的示例代码,展示了如何在Flutter应用中使用Pressable插件。

// ignore_for_file: avoid_print
import 'package:flutter/material.dart';
import 'package:pressable/pressable.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const HomeScreen(),
    );
  }
}

class HomeScreen extends StatelessWidget {
  const HomeScreen({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Example')),
      body: Column(
        children: [
          Pressable.builder(
            onPressed: () {
              print('[HomeScreen.build] Builder pressed');
            },
            builder: (context, isPressed) {
              return AnimatedContainer(
                width: 200,
                height: 50,
                color: isPressed ? Colors.blue : const Color(0xFFd6d6d6),
                duration: const Duration(milliseconds: 100),
                child: const Center(
                  child: Text('Custom Builder'),
                ),
              );
            },
          ),
          Pressable.ripple(
            onPressed: () {
              print('[HomeScreen.build] Ripple pressed');
            },
            child: const ExampleButton(title: 'Ripple'),
          ),
          Pressable.scale(
            onPressed: () {
              print('[HomeScreen.build] Scale pressed');
            },
            theme: const PressableScaleTheme(
              scaleFactor: 0.8,
            ),
            child: const ExampleButton(title: 'Scale'),
          ),
          Pressable.opacity(
            onPressed: () {
              print('[HomeScreen.build] Opacity pressed');
            },
            theme: const PressableOpacityTheme(
              curve: Curves.easeOut,
              opacityFactor: 0.4,
            ),
            child: const ExampleButton(title: 'Opacity'),
          ),
          Pressable.fill(
            onPressed: () {
              print('[HomeScreen.build] Fill pressed');
            },
            theme: const PressableFillTheme(
              fillColor: Colors.red,
            ),
            child: const ExampleButton(title: 'Fill'),
          ),
          Pressable.platform(
            onPressed: () {
              print('[HomeScreen.build] Platform pressed');
            },
            ios: const PressableTheme.opacity(),
            android: const PressableTheme.ripple(),
            child: const ExampleButton(title: 'Platform'),
          ),
          SizedBox(
            width: 150,
            child: Stack(
              children: [
                Pressable.scale(
                  onPressed: () {
                    print('[HomeScreen.build] Scale pressed');
                  },
                  child: Container(
                    width: 150,
                    height: 50,
                    color: Colors.black12,
                    child: const Center(child: Text('Test')),
                  ),
                ),
                Align(
                  alignment: Alignment.centerRight,
                  child: IconButton(
                    onPressed: () {},
                    icon: const Icon(Icons.bookmark),
                  ),
                ),
              ],
            ),
          ),
          DefaultPressableTheme(
            fillTheme: const PressableFillTheme(
              fillColor: Colors.green,
            ),
            child: Pressable.fill(
              onPressed: () {
                print('[HomeScreen.build] Default theme pressed');
              },
              child: const ExampleButton(title: 'Default theme'),
            ),
          ),
        ],
      ),
    );
  }
}

class ExampleButton extends StatelessWidget {
  const ExampleButton({
    Key? key,
    required this.title,
  }) : super(key: key);

  final String title;

  @override
  Widget build(BuildContext context) {
    return Container(
      width: 200,
      height: 50,
      padding: const EdgeInsets.symmetric(horizontal: 8),
      color: Colors.black12,
      child: Row(
        children: [
          Text(title),
          const Spacer(),
          IconButton(
            onPressed: () {},
            icon: const Icon(Icons.bookmark),
          ),
        ],
      ),
    );
  }
}

通过上述代码和示例,你可以在Flutter应用中轻松实现各种按压交互效果,提升用户体验。


更多关于Flutter可按压交互插件pressable的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter可按压交互插件pressable的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是一个关于如何在Flutter中使用Pressable交互插件的代码案例。需要注意的是,Flutter本身并没有一个名为Pressable的内置Widget,但我们可以使用GestureDetector来实现类似的功能。不过,如果你指的是某个第三方库中的Pressable,请确保你已经将其添加到你的pubspec.yaml文件中。这里,我将展示如何使用GestureDetector来创建一个可按压的交互组件。

首先,确保你的Flutter环境已经设置好,并且你有一个正在运行的Flutter项目。

使用GestureDetector实现可按压交互

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Pressable Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Pressable Demo'),
      ),
      body: Center(
        child: PressableWidget(),
      ),
    );
  }
}

class PressableWidget extends StatefulWidget {
  @override
  _PressableWidgetState createState() => _PressableWidgetState();
}

class _PressableWidgetState extends State<PressableWidget> {
  bool _isPressed = false;

  void _handlePress() {
    setState(() {
      _isPressed = !_isPressed;
    });
    // 模拟按压后的处理逻辑,比如延迟恢复状态
    Future.delayed(Duration(milliseconds: 200), () {
      setState(() {
        _isPressed = false;
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTapDown: (details) => _handlePress(),
      onTapUp: (details) => _handlePress(), // 如果需要在抬起时也触发,可以添加此行
      onTapCancel: () => _handlePress(), // 如果需要取消按压时触发,可以添加此行
      child: Container(
        width: 200,
        height: 100,
        decoration: BoxDecoration(
          color: _isPressed ? Colors.grey.shade300 : Colors.blue,
          borderRadius: BorderRadius.circular(10),
        ),
        child: Center(
          child: Text(
            _isPressed ? 'Pressed' : 'Press Me',
            style: TextStyle(color: Colors.white),
          ),
        ),
      ),
    );
  }
}

解释

  1. GestureDetector: 用于监听各种手势事件,这里我们主要使用onTapDown来检测按压开始的事件。
  2. _handlePress: 一个处理按压逻辑的方法,它改变_isPressed状态来模拟按压效果。同时,使用Future.delayed来模拟按压后的恢复效果。
  3. Container: 作为按压的目标Widget,其颜色根据_isPressed状态变化。
  4. Text: 显示按压状态的文本。

如果你使用的是某个第三方库中的Pressable,请查阅该库的文档以获取正确的使用方法和示例代码。通常,第三方库的Pressable组件会提供更丰富的按压反馈选项,如涟漪效果、动画等。

回到顶部