ProComponents, templates & AI tooling
2.3k

PressableFeedback 按压反馈更新

为按压交互提供视觉反馈的容器组件,内置缩放动画。

导入

import { PressableFeedback } from 'heroui-native';

结构

<PressableFeedback>
  <PressableFeedback.Highlight />
  <PressableFeedback.Ripple />
  <PressableFeedback.Scale>...</PressableFeedback.Scale>
</PressableFeedback>
  • PressableFeedback:内置缩放动画的可按压容器;管理按压状态与容器尺寸,并通过上下文提供给子复合部件。使用 PressableFeedback.Scale 时可将 animation={false} 关闭根级内置缩放。
  • PressableFeedback.Scale:对特定子元素应用缩放的包装层;需要精确控制哪个元素缩放,或要在缩放层上直接应用 className / style 时使用。
  • PressableFeedback.Highlight:iOS 风格的高亮遮罩,绝对定位,在按压时淡入。
  • PressableFeedback.Ripple:Android 风格的涟漪,从触点扩展的径向渐变圆。

用法

基础

默认提供按下缩放反馈,多数场景推荐直接使用。

<PressableFeedback>...</PressableFeedback>

配合 Highlight

在默认缩放之外叠加 iOS 风格高亮。

<PressableFeedback>
  <PressableFeedback.Highlight />
  ...
</PressableFeedback>

配合 Ripple

在默认缩放之外叠加 Android 风格涟漪。

<PressableFeedback>
  <PressableFeedback.Ripple />
  ...
</PressableFeedback>

自定义缩放动画

通过根组件 animation.scale 配置,支持 valuetimingConfigignoreScaleCoefficient

<PressableFeedback
  animation={{
    scale: {
      value: 0.9,
      timingConfig: { duration: 150 },
      ignoreScaleCoefficient: true,
    },
  }}
>
  ...
</PressableFeedback>

自定义 Highlight 动画

配置高亮层的不透明度与背景色。

<PressableFeedback>
  <PressableFeedback.Highlight
    animation={{
      backgroundColor: { value: '#3b82f6' },
      opacity: { value: [0, 0.2] },
    }}
  />
  ...
</PressableFeedback>

自定义 Ripple 动画

配置涟漪颜色、不透明度与时长。

<PressableFeedback>
  <PressableFeedback.Ripple
    animation={{
      backgroundColor: { value: '#ec4899' },
      opacity: { value: [0, 0.1, 0] },
      progress: { baseDuration: 600 },
    }}
  />
  ...
</PressableFeedback>

对指定子元素缩放(PressableFeedback.Scale)

需要对容器内某一子元素而非根节点缩放时,将根组件设为 animation={false} 关闭内置缩放,再使用 PressableFeedback.Scale,以便在缩放层上直接应用 className / style

<PressableFeedback animation={false}>
  <PressableFeedback.Scale>...</PressableFeedback.Scale>
</PressableFeedback>

可与 HighlightRipple 组合在 Scale 内:

<PressableFeedback animation={false}>
  <PressableFeedback.Scale>
    <PressableFeedback.Highlight />
    ...
  </PressableFeedback.Scale>
</PressableFeedback>

禁用全部动画

根上设置 animation="disable-all" 可级联禁用内置缩放及子复合部件(Scale、Highlight、Ripple)的动画。

<PressableFeedback animation="disable-all">...</PressableFeedback>

也可在保留缩放配置的同时禁用动画(例如运行时切换):

<PressableFeedback animation={{ scale: { value: 0.97 }, state: 'disable-all' }}>
  ...
</PressableFeedback>

示例

import { PressableFeedback, Card, Button } from 'heroui-native';
import { Image } from 'expo-image';
import { LinearGradient } from 'expo-linear-gradient';
import { StyleSheet, View, Text } from 'react-native';

export default function PressableFeedbackExample() {
  return (
    <PressableFeedback className="w-full aspect-square overflow-auto">
      <Card className="flex-1">
        <Image
          source={{
            uri: 'https://heroui-assets.nyc3.cdn.digitaloceanspaces.com/docs/neo2.jpeg',
          }}
          style={StyleSheet.absoluteFill}
          contentFit="cover"
        />
        <LinearGradient
          colors={['rgba(0,0,0,0.1)', 'rgba(0,0,0,0.4)']}
          style={StyleSheet.absoluteFill}
        />
        <PressableFeedback.Ripple
          animation={{
            backgroundColor: { value: 'white' },
            opacity: { value: [0, 0.3, 0] },
          }}
        />
        <View className="flex-1 gap-4" pointerEvents="box-none">
          <Card.Body className="flex-1" pointerEvents="none">
            <Card.Title className="text-base text-zinc-50 uppercase mb-0.5">
              Neo
            </Card.Title>
            <Card.Description className="text-zinc-50 font-medium text-base">
              家用机器人
            </Card.Description>
          </Card.Body>
          <Card.Footer className="gap-3">
            <View className="flex-row items-center justify-between">
              <View pointerEvents="none">
                <Text className="text-base text-white">即将开售</Text>
                <Text className="text-base text-zinc-300">订阅通知</Text>
              </View>
              <Button size="sm" className="bg-white">
                <Button.Label className="text-black">通知我</Button.Label>
              </Button>
            </View>
          </Card.Footer>
        </View>
      </Card>
    </PressableFeedback>
  );
}

更多示例见 GitHub 仓库

API 参考

PressableFeedback

proptypedefaultdescription
childrenReact.ReactNode-需要包裹按压反馈的内容
isDisabledbooleanfalse是否禁用
classNamestring-额外的 class
animationPressableFeedbackRootAnimation-通过 { scale: ... } 自定义缩放;false 关闭根级缩放;'disable-all' 级联禁用全部
isAnimatedStyleActivebooleantrue根内置动画样式是否启用
asChildbooleanfalse是否以子元素方式渲染
...restAnimatedProps<PressableProps>-支持 Reanimated Animated Pressable 的属性

PressableFeedbackRootAnimation

animation 遵循标准 AnimationRoot 控制流:

  • trueundefined:使用默认内置缩放
  • false"disabled":关闭根内置缩放(改用 PressableFeedback.Scale 时)
  • "disable-all":级联禁用全部动画(含内置缩放与子级 Scale、Highlight、Ripple)
  • object:自定义内置缩放
proptypedefaultdescription
scalePressableFeedbackScaleAnimation-自定义内置缩放(value、timingConfig 等)
state'disabled' | 'disable-all' | boolean-在保留配置的同时控制动画状态(例如运行时开关)

PressableFeedback.Scale

对容器内指定子元素应用缩放时使用;根上设 animation={false} 以关闭其内置缩放。

proptypedefaultdescription
classNamestring-额外的 class
animationPressableFeedbackScaleAnimation-缩放动画配置
isAnimatedStyleActivebooleantrue是否启用 Reanimated 动画样式
styleViewStyle-额外样式
...AnimatedPropsAnimatedProps<ViewProps>-支持 Reanimated Animated.View 的属性

PressableFeedbackScaleAnimation

缩放动画配置,可为:

  • false"disabled":禁用缩放动画
  • trueundefined:使用默认缩放动画
  • object:自定义缩放配置
proptypedefaultdescription
state'disabled' | boolean-在自定义属性时禁用动画
valuenumber0.985按下时的缩放值(会随容器宽度自动调整)
timingConfigWithTimingConfig{ duration: 300, easing: Easing.out(Easing.ease) }时间曲线配置
ignoreScaleCoefficientbooleanfalse为 true 时忽略自动缩放系数,直接使用 value

PressableFeedback.Highlight

proptypedefaultdescription
classNamestring-额外的 class
animationPressableFeedbackHighlightAnimation-高亮层动画配置
isAnimatedStyleActivebooleantrue是否启用 Reanimated 动画样式
styleViewStyle-额外样式
...AnimatedPropsAnimatedProps<ViewProps>-支持 Reanimated Animated.View 的属性

PressableFeedbackHighlightAnimation

高亮层动画配置,可为:

  • false"disabled":禁用高亮动画
  • trueundefined:使用默认动画
  • object:自定义动画配置
proptypedefaultdescription
state'disabled' | boolean-在自定义属性时禁用动画
opacity.value[number, number][0, 0.1]不透明度 [未按下, 按下]
opacity.timingConfigWithTimingConfig{ duration: 200 }时间曲线配置
backgroundColor.valuestring随主题灰色高亮层背景色

PressableFeedback.Ripple

proptypedefaultdescription
classNamestring-容器插槽的 class
classNamesElementSlots<RippleSlots>-各插槽 class(container、ripple)
stylesPartial<Record<RippleSlots, ViewStyle>>-涟漪遮罩各部分的样式
animationPressableFeedbackRippleAnimation-涟漪动画配置
isAnimatedStyleActivebooleantrue是否启用 Reanimated 动画样式
...ViewPropsOmit<ViewProps, 'style'>-支持 View 属性(不含 style

styles

proptypedescription
containerViewStyle容器插槽样式
rippleViewStyle涟漪插槽样式

PressableFeedbackRippleAnimation

涟漪动画配置,可为:

  • false"disabled":禁用涟漪动画
  • trueundefined:使用默认动画
  • object:自定义动画配置
proptypedefaultdescription
state'disabled' | boolean-在自定义属性时禁用动画
backgroundColor.valuestring随主题计算涟漪背景色
progress.baseDurationnumber1000涟漪进度基准时长(会按对角线自动调整)
progress.minBaseDurationnumber750进度动画最小时长
progress.ignoreDurationCoefficientbooleanfalse为 true 时忽略自动时长系数,直接使用基准时长
opacity.value[number, number, number][0, 0.1, 0]不透明度 [起始, 峰值, 结束]
opacity.timingConfigWithTimingConfig{ duration: 200 }时间曲线配置
scale.value[number, number, number][0, 1, 1]缩放 [起始, 峰值, 结束]
scale.timingConfigWithTimingConfig{ duration: 200 }时间曲线配置

ElementSlots<RippleSlots>

涟漪各插槽的额外 class:

slotdescription
container外层容器(absolute inset-0),可通过 class 完全定制样式
ripple内层涟漪(absolute top-0 left-0 rounded-full),带动画属性,不宜用 className 覆盖动画相关表现

本页目录