自定义 React Native 滑块

发布于 2025-01-11 02:08:01 字数 192 浏览 0 评论 0原文

有谁知道如何在反应本机中渲染滑块,如下所示,具有不同的部分?到目前为止,只见过一根线和一个点的滑块。

示例滑块

Does anyone know how to render a slider in react-native like the below, with distinct sections? So far, have only seen sliders with one line and one dot.

Example Slider

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

像你 2025-01-18 02:08:01

您可以使用 LayoutAnimation 来实现这种类型的滑块。找到下面的代码来完成它。

import React, { useState } from 'react';
import {Button,LayoutAnimation,Platform,StyleSheet,Text,UIManager,View} from 'react-native';

if (Platform.OS === 'android') {
  if (UIManager.setLayoutAnimationEnabledExperimental) {
    UIManager.setLayoutAnimationEnabledExperimental(true);
  }
}

const step = ['1', '2', '3', '4', '5', '6', '7'];
const activeColor = '#444';

export default function TrackingStatus() {
  const [activeIndex, setActive] = useState(0);
  const setActiveIndex = (val) => {
    LayoutAnimation.easeInEaseOut();
    setActive(val);
  };
  const marginLeft = (100 / (step.length - 1)) * activeIndex - 100 + '%';
  return (
    <View style={styles.constainer}>
      <Text style={styles.prop}>{activeIndex}</Text>
      <View style={styles.statusContainer}>
        <View style={styles.line}>
          <View style={[styles.activeLine, { marginLeft }]} />
        </View>
        {step.map((step, index) => (
          <View style={[styles.dot]} key={step}>
            <View
              style={[
                index <= activeIndex
                  ? { height: '100%', width: '100%' }
                  : { height: '0%', width: '0%' },
                { backgroundColor: activeColor, borderRadius: 20 },
              ]}
            />
          </View>
        ))}
      </View>
      <View style={styles.btns}>
        <Button
          title="prev"
          onPress={() => setActiveIndex(activeIndex - 1)}
          disabled={activeIndex <= 0}
        />
        <Button
          title="next"
          onPress={() => setActiveIndex(activeIndex + 1)}
          disabled={activeIndex >= step.length - 1}
        />
      </View>
    </View>
  );
}

const styles = StyleSheet.create({
  constainer: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    paddingHorizontal: 30,
  },
  statusContainer: {
    flexDirection: 'row',
    alignItems: 'center',
    width: '100%',
    height: 70,
    justifyContent: 'space-between',
  },
  dot: {
    height: 15,
    width: 15,
    borderRadius: 10,
    backgroundColor: '#ccc',
    overflow: 'hidden',
    alignItems: 'center',
    justifyContent: 'center',
  },    
  line: {
    height: 5,
    width: '100%',
    backgroundColor: '#ccc',
    position: 'absolute',
    borderRadius: 5,
    overflow: 'hidden',
  },
  activeLine: {
    height: '100%',
    width: '100%',
    backgroundColor: activeColor,
    borderRadius: 5,
  },
  btns: {
    width: '100%',
    flexDirection: 'row',
    justifyContent: 'space-evenly',
    marginTop: 20,
  },
  prop: {
    marginBottom: 20,
    width: 100,
    textAlign: 'center',
  },
});

在上面的代码中,我们只是根据需要创建了一个 UI 克隆,并添加了左边距以及用颜色填充点。就在更改 margin-left & 的状态之前点颜色,我们添加了布局动画以添加进度动画效果。

输出

我希望这个解释能帮助您理解工作原理

You can achieve this type of slider by using LayoutAnimation. Find the below code to get it done.

import React, { useState } from 'react';
import {Button,LayoutAnimation,Platform,StyleSheet,Text,UIManager,View} from 'react-native';

if (Platform.OS === 'android') {
  if (UIManager.setLayoutAnimationEnabledExperimental) {
    UIManager.setLayoutAnimationEnabledExperimental(true);
  }
}

const step = ['1', '2', '3', '4', '5', '6', '7'];
const activeColor = '#444';

export default function TrackingStatus() {
  const [activeIndex, setActive] = useState(0);
  const setActiveIndex = (val) => {
    LayoutAnimation.easeInEaseOut();
    setActive(val);
  };
  const marginLeft = (100 / (step.length - 1)) * activeIndex - 100 + '%';
  return (
    <View style={styles.constainer}>
      <Text style={styles.prop}>{activeIndex}</Text>
      <View style={styles.statusContainer}>
        <View style={styles.line}>
          <View style={[styles.activeLine, { marginLeft }]} />
        </View>
        {step.map((step, index) => (
          <View style={[styles.dot]} key={step}>
            <View
              style={[
                index <= activeIndex
                  ? { height: '100%', width: '100%' }
                  : { height: '0%', width: '0%' },
                { backgroundColor: activeColor, borderRadius: 20 },
              ]}
            />
          </View>
        ))}
      </View>
      <View style={styles.btns}>
        <Button
          title="prev"
          onPress={() => setActiveIndex(activeIndex - 1)}
          disabled={activeIndex <= 0}
        />
        <Button
          title="next"
          onPress={() => setActiveIndex(activeIndex + 1)}
          disabled={activeIndex >= step.length - 1}
        />
      </View>
    </View>
  );
}

const styles = StyleSheet.create({
  constainer: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    paddingHorizontal: 30,
  },
  statusContainer: {
    flexDirection: 'row',
    alignItems: 'center',
    width: '100%',
    height: 70,
    justifyContent: 'space-between',
  },
  dot: {
    height: 15,
    width: 15,
    borderRadius: 10,
    backgroundColor: '#ccc',
    overflow: 'hidden',
    alignItems: 'center',
    justifyContent: 'center',
  },    
  line: {
    height: 5,
    width: '100%',
    backgroundColor: '#ccc',
    position: 'absolute',
    borderRadius: 5,
    overflow: 'hidden',
  },
  activeLine: {
    height: '100%',
    width: '100%',
    backgroundColor: activeColor,
    borderRadius: 5,
  },
  btns: {
    width: '100%',
    flexDirection: 'row',
    justifyContent: 'space-evenly',
    marginTop: 20,
  },
  prop: {
    marginBottom: 20,
    width: 100,
    textAlign: 'center',
  },
});

In the above code, We simply create a UI clone as required and add margin-left as well as filling dots with colour. just before changing the state of margin-left & dot colour, we added layout animation to add an animation effect for progress.

Output
enter image description here

I hope this explanation will help you understand the working

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文