ReactNative项目OpenHarmony三方库集成实战:@react-native-community/slider
滑块(Slider)是移动应用中常用的交互组件,用于在给定范围内选择一个数值。无论是调节音量、设置亮度、筛选价格区间,还是调整播放进度,滑块都能提供直观的用户体验。是 React Native 官方社区维护的滑块组件库,提供了跨平台一致的滑块体验,支持丰富的自定义选项和事件回调。库名称版本信息4.4.4: 支持 RN 0.72 版本5.0.1: 支持 RN 0.77 版本5.1.2: 支持 RN
欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net
📋 前言
滑块(Slider)是移动应用中常用的交互组件,用于在给定范围内选择一个数值。无论是调节音量、设置亮度、筛选价格区间,还是调整播放进度,滑块都能提供直观的用户体验。@react-native-community/slider 是 React Native 官方社区维护的滑块组件库,提供了跨平台一致的滑块体验,支持丰富的自定义选项和事件回调。
🎯 库简介
基本信息
- 库名称:
@react-native-community/slider - 版本信息:
4.4.4+@react-native-ohos/slider: 支持 RN 0.72 版本5.0.1+@react-native-ohos/slider: 支持 RN 0.77 版本5.1.2+@react-native-ohos/slider: 支持 RN 0.82 版本
- 官方仓库: https://github.com/callstack/react-native-slider
- 鸿蒙仓库: https://atomgit.com/openharmony-sig/rntpc_react-native-slider
- 主要功能:
- 🎚️ 范围数值选择
- 🎨 丰富的样式定制
- 📱 跨平台一致体验
- 🔄 步进值支持
- 🖼️ 自定义滑块图标
- 📊 步骤标记显示
为什么需要滑块组件?
| 特性 | 手动实现 | @react-native-community/slider |
|---|---|---|
| 跨平台一致性 | ⚠️ 需分别适配 | ✅ 统一体验 |
| 步进值支持 | ⚠️ 需自行计算 | ✅ 内置 step 属性 |
| 自定义样式 | ❌ 工作量大 | ✅ 丰富的 props |
| 事件回调 | ⚠️ 需自行处理 | ✅ 完整事件支持 |
| 滑块图标 | ❌ 需额外实现 | ✅ 支持自定义图片 |
| HarmonyOS 支持 | ❌ 无 | ✅ 完善适配 |
核心功能
| 功能 | 说明 | HarmonyOS 支持 |
|---|---|---|
| 基础滑块 | 范围数值选择 | ✅ |
| 步进值 | 按步长滑动 | ✅ |
| 最小/最大值 | 设置范围边界 | ✅ |
| 滑动限制 | 设置上下限 | ✅ |
| 自定义颜色 | 轨道和滑块颜色 | ✅ |
| 自定义图标 | 滑块图片 | ✅ |
| 步骤标记 | 显示刻度 | ✅ |
| 禁用状态 | 禁止交互 | ✅ |
| 反向滑块 | 从右到左 | ✅ |
兼容性验证
在以下环境验证通过:
- RNOH: 0.72.90; SDK: HarmonyOS 6.0.0 Release SDK; IDE: DevEco Studio 6.0.2; ROM: 6.0.0
📦 安装步骤
1. 安装依赖
请到三方库的 Releases 发布地址查看配套的版本信息:
| 三方库版本 | 发布信息 | 支持 RN 版本 |
|---|---|---|
| 4.4.4 | @react-native-ohos/slider Releases | 0.72 |
| 5.0.1 | @react-native-ohos/slider Releases | 0.77 |
| 5.1.2 | @react-native-ohos/slider Releases | 0.82 |

# RN 0.72 版本
npm install @react-native-ohos/slider@4.4.4-rc.1
# RN 0.77 版本
npm install @react-native-ohos/slider@5.0.1-rc.1
# RN 0.82 版本
npm install @react-native-ohos/slider@5.1.2-rc.1
# 或者使用 yarn
yarn add @react-native-ohos/slider
2. 验证安装
安装完成后,检查 package.json 文件:
{
"dependencies": {
"@react-native-ohos/slider": "^4.4.4-rc.1"
}
}
3. TypeScript 类型定义配置
由于鸿蒙适配版本的 @react-native-community/slider 库类型定义可能不完整,建议在项目中添加自定义类型定义文件。
在 src/types 目录下创建 react-native-slider.d.ts 文件:
declare module '@react-native-community/slider' {
import { Component } from 'react';
import { ViewStyle, StyleProp } from 'react-native';
export interface StepMarkerProps {
stepMarked: boolean;
currentValue: number;
index: number;
min: number;
max: number;
}
export interface SliderProps {
style?: StyleProp<ViewStyle>;
value?: number;
minimumValue?: number;
maximumValue?: number;
step?: number;
minimumTrackTintColor?: string;
maximumTrackTintColor?: string;
thumbTintColor?: string;
upperLimit?: number;
lowerLimit?: number;
onValueChange?: (value: number) => void;
onSlidingStart?: (value: number) => void;
onSlidingComplete?: (value: number) => void;
onLowLimit?: () => void;
onUpperLimit?: () => void;
disabled?: boolean;
vertical?: boolean;
inverted?: boolean;
trackStyle?: StyleProp<ViewStyle>;
thumbStyle?: StyleProp<ViewStyle>;
debugTouchArea?: boolean;
StepMarker?: React.ComponentType<StepMarkerProps>;
}
export default class Slider extends Component<SliderProps> {}
}
然后在 tsconfig.json 中确保包含该类型文件:
{
"compilerOptions": {
"typeRoots": ["./node_modules/@types", "./src/types"]
},
"include": ["src/**/*", "src/types/**/*"]
}
🔧 HarmonyOS 平台配置 ⭐
Link 配置
| 版本 | 是否支持 autolink | RN 框架版本 |
|---|---|---|
| ~5.1.2 | No | 0.82 |
| ~5.0.1 | No | 0.77 |
| ~4.4.4 | Yes | 0.72 |
如您使用的版本支持 Autolink,并且工程已接入 Autolink,可跳过 ManualLink 配置。
ManualLink: 此步骤为手动配置原生依赖项的指导1. 在工程根目录的 oh-package.json5 添加 overrides 字段(看自己package.json中的版本)
打开 harmony/oh-package.json5,添加以下配置:
{
// ... 其他配置
"overrides": {
"@rnoh/react-native-openharmony": "0.72.90"
}
}
2. 引入原生端代码
方式一:通过 HAR 包引入(推荐)
💡 提示:HAR 包位于三方库安装路径的
harmony文件夹下。
打开 harmony/entry/oh-package.json5,添加以下依赖:
"dependencies": {
"@react-native-ohos/slider": "file:../../node_modules/@react-native-ohos/slider/harmony/slider.har"
}
点击右上角的 sync 按钮,或者在终端执行:
cd harmony/entry
ohpm install
3. 配置 CMakeLists 和引入 SliderPackage
打开 harmony/entry/src/main/cpp/CMakeLists.txt,添加:
project(rnapp)
cmake_minimum_required(VERSION 3.4.1)
set(RNOH_APP_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
+ set(OH_MODULES "${CMAKE_CURRENT_SOURCE_DIR}/../../../oh_modules")
set(RNOH_CPP_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../react-native-harmony/harmony/cpp")
add_subdirectory("${RNOH_CPP_DIR}" ./rn)
# 添加 Slider 模块
+ add_subdirectory("${OH_MODULES}/@react-native-ohos/slider/src/main/cpp" ./slider)
add_library(rnoh_app SHARED
"./PackageProvider.cpp"
"${RNOH_CPP_DIR}/RNOHAppNapiBridge.cpp"
)
target_link_libraries(rnoh_app PUBLIC rnoh)
# 链接 Slider 库
+ target_link_libraries(rnoh_app PUBLIC rnoh_slider)
打开 harmony/entry/src/main/cpp/PackageProvider.cpp,添加:
#include "RNOH/PackageProvider.h"
+ #include "SliderPackage.h"
using namespace rnoh;
std::vector<std::shared_ptr<Package>> PackageProvider::getPackages(Package::Context ctx) {
return {
+ std::make_shared<SliderPackage>(ctx),
};
}
4. 在 ArkTs 侧引入 Slider 组件
找到 function buildCustomRNComponent(),一般位于 entry/src/main/ets/pages/index.ets 或 entry/src/main/ets/rn/LoadBundle.ets,添加:
import { RNCSlider, SLIDER_TYPE } from "@react-native-ohos/slider"
@Builder
export function buildCustomRNComponent(ctx: ComponentBuilderContext) {
// ... 其他组件
if (ctx.componentName === SLIDER_TYPE) {
RNCSlider({
ctx: ctx.rnComponentContext,
tag: ctx.tag,
})
}
}
💡 提示:本库使用了混合方案,需要添加组件名。
在 entry/src/main/ets/pages/index.ets 或 entry/src/main/ets/rn/LoadBundle.ets 找到常量 arkTsComponentNames 在其数组里添加组件名:
const arkTsComponentNames: Array<string> = [
// ... 其他组件名
SLIDER_TYPE
];
🚀 同步并运行
点击 DevEco Studio 右上角的 sync 按钮,或者在终端执行:
cd harmony/entry
ohpm install
然后编译、运行即可。
📖 API 详解
基础属性
value - 当前值
表示滑块的当前值,可用于以编程方式控制滑块位置。这是滑块组件最核心的属性,决定了滑块手柄的位置。
类型:number
默认值:0
使用场景:
- 初始化滑块位置
- 响应用户操作更新显示
- 程序化控制滑块位置
import Slider from "@react-native-community/slider";
const [value, setValue] = useState(50);
<Slider
value={value}
onValueChange={setValue}
/>
// 实际应用:双向绑定
const [sliderValue, setSliderValue] = useState(30);
<View>
<Text>当前值: {Math.round(sliderValue)}</Text>
<Slider
value={sliderValue}
onValueChange={setSliderValue}
minimumValue={0}
maximumValue={100}
/>
</View>
⚠️ 注意:这不是受控组件,您不需要在拖动过程中更新值。滑块内部会自行管理拖动过程中的值,
onValueChange回调会在值变化时通知您。
minimumValue - 最小值
设置滑块的最小值,定义滑动范围的起点。
类型:number
默认值:0
使用场景:
- 定义数值范围起点
- 温度滑块(如最低温度)
- 年龄选择器(如 18 岁)
// 基础用法
<Slider
minimumValue={0}
maximumValue={100}
value={50}
/>
// 温度范围(摄氏度)
<Slider
minimumValue={-20}
maximumValue={50}
value={25}
/>
// 年龄选择
<Slider
minimumValue={18}
maximumValue={100}
value={25}
step={1}
/>
// 价格范围(元)
<Slider
minimumValue={0}
maximumValue={10000}
value={5000}
step={100}
/>
maximumValue - 最大值
设置滑块的最大值,定义滑动范围的终点。
类型:number
默认值:1
使用场景:
- 定义数值范围终点
- 音量控制(0-100)
- 亮度调节(0-100)
// 百分比滑块
<Slider
minimumValue={0}
maximumValue={100}
value={50}
/>
// 音量控制
<Slider
minimumValue={0}
maximumValue={100}
value={volume}
onValueChange={setVolume}
/>
// 评分滑块(1-5星)
<Slider
minimumValue={1}
maximumValue={5}
value={3}
step={1}
/>
// 时间选择(分钟)
<Slider
minimumValue={0}
maximumValue={60}
value={30}
step={5}
/>
step - 步进值
设置滑块的步长值,使滑块只能取特定间隔的值。该值应在 0 到 (maximumValue - minimumValue) 之间。
类型:number
默认值:0(连续滑动)
使用场景:
- 整数选择(step=1)
- 十分位选择(step=10)
- 固定选项(如 1-5 星,step=1)
// 步进 10
<Slider
minimumValue={0}
maximumValue={100}
step={10} // 可选值:0, 10, 20, 30, ..., 100
value={50}
/>
// 星级评分
<Slider
minimumValue={1}
maximumValue={5}
step={1} // 可选值:1, 2, 3, 4, 5
value={3}
/>
// 价格筛选
<Slider
minimumValue={0}
maximumValue={10000}
step={500} // 每 500 元一档
value={3000}
/>
// 时间间隔
<Slider
minimumValue={0}
maximumValue={60}
step={15} // 每 15 分钟一档:0, 15, 30, 45, 60
value={30}
/>
disabled - 禁用状态
如果为 true,用户将无法移动滑块,滑块会显示为灰色不可交互状态。
类型:boolean
默认值:false
使用场景:
- 条件未满足时禁用
- 只读展示
- 权限控制
// 禁用状态
<Slider
disabled={true}
value={50}
/>
// 条件性禁用
const [isPremium, setIsPremium] = useState(false);
<Slider
disabled={!isPremium}
value={volume}
onValueChange={isPremium ? setVolume : undefined}
/>
// 根据网络状态禁用
const [isOnline, setIsOnline] = useState(true);
<Slider
disabled={!isOnline}
value={quality}
onValueChange={setQuality}
/>
inverted - 反向
反转滑块的方向,使最小值在右侧,最大值在左侧。
类型:boolean
默认值:false
使用场景:
- RTL 语言支持
- 特殊交互设计
- 反向数值表示
// 正常方向(默认)
<Slider
minimumValue={0}
maximumValue={100}
value={50}
/>
// 反向滑块
<Slider
inverted={true}
minimumValue={0}
maximumValue={100}
value={50}
/>
// RTL 语言适配
const isRTL = I18nManager.isRTL;
<Slider
inverted={isRTL}
minimumValue={0}
maximumValue={100}
value={50}
/>
样式属性
style - 容器样式
用于设置 Slider 组件的样式和布局,可以控制宽度、高度、边距等。
类型:ViewStyle
使用场景:
- 设置滑块宽度
- 控制布局间距
- 自定义外观
// 固定宽度
<Slider
style={{ width: 300, height: 40 }}
value={50}
/>
// 响应式宽度
<Slider
style={{ width: '100%', height: 40 }}
value={50}
/>
// 带边距
<Slider
style={{ width: '100%', marginHorizontal: 16 }}
value={50}
/>
// 使用 StyleSheet
const styles = StyleSheet.create({
slider: {
width: '100%',
height: 40,
marginVertical: 10,
},
});
<Slider style={styles.slider} value={50} />
minimumTrackTintColor - 已滑轨道颜色
设置滑块手柄左侧(已滑动部分)轨道的颜色。
类型:string
默认值:系统默认蓝色
使用场景:
- 品牌色适配
- 状态颜色区分
- 暗色/亮色主题
// 蓝色已滑轨道
<Slider
minimumTrackTintColor="#007AFF"
maximumTrackTintColor="#E5E5EA"
value={50}
/>
// 根据值动态变色
const getTrackColor = (value: number) => {
if (value < 30) return '#FF3B30'; // 红色
if (value < 70) return '#FF9500'; // 橙色
return '#34C759'; // 绿色
};
<Slider
minimumTrackTintColor={getTrackColor(value)}
value={value}
onValueChange={setValue}
/>
// 主题适配
const isDarkMode = useColorScheme() === 'dark';
<Slider
minimumTrackTintColor={isDarkMode ? '#0A84FF' : '#007AFF'}
maximumTrackTintColor={isDarkMode ? '#3A3A3C' : '#E5E5EA'}
value={50}
/>
maximumTrackTintColor - 未滑轨道颜色
设置滑块手柄右侧(未滑动部分)轨道的颜色。
类型:string
默认值:浅灰色
使用场景:
- 背景色适配
- 视觉层次
- 主题适配
// 浅色背景
<Slider
minimumTrackTintColor="#007AFF"
maximumTrackTintColor="#E5E5EA"
value={50}
/>
// 深色背景
<Slider
minimumTrackTintColor="#0A84FF"
maximumTrackTintColor="#3A3A3C"
value={50}
/>
// 自定义对比色
<Slider
minimumTrackTintColor="#34C759"
maximumTrackTintColor="#F2F2F7"
value={70}
/>
thumbTintColor - 滑块手柄颜色
设置前景滑块手柄的颜色。手柄是用户拖动的圆形控件。
类型:string
默认值:白色(带阴影)
使用场景:
- 品牌色手柄
- 状态指示
- 视觉突出
// 蓝色手柄
<Slider
thumbTintColor="#007AFF"
value={50}
/>
// 与轨道同色
<Slider
minimumTrackTintColor="#34C759"
thumbTintColor="#34C759"
value={50}
/>
// 状态颜色
<Slider
thumbTintColor={isActive ? '#007AFF' : '#8E8E93'}
value={50}
/>
⚠️ 注意:此属性将覆盖设置的
thumbImage属性。如果同时设置了thumbTintColor和thumbImage,图片会以指定颜色着色。
thumbImage - 滑块手柄图片
为滑块手柄设置自定义图片,实现个性化的滑块外观。
类型:ImageSource
使用场景:
- 自定义手柄形状
- 品牌图标
- 特殊视觉效果
// 使用本地图片
<Slider
thumbImage={require('./custom-thumb.png')}
value={50}
/>
// 使用不同状态的图片
const [isDragging, setIsDragging] = useState(false);
<Slider
thumbImage={isDragging
? require('./thumb-active.png')
: require('./thumb-normal.png')
}
value={50}
onSlidingStart={() => setIsDragging(true)}
onSlidingComplete={() => setIsDragging(false)}
/>
💡 提示:使用 thumbImage 属性时请确保引入的图片路径地址正确,可检查
harmony/entry/src/main/resources/rawfile/assets目录下是否被打包至静态资源目录。建议图片尺寸适中,过大可能影响性能。
trackStyle - 轨道样式
自定义轨道的样式(仅限 Android)。
类型:ViewStyle
<Slider
trackStyle={{
height: 8,
borderRadius: 4,
}}
value={50}
/>
thumbStyle - 手柄样式
自定义手柄的样式(仅限 Android)。
类型:ViewStyle
<Slider
thumbStyle={{
width: 24,
height: 24,
borderRadius: 12,
backgroundColor: '#007AFF',
}}
value={50}
/>
限制属性
lowerLimit - 滑动下限
设置滑动下限,用户将无法滑到该限制以下。适用于需要设置最小阈值的场景。
类型:number
默认值:minimumValue
使用场景:
- 最小音量限制
- 最低价格筛选
- 最小值约束
// 最小只能滑到 20
<Slider
minimumValue={0}
maximumValue={100}
lowerLimit={20}
value={50}
/>
// 价格筛选 - 最低价格
<Slider
minimumValue={0}
maximumValue={10000}
lowerLimit={100} // 最低 100 元
value={500}
step={100}
/>
// 音量控制 - 保持最小音量
<Slider
minimumValue={0}
maximumValue={100}
lowerLimit={10} // 最低 10% 音量
value={volume}
onValueChange={setVolume}
/>
upperLimit - 滑动上限
设置滑动上限,用户将无法滑到该限制以上。适用于需要设置最大阈值的场景。
类型:number
默认值:maximumValue
使用场景:
- 最大音量限制
- 最高价格筛选
- 最大值约束
// 最大只能滑到 80
<Slider
minimumValue={0}
maximumValue={100}
upperLimit={80}
value={50}
/>
// 价格筛选 - 最高价格
<Slider
minimumValue={0}
maximumValue={10000}
upperLimit={8000} // 最高 8000 元
value={5000}
step={100}
/>
// 亮度控制 - 保护眼睛
<Slider
minimumValue={0}
maximumValue={100}
upperLimit={80} // 最高 80% 亮度
value={brightness}
onValueChange={setBrightness}
/>
事件属性
onValueChange - 值变化回调
用户拖动滑块时持续调用的回调函数,用于实时获取滑块当前值。
类型:(value: number) => void
参数:
value: 当前滑块值
使用场景:
- 实时更新显示值
- 联动其他组件
- 即时反馈
const [value, setValue] = useState(50);
<Slider
value={value}
onValueChange={(newValue) => {
console.log('当前值:', newValue);
setValue(newValue);
}}
/>
// 实时显示
<View>
<Text>当前值: {Math.round(value)}</Text>
<Slider
value={value}
onValueChange={setValue}
minimumValue={0}
maximumValue={100}
/>
</View>
// 联动其他组件
const [opacity, setOpacity] = useState(1);
<View>
<View style={{ opacity, width: 100, height: 100, backgroundColor: 'blue' }} />
<Slider
value={opacity}
onValueChange={setOpacity}
minimumValue={0}
maximumValue={1}
/>
</View>
⚠️ 注意:此回调在拖动过程中会频繁调用,避免在其中执行耗时操作。
onSlidingStart - 开始滑动回调
用户开始拖动滑块时调用的回调函数,初始值作为参数传递。
类型:(value: number) => void
参数:
value: 开始滑动时的初始值
使用场景:
- 记录滑动起点
- 暂停其他操作
- 显示滑动提示
const [isSliding, setIsSliding] = useState(false);
const [startValue, setStartValue] = useState(0);
<Slider
value={value}
onSlidingStart={(startValue) => {
console.log('开始滑动,初始值:', startValue);
setIsSliding(true);
setStartValue(startValue);
}}
onSlidingComplete={() => setIsSliding(false)}
/>
// 暂停播放
const [isPlaying, setIsPlaying] = useState(true);
<Slider
value={currentTime}
onSlidingStart={() => setIsPlaying(false)}
onSlidingComplete={(time) => {
seekTo(time);
setIsPlaying(true);
}}
/>
onSlidingComplete - 滑动完成回调
用户释放滑块时调用的回调函数,当前值作为参数传递。这是执行最终操作的最佳时机。
类型:(value: number) => void
参数:
value: 滑动完成时的最终值
使用场景:
- 提交数据到服务器
- 保存设置
- 执行搜索
<Slider
value={value}
onSlidingComplete={(finalValue) => {
console.log('滑动完成,最终值:', finalValue);
// 提交数据到服务器
submitValue(finalValue);
}}
/>
// 价格筛选 - 触发搜索
<Slider
value={maxPrice}
onSlidingComplete={(price) => {
// 只在滑动完成时触发搜索
searchProducts({ maxPrice: price });
}}
/>
// 保存设置
<Slider
value={volume}
onSlidingComplete={(vol) => {
// 保存音量设置
AsyncStorage.setItem('volume', vol.toString());
}}
/>
步骤标记属性(5.0.1+)
StepMarker - 步骤标记组件
用于在滑轨上渲染每个刻度的自定义组件,可根据滑块位置动态改变该刻度的样式。这是实现可视化刻度的强大功能。
类型:React.ComponentType<StepMarkerProps>
StepMarkerProps 接口:
| 属性 | 类型 | 说明 |
|---|---|---|
| stepMarked | boolean | 当前刻度是否为滑块所在位置或之前 |
| currentValue | number | Slider 当前滑块位置的数值 |
| index | number | 当前刻度标记实例的渲染索引号 |
| min | number | Slider 的最小值 |
| max | number | Slider 的最大值 |
使用场景:
- 显示刻度值
- 高亮当前位置
- 自定义刻度样式
interface MarkerProps {
stepMarked: boolean;
currentValue: number;
index: number;
min: number;
max: number;
}
const StepMarker: React.FC<MarkerProps> = ({ stepMarked, index }) => {
const stepValue = index * 25;
return (
<View style={[
styles.marker,
stepMarked && styles.markerActive,
]}>
<Text style={[
styles.markerText,
stepMarked && styles.markerTextActive,
]}>
{stepValue}
</Text>
</View>
);
};
<Slider
minimumValue={0}
maximumValue={100}
step={25}
StepMarker={StepMarker}
value={value}
onValueChange={setValue}
/>
const styles = StyleSheet.create({
marker: {
width: 28,
height: 28,
borderRadius: 14,
backgroundColor: '#E5E5EA',
justifyContent: 'center',
alignItems: 'center',
},
markerActive: {
backgroundColor: '#5856D6',
},
markerText: {
fontSize: 10,
fontWeight: '600',
color: '#999',
},
markerTextActive: {
color: '#FFF',
},
});
renderStepNumber - 显示步骤编号
启用步骤编号显示功能,步骤编号将显示在滑轨下方。这是快速实现刻度显示的简便方法。
类型:boolean
默认值:false
使用场景:
- 快速显示刻度
- 简单刻度需求
- 无需自定义样式
// 启用步骤编号
<Slider
minimumValue={0}
maximumValue={100}
step={25}
renderStepNumber={true}
value={50}
/>
// 配合 step 使用
<Slider
minimumValue={0}
maximumValue={10}
step={2}
renderStepNumber={true}
value={6}
/>
// 显示:0, 2, 4, 6, 8, 10
其他属性
tapToSeek - 点击定位(iOS)
允许点击滑块轨道来设置手柄位置,提供更便捷的交互方式。
类型:boolean
默认值:false(iOS)
使用场景:
- 快速定位
- 提升用户体验
<Slider
tapToSeek={true}
value={50}
/>
⚠️ 注意:此属性在 HarmonyOS 上暂不支持。
vertical - 垂直方向
如果设置为 true,则将滑块方向更改为垂直。适用于特殊布局需求。
类型:boolean
默认值:false
使用场景:
- 垂直布局
- 特殊 UI 设计
- 音量/亮度控制条
// 垂直滑块
<Slider
vertical={true}
style={{ height: 200, width: 40 }}
value={50}
/>
// 垂直音量控制
<View style={{ flexDirection: 'row', alignItems: 'center' }}>
<Text>🔈</Text>
<Slider
vertical={true}
style={{ height: 150, width: 40 }}
value={volume}
onValueChange={setVolume}
/>
<Text>🔊</Text>
</View>
maximumTrackImage - 最大轨道图片(iOS)
为未滑动部分的轨道分配图像,仅支持静态图像。
类型:ImageSource
<Slider
maximumTrackImage={require('./track.png')}
value={50}
/>
⚠️ 注意:此属性在 HarmonyOS 上暂不支持。
minimumTrackImage - 最小轨道图片(iOS)
为已滑动部分的轨道分配图像,仅支持静态图像。
类型:ImageSource
<Slider
minimumTrackImage={require('./track-active.png')}
value={50}
/>
⚠️ 注意:此属性在 HarmonyOS 上暂不支持。
trackImage - 轨道图片(iOS)
为整个轨道分配单个图像,仅支持静态图像。
类型:ImageSource
<Slider
trackImage={require('./track.png')}
value={50}
/>
⚠️ 注意:此属性在 HarmonyOS 上暂不支持。
📋 完整示例

import React, { useState, useEffect } from "react";
import {
SafeAreaView,
ScrollView,
StyleSheet,
Text,
View,
TouchableOpacity,
} from "react-native";
import Slider from "@react-native-community/slider";
const App: React.FC = () => {
const [basicValue, setBasicValue] = useState(50);
const [volume, setVolume] = useState(50);
const [brightness, setBrightness] = useState(70);
const [stepValue, setStepValue] = useState(50);
const [isPlaying, setIsPlaying] = useState(false);
const [currentTime, setCurrentTime] = useState(0);
const duration = 180;
useEffect(() => {
let interval: ReturnType<typeof setInterval>;
if (isPlaying && currentTime < duration) {
interval = setInterval(() => {
setCurrentTime((prev) => Math.min(duration, prev + 1));
}, 1000);
}
return () => clearInterval(interval);
}, [isPlaying, currentTime]);
const formatTime = (seconds: number) => {
const mins = Math.floor(seconds / 60);
const secs = seconds % 60;
return `${mins}:${secs.toString().padStart(2, "0")}`;
};
const getVolumeIcon = () => {
if (volume === 0) return "🔇";
if (volume < 30) return "🔈";
if (volume < 70) return "🔉";
return "🔊";
};
const StepMarker: React.FC<{
stepMarked: boolean;
currentValue: number;
index: number;
}> = ({ stepMarked, index }) => (
<View style={[styles.marker, stepMarked && styles.markerActive]}>
<Text style={[styles.markerText, stepMarked && styles.markerTextActive]}>
{index * 25}
</Text>
</View>
);
return (
<SafeAreaView style={styles.container}>
<ScrollView contentContainerStyle={styles.content}>
<Text style={styles.title}>滑块组件示例</Text>
{/* 基础滑块 */}
<View style={styles.card}>
<Text style={styles.cardTitle}>基础滑块</Text>
<Text style={styles.valueText}>当前值: {Math.round(basicValue)}</Text>
<Slider
style={styles.slider}
minimumValue={0}
maximumValue={100}
value={basicValue}
onValueChange={setBasicValue}
minimumTrackTintColor="#007AFF"
maximumTrackTintColor="#E5E5EA"
thumbTintColor="#007AFF"
/>
<View style={styles.rangeLabels}>
<Text style={styles.rangeLabel}>0</Text>
<Text style={styles.rangeLabel}>100</Text>
</View>
</View>
{/* 系统控制 */}
<View style={styles.card}>
<Text style={styles.cardTitle}>系统控制</Text>
<View style={styles.controlRow}>
<Text style={styles.icon}>{getVolumeIcon()}</Text>
<Text style={styles.controlLabel}>音量</Text>
<Text style={styles.controlValue}>{Math.round(volume)}%</Text>
</View>
<Slider
style={styles.slider}
minimumValue={0}
maximumValue={100}
value={volume}
onValueChange={setVolume}
minimumTrackTintColor="#007AFF"
maximumTrackTintColor="#E5E5EA"
thumbTintColor="#007AFF"
/>
<View style={styles.controlRow}>
<Text style={styles.icon}>{brightness < 50 ? "🌙" : "☀️"}</Text>
<Text style={styles.controlLabel}>亮度</Text>
<Text style={styles.controlValue}>{Math.round(brightness)}%</Text>
</View>
<Slider
style={styles.slider}
minimumValue={0}
maximumValue={100}
value={brightness}
onValueChange={setBrightness}
minimumTrackTintColor="#FF9500"
maximumTrackTintColor="#E5E5EA"
thumbTintColor="#FF9500"
/>
</View>
{/* 带步骤标记的滑块 */}
<View style={styles.card}>
<Text style={styles.cardTitle}>带步骤标记的滑块</Text>
<Text style={styles.valueText}>当前值: {Math.round(stepValue)}</Text>
<Slider
style={styles.slider}
minimumValue={0}
maximumValue={100}
step={25}
value={stepValue}
onValueChange={setStepValue}
minimumTrackTintColor="#5856D6"
maximumTrackTintColor="#E5E5EA"
thumbTintColor="#5856D6"
StepMarker={StepMarker}
/>
</View>
{/* 播放进度 */}
<View style={styles.card}>
<Text style={styles.cardTitle}>播放进度</Text>
<View style={styles.songInfo}>
<View style={styles.albumArt}>
<Text style={styles.albumArtText}>🎵</Text>
</View>
<View style={styles.songDetails}>
<Text style={styles.songTitle}>示例歌曲</Text>
<Text style={styles.artistName}>未知艺术家</Text>
</View>
</View>
<Slider
style={styles.slider}
minimumValue={0}
maximumValue={duration}
value={currentTime}
onValueChange={setCurrentTime}
onSlidingStart={() => setIsPlaying(false)}
minimumTrackTintColor="#007AFF"
maximumTrackTintColor="#E5E5EA"
thumbTintColor="#007AFF"
/>
<View style={styles.timeLabels}>
<Text style={styles.timeLabel}>{formatTime(currentTime)}</Text>
<Text style={styles.timeLabel}>{formatTime(duration)}</Text>
</View>
<View style={styles.controls}>
<TouchableOpacity
style={styles.controlButton}
onPress={() => setCurrentTime(0)}
>
<Text style={styles.controlIcon}>⏮️</Text>
</TouchableOpacity>
<TouchableOpacity
style={styles.playButton}
onPress={() => setIsPlaying(!isPlaying)}
>
<Text style={styles.playIcon}>{isPlaying ? "⏸️" : "▶️"}</Text>
</TouchableOpacity>
<TouchableOpacity
style={styles.controlButton}
onPress={() => {
setCurrentTime(0);
setIsPlaying(false);
}}
>
<Text style={styles.controlIcon}>⏭️</Text>
</TouchableOpacity>
</View>
</View>
{/* 禁用状态 */}
<View style={styles.card}>
<Text style={styles.cardTitle}>禁用状态</Text>
<Slider
style={styles.slider}
minimumValue={0}
maximumValue={100}
value={30}
disabled={true}
minimumTrackTintColor="#007AFF"
maximumTrackTintColor="#E5E5EA"
thumbTintColor="#007AFF"
/>
</View>
</ScrollView>
</SafeAreaView>
);
};
const styles = StyleSheet.create({
container: { flex: 1, backgroundColor: "#F5F5F5" },
content: { padding: 16 },
title: { fontSize: 24, fontWeight: "bold", marginBottom: 20, color: "#333", textAlign: "center" },
card: { backgroundColor: "#FFF", borderRadius: 12, padding: 16, marginBottom: 16 },
cardTitle: { fontSize: 16, fontWeight: "600", marginBottom: 12, color: "#333" },
valueText: { fontSize: 14, color: "#007AFF", fontWeight: "500", marginBottom: 8, textAlign: "center" },
slider: { width: "100%", height: 40 },
rangeLabels: { flexDirection: "row", justifyContent: "space-between" },
rangeLabel: { fontSize: 12, color: "#999" },
controlRow: { flexDirection: "row", alignItems: "center", marginBottom: 8 },
icon: { fontSize: 20, marginRight: 8 },
controlLabel: { fontSize: 14, color: "#666", flex: 1 },
controlValue: { fontSize: 14, fontWeight: "600", color: "#333" },
marker: { width: 24, height: 24, borderRadius: 12, backgroundColor: "#E5E5EA", justifyContent: "center", alignItems: "center" },
markerActive: { backgroundColor: "#5856D6" },
markerText: { fontSize: 10, fontWeight: "600", color: "#999" },
markerTextActive: { color: "#FFF" },
songInfo: { flexDirection: "row", alignItems: "center", marginBottom: 16 },
albumArt: { width: 60, height: 60, borderRadius: 8, backgroundColor: "#F0F0F0", justifyContent: "center", alignItems: "center" },
albumArtText: { fontSize: 24 },
songDetails: { marginLeft: 12, flex: 1 },
songTitle: { fontSize: 16, fontWeight: "600", color: "#333", marginBottom: 2 },
artistName: { fontSize: 12, color: "#999" },
timeLabels: { flexDirection: "row", justifyContent: "space-between", marginTop: 4 },
timeLabel: { fontSize: 12, color: "#999" },
controls: { flexDirection: "row", justifyContent: "center", alignItems: "center", marginTop: 16 },
controlButton: { padding: 8 },
controlIcon: { fontSize: 24 },
playButton: { backgroundColor: "#007AFF", width: 56, height: 56, borderRadius: 28, justifyContent: "center", alignItems: "center", marginHorizontal: 16 },
playIcon: { fontSize: 24 },
});
export default App;
⚠️ 遗留问题
更多推荐



所有评论(0)