欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net

在这里插入图片描述

📋 前言

@react-native-community/slider 是 React Native 社区维护的滑块组件库,是 react-native-slider 的官方继任者。它提供了丰富的自定义选项,包括颜色、样式、步长、图像支持等,可以用于音量调节、亮度控制、进度条、数值选择等各种场景,完全兼容 Android、iOS、Windows、Web 和 HarmonyOS 五端。

🎯 库简介

基本信息
  • 库名称: @react-native-community/slider

  • 版本信息:

    • 4.4.4: 支持 RN 0.72 版本(@react-native-ohos/slider)
    • 5.0.1: 支持 RN 0.77 版本(@react-native-ohos/slider)
    • 5.1.2: 支持 RN 0.82 版本(@react-native-ohos/slider)
  • 官方仓库: https://github.com/react-native-oh-library/react-native-slider

  • 主要功能:

    • 创建可拖动的滑块控件

    • 支持自定义颜色和样式

    • 支持步长控制

    • 支持垂直方向

    • 支持反转方向

    • 兼容 Android、iOS、Windows、Web 和 HarmonyOS- 兼容性验证:

    • RNOH 0.72.96 + HarmonyOS 6.0.0 Release SDK

    • RNOH 0.77.18 + HarmonyOS 6.0.0 Release SDK

    • RNOH 0.82.1 + HarmonyOS 6.0.1 Release SDK

为什么需要这个库?
  • 社区维护: 由 React Native 社区官方维护,是 react-native-slider 的继任者
  • 功能丰富: 支持更多自定义选项和高级功能
  • 跨平台一致: 在五端提供一致的渲染效果
  • 持续更新: 活跃的维护和更新,支持最新的 RN 版本
  • 易于使用: API 简单直观,易于集成

📦 安装步骤

1. 使用 npm 安装
npm install @react-native-ohos/slider@4.4.4-rc.1
2. 验证安装

安装完成后,检查 package.json 文件,应该能看到新增的依赖:

{
  "dependencies": {
    "@react-native-ohos/slider": "^4.4.4-rc.1",
    // ... 其他依赖
  }
}

🔧 HarmonyOS 平台配置 ⭐

1. 引入原生端代码

目前有两种方法:

方法一:通过 har 包引入(不推荐)

[!TIP] har 包位于三方库安装路径的 harmony 文件夹下。

打开 harmony/entry/oh-package.json5,添加以下依赖:

"dependencies": {
    "@rnoh/react-native-openharmony": "file:../react_native_openharmony",
    "@react-native-ohos/slider": "file:../../node_modules/@react-native-ohos/slider/harmony/slider.har"
}

点击右上角的 sync 按钮

或者在终端执行:

cd harmony/entry
ohpm install
方法二:直接链接源码

步骤 1: 把 <RN工程>/node_modules/@react-native-ohos/slider/harmony 目录下的源码 slider 复制到 harmony 工程根目录下。

步骤 2: 在 harmony 工程根目录的 build-profile.json5 添加以下模块:

modules: [
  ...
  {
    name: 'slider',
    srcPath: './slider',
  }
]

步骤 3: 打开 slider/oh-package.json5,修改 @rnoh/react-native-openharmony 和项目的版本一致。

步骤 4: 打开 harmony/entry/oh-package.json5,添加以下依赖:

"dependencies": {
  "@rnoh/react-native-openharmony": "0.72.90",
  "@react-native-ohos/slider": "file:../slider"
}

步骤 5: 点击 DevEco Studio 右上角的 sync 按钮

2. 配置 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)

# RNOH_BEGIN: add_package_subdirectories
add_subdirectory("../../../../sample_package/src/main/cpp" ./sample-package)
+ add_subdirectory("${OH_MODULES}/@react-native-ohos/slider/src/main/cpp" ./slider)
# RNOH_END: add_package_subdirectories

add_library(rnoh_app SHARED
    "./PackageProvider.cpp"
    "${RNOH_CPP_DIR}/RNOHAppNapiBridge.cpp"
)

target_link_libraries(rnoh_app PUBLIC rnoh)

# RNOH_BEGIN: link_packages
target_link_libraries(rnoh_app PUBLIC rnoh_sample_package)
+ target_link_libraries(rnoh_app PUBLIC rnoh_slider)
# RNOH_END: link_packages

打开 harmony/entry/src/main/cpp/PackageProvider.cpp,添加:

#include "RNOH/PackageProvider.h"
#include "SamplePackage.h"
+ #include "SliderPackage.h"

using namespace rnoh;

std::vector<std::shared_ptr<Package>> PackageProvider::getPackages(Package::Context ctx) {
    return {
      std::make_shared<SamplePackage>(ctx),
+     std::make_shared<SliderPackage>(ctx)
    };
}
3. 在 ArkTS 侧引入 slider 组件

找到 function buildCustomRNComponent(),一般位于 harmony/entry/src/main/ets/pages/index.etsharmony/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,
+   })
+ }
 ...
}

[!TIP] 本库使用了混合方案,需要添加组件名。

harmony/entry/src/main/ets/pages/index.etsharmony/entry/src/main/ets/rn/LoadBundle.ets 找到常量 arkTsComponentNames 在其数组里添加组件名:

const arkTsComponentNames: Array<string> = [
  SampleView.NAME,
  GeneratedSampleView.NAME,
  PropsDisplayer.NAME,
+ SLIDER_TYPE
  ];
4. 运行

点击右上角的 sync 按钮

或者在终端执行:

cd harmony/entry
ohpm install

然后编译、运行即可。

💻 完整代码示例

下面是一个完整的示例,展示了 @react-native-community/slider 的各种使用场景:

import React, { useState } from 'react';
import {
  View,
  Text,
  StyleSheet,
  ScrollView,
  StatusBar,
  SafeAreaView,
  Alert,
} from 'react-native';
import Slider from '@react-native-community/slider';

function SliderDemo() {
  const [slider1Value, setSlider1Value] = useState(0.2);
  const [slider2Value, setSlider2Value] = useState(0.5);
  const [slider3Value, setSlider3Value] = useState(0.7);
  const [slider4Value, setSlider4Value] = useState(0.3);
  const [slider5Value, setSlider5Value] = useState(0.4);
  const [slider6Value, setSlider6Value] = useState(0.2);
  const [slider7Value, setSlider7Value] = useState(0.5);
  const [slider8Value, setSlider8Value] = useState(0.6);
  const [slider9Value, setSlider9Value] = useState(0.2);
  const [slider10Value, setSlider10Value] = useState(0.4);
  const [slider11Value, setSlider11Value] = useState(0.5);

  return (
    <SafeAreaView style={styles.container}>
      <StatusBar barStyle="dark-content" backgroundColor="#ffffff" />
      <View style={styles.header}>
        <Text style={styles.headerTitle}>Slider 滑块组件</Text>
      </View>

      <ScrollView style={styles.scrollView}>
        {/* 示例 1: 默认样式 */}
        <View style={styles.section}>
          <Text style={styles.sectionTitle}>1. 默认样式</Text>
          <Slider
            style={styles.slider}
            value={slider1Value}
            onValueChange={setSlider1Value}
          />
          <Text style={styles.valueText}>: {slider1Value.toFixed(2)}</Text>
        </View>

        {/* 示例 2: 自定义颜色 */}
        <View style={styles.section}>
          <Text style={styles.sectionTitle}>2. 自定义颜色</Text>
          <Slider
            style={styles.slider}
            value={slider2Value}
            onValueChange={setSlider2Value}
            minimumTrackTintColor="#1A9274"
            maximumTrackTintColor="#D3D3D3"
            thumbTintColor="#1A9274"
          />
          <Text style={styles.valueText}>: {slider2Value.toFixed(2)}</Text>
        </View>

        {/* 示例 3: 自定义范围 */}
        <View style={styles.section}>
          <Text style={styles.sectionTitle}>3. 自定义范围 (0-100)</Text>
          <Slider
            style={styles.slider}
            value={slider3Value}
            onValueChange={setSlider3Value}
            minimumValue={0}
            maximumValue={100}
            minimumTrackTintColor="#FF6B6B"
            thumbTintColor="#FF6B6B"
          />
          <Text style={styles.valueText}>: {slider3Value.toFixed(0)}</Text>
        </View>

        {/* 示例 4: 带步长 */}
        <View style={styles.section}>
          <Text style={styles.sectionTitle}>4. 带步长 (step=0.1)</Text>
          <Slider
            style={styles.slider}
            value={slider4Value}
            onValueChange={setSlider4Value}
            step={0.1}
            minimumTrackTintColor="#4ECDC4"
            thumbTintColor="#4ECDC4"
          />
          <Text style={styles.valueText}>: {slider4Value.toFixed(1)}</Text>
        </View>

        {/* 示例 5: 禁用状态 */}
        <View style={styles.section}>
          <Text style={styles.sectionTitle}>5. 禁用状态</Text>
          <Slider
            style={styles.slider}
            value={slider5Value}
            onValueChange={setSlider5Value}
            disabled={true}
            minimumTrackTintColor="#CCCCCC"
            maximumTrackTintColor="#E0E0E0"
            thumbTintColor="#999999"
          />
          <Text style={styles.valueText}>: {slider5Value.toFixed(2)} (禁用)</Text>
        </View>

        {/* 示例 6: 反转方向 */}
        <View style={styles.section}>
          <Text style={styles.sectionTitle}>6. 反转方向</Text>
          <Slider
            style={styles.slider}
            value={slider6Value}
            onValueChange={setSlider6Value}
            inverted={true}
            minimumTrackTintColor="#FF9F43"
            thumbTintColor="#FF9F43"
          />
          <Text style={styles.valueText}>: {slider6Value.toFixed(2)}</Text>
        </View>

        {/* 示例 7: 事件回调 */}
        <View style={styles.section}>
          <Text style={styles.sectionTitle}>7. 事件回调</Text>
          <Slider
            style={styles.slider}
            value={slider7Value}
            onValueChange={setSlider7Value}
            onSlidingStart={() => {
              console.log('开始拖动');
            }}
            onSlidingComplete={(value) => {
              Alert.alert('拖动完成', `最终值: ${value.toFixed(2)}`);
            }}
            minimumTrackTintColor="#54A0FF"
            thumbTintColor="#54A0FF"
          />
          <Text style={styles.valueText}>: {slider7Value.toFixed(2)}</Text>
        </View>

        {/* 示例 8: 滑动限制 */}
        <View style={styles.section}>
          <Text style={styles.sectionTitle}>8. 滑动限制 (0.3-0.7)</Text>
          <Slider
            style={styles.slider}
            value={slider8Value}
            onValueChange={setSlider8Value}
            lowerLimit={0.3}
            upperLimit={0.7}
            minimumTrackTintColor="#FF6B9D"
            thumbTintColor="#FF6B9D"
          />
          <Text style={styles.valueText}>: {slider8Value.toFixed(2)}</Text>
        </View>

        {/* 示例 9: 垂直方向 */}
        <View style={styles.section}>
          <Text style={styles.sectionTitle}>9. 垂直方向</Text>
          <View style={styles.verticalContainer}>
            <Slider
              style={styles.verticalSlider}
              value={slider9Value}
              onValueChange={setSlider9Value}
              vertical={true}
              minimumTrackTintColor="#A55EEA"
              thumbTintColor="#A55EEA"
            />
            <Text style={styles.valueText}>: {slider9Value.toFixed(2)}</Text>
          </View>
        </View>

{/* 示例 10: 大号滑块 */}
        <View style={styles.section}>
          <Text style={styles.sectionTitle}>10. 大号滑块</Text>
          <Slider
            style={styles.largeSlider}
            value={slider10Value}
            onValueChange={setSlider10Value}
            minimumTrackTintColor="#6C5CE7"
            thumbTintColor="#6C5CE7"
          />
          <Text style={styles.valueText}>: {slider10Value.toFixed(2)}</Text>
        </View>
      </ScrollView>
    </SafeAreaView>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#f5f5f5',
  },
  header: {
    backgroundColor: '#ffffff',
    paddingHorizontal: 16,
    paddingVertical: 12,
    borderBottomWidth: 1,
    borderBottomColor: '#e0e0e0',
  },
  headerTitle: {
    fontSize: 20,
    fontWeight: 'bold',
    color: '#333333',
  },
  scrollView: {
    flex: 1,
  },
  section: {
    backgroundColor: '#ffffff',
    marginTop: 12,
    paddingHorizontal: 16,
    paddingVertical: 16,
  },
  sectionTitle: {
    fontSize: 18,
    fontWeight: 'bold',
    color: '#333333',
    marginBottom: 12,
  },
  slider: {
    width: '100%',
    height: 40,
  },
  verticalContainer: {
    flexDirection: 'row',
    alignItems: 'center',
    height: 200,
  },
  verticalSlider: {
    width: 40,
    height: 200,
  },
  largeSlider: {
    width: '100%',
    height: 60,
  },
  valueText: {
    fontSize: 14,
    color: '#666666',
    marginTop: 8,
    textAlign: 'center',
  },
  hintText: {
    fontSize: 12,
    color: '#999999',
    marginTop: 4,
    textAlign: 'center',
  },
  stepMarker: {
    width: 20,
    height: 20,
    borderRadius: 10,
    backgroundColor: '#e0e0e0',
    justifyContent: 'center',
    alignItems: 'center',
  },
  stepMarkerActive: {
    backgroundColor: '#FD79A8',
  },
  stepMarkerText: {
    fontSize: 10,
    color: '#ffffff',
    fontWeight: 'bold',
  },
});

export default SliderDemo;

🎨 实际应用场景

完整示例代码已展示了以下实际应用场景:

  • 默认样式: 使用默认配置创建基础滑块
  • 自定义颜色: 通过 minimumTrackTintColormaximumTrackTintColorthumbTintColor 自定义颜色
  • 自定义范围: 通过 minimumValuemaximumValue 设置取值范围
  • 步长控制: 使用 step 属性设置滑块步长
  • 禁用状态: 使用 disabled 属性禁用滑块
  • 反转方向: 使用 inverted 属性反转滑块方向
  • 事件回调: 监听 onSlidingStartonSlidingComplete 事件
  • 滑动限制: 使用 lowerLimitupperLimit 限制滑动范围
  • 垂直方向: 使用 vertical 属性创建垂直滑块
  • 大号滑块: 通过 style 增加滑块尺寸

⚠️ 注意事项与最佳实践

1. 值的范围
  • 默认范围是 0 到 1

  • 可以通过 minimumValuemaximumValue 自定义范围

  • step 值应该在 0 到 (maximumValue - minimumValue) 之间

  • lowerLimitupperLimit 用于限制滑动范围(仅对数值生效)

2. 性能优化
  • 避免在 onValueChange 中执行复杂操作
  • 对于频繁的值更新,考虑使用节流或防抖
// 正确:使用节流
import { throttle } from 'lodash';

const handleValueChange = throttle((value: number) => {
  // 处理值变化
}, 100);

<Slider onValueChange={handleValueChange} />
4. 样式定制
// 推荐的样式配置
<Slider
  style={{ height: 40 }}  // 增加容器高度,方便触摸
  minimumTrackTintColor="#1A9274"  // 左侧轨道颜色
  maximumTrackTintColor="#D3D3D3"  // 右侧轨道颜色
  thumbTintColor="#1A9274"  // 滑块按钮颜色
/>
5. 事件处理
// 完整的事件处理
<Slider
  value={value}
  onValueChange={(value: number) => {
    // 拖动过程中持续触发
    console.log('值变化:', value);
  }}
  onSlidingStart={(value: number) => {
    // 开始拖动时触发
    console.log('开始拖动:', value);
  }}
  onSlidingComplete={(value: number) => {
    // 拖动完成时触发
    console.log('拖动完成:', value);
    // 这里可以执行最终操作,如保存数据
  }}
/>
6. 垂直滑块
// 垂直滑块
<Slider
  style={{ width: 40, height: 200 }}
  value={value}
  vertical={true}
  onValueChange={setValue}
/>
7. HarmonyOS 兼容性

在 HarmonyOS 上,滑块的渲染和行为与原生平台保持一致。

📊 遗留问题

目前已知的问题:

  • upperLimit 和 lowerLimit 只对数值生效,滑动限制不生效
  • 不支持滑轨设置图片
  • 未适配无障碍
  • 不支持点击滑块轨道来设置拇指位置
  • 不支持指定最大轨迹图像
  • 不支持分配最小轨道图像

📝 总结

通过集成 @react-native-community/slider,我们为项目添加了功能强大的滑块控件。这个库是 React Native 社区官方维护的,提供了丰富的自定义选项和高级功能,包括垂直方向、反转方向等,可以用于音量调节、亮度控制、进度条、数值选择等各种场景。

关键要点回顾
  • 安装依赖: npm install @react-native-ohos/slider
  • 配置平台:
    • 添加 har 包依赖
    • 配置 CMakeLists.txt
    • 引入 SliderPackage
    • 在 ArkTS 侧添加组件
  • 集成代码: 使用 import Slider from '@react-native-community/slider'
  • 支持功能: 自定义颜色、样式、步长、图片、垂直方向、反转方向等
  • 测试验证: 确保五端表现一致
常用属性快速参考
// 基本属性
value={0.5}                              // 当前值
disabled={false}                         // 是否禁用
minimumValue={0}                         // 最小值
maximumValue={1}                         // 最大值
step={0.1}                               // 步长

// 颜色属性
minimumTrackTintColor="#1A9274"          // 左侧轨道颜色
maximumTrackTintColor="#D3D3D3"          // 右侧轨道颜色
thumbTintColor="#1A9274"                 // 滑块按钮颜色

// 方向属性
inverted={false}                         // 是否反转方向
vertical={false}                         // 是否垂直方向

// 限制属性
lowerLimit={0.2}                         // 滑动下限
upperLimit={0.8}                         // 滑动上限

// 事件属性
onValueChange={(val: number) => {}}     // 值变化回调
onSlidingStart={(val: number) => {}}   // 开始拖动回调
onSlidingComplete={(val: number) => {}} // 拖动完成回调
Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐