【React Native】自定义虚线控件DashedLine

React Native DashedLine 自定义虚线组件文档

组件介绍

DashedLine 是一个自定义的 React Native 虚线控件组件,支持水平和垂直两种方向,可自由控制虚线的外观参数。

基础使用示例

import React from 'react';
import { View } from 'react-native';
import DashedLine from 'react-native-dashed-line-component';

const App = () => {
  return (
    <View style={{ padding: 20 }}>
      {/* 基本水平虚线 */}
      <DashedLine />
      
      <View style={{ marginVertical: 20 }} />
      
      {/* 垂直虚线 */}
      <View style={{ height: 200 }}>
        <DashedLine direction="vertical" />
      </View>
    </View>
  );
};

export default App;

自定义样式示例

// 高级定制虚线
<DashedLine 
  direction="horizontal"
  dashLength={8}
  dashGap={3}
  dashThickness={2}
  dashColor="#3498db"
  dashRadius={3}
  style={{ marginVertical: 15, backgroundColor: '#f9f9f9' }}
/>

API 文档

Props

属性名类型默认值描述
direction`‘horizontal’‘vertical’`'horizontal'
dashLengthnumber6每个虚线段的长度(像素)
dashGapnumber4虚线之间的间隙(像素)
dashThicknessnumber1虚线的粗细(像素)
dashColorstring'#999'虚线的颜色
dashRadiusnumber0虚线片段的圆角半径(像素)
styleStyleProp<ViewStyle>{}容器自定义样式

源码实现

如果您想基于现有组件进行自定义开发,可参考核心代码逻辑:

import React from 'react';
import {StyleProp, StyleSheet, View, ViewStyle} from 'react-native';

interface DashedLineProps {
  /** 虚线方向: 'horizontal' (水平) 或 'vertical' (垂直) */
  direction?: 'horizontal' | 'vertical';
  /** 每个虚线段的长度 (像素) */
  dashLength?: number;
  /** 虚线之间的间隙 (像素) */
  dashGap?: number;
  /** 虚线的粗细 (像素) */
  dashThickness?: number;
  /** 虚线的颜色 */
  dashColor?: string;
  /** 容器的自定义样式 */
  style?: StyleProp<ViewStyle>;
  /** 虚线的圆角半径 */
  dashRadius?: number;
}

const DashedLine = ({
  direction = 'horizontal',
  dashLength = 6,
  dashGap = 4,
  dashThickness = 1,
  dashColor = '#999',
  dashRadius = 0,
  style,
}: DashedLineProps) => {
  const [parentWidth, setParentWidth] = React.useState(0);
  const [parentHeight, setParentHeight] = React.useState(0);

  // 计算所需片段数量和容器尺寸
  const isHorizontal = direction === 'horizontal';
  const containerSize = isHorizontal ? parentWidth : parentHeight;
  const segmentSize = dashLength + dashGap;

  const containerStyle = [
    styles.container,
    isHorizontal ? styles.horizontal : styles.vertical,
  ];

  // 创建所有虚线片段的视图
  const renderSegments = () => {
    // 为简单起见,我们假设容器宽度为窗口宽度
    // 实际应用中可以使用 onLayout 获取精确尺寸
    const totalSegments = Math.ceil(
      (isHorizontal ? parentWidth : parentHeight) / segmentSize,
    );

    return Array.from({length: totalSegments}).map((_, idx) => (
      <View
        key={idx}
        style={[
          styles.dashSegment,
          isHorizontal ? styles.horizontalSegment : styles.verticalSegment,
          {
            backgroundColor: dashColor,
            width: isHorizontal ? dashLength : dashThickness,
            height: isHorizontal ? dashThickness : dashLength,
            borderRadius: dashRadius,
            marginRight: isHorizontal ? dashGap : 0,
            marginBottom: isHorizontal ? 0 : dashGap,
          },
        ]}
      />
    ));
  };

  return (
    <View
      style={[styles.containerOut, style]}
      onLayout={event => {
        setParentWidth(event.nativeEvent.layout.width);
        setParentHeight(event.nativeEvent.layout.height);
      }}>
      <View
        style={[
          ...containerStyle,
          {
            maxWidth: isHorizontal ? containerSize : dashThickness,
            height: isHorizontal ? dashThickness : containerSize,
            alignItems: 'center',
            justifyContent: 'center',
          },
        ]}>
        <View
          style={[
            styles.segmentContainer,
            isHorizontal
              ? styles.horizontalSegmentContainer
              : styles.verticalSegmentContainer,
          ]}>
          {renderSegments()}
        </View>
      </View>
    </View>
  );
};

const styles = StyleSheet.create({
  containerOut: {
    width: '100%',
  },
  container: {
    backgroundColor: 'transparent',
    overflow: 'hidden',
  },
  horizontal: {
    width: '100%',
    height: 1, // 默认高度会被覆盖
  },
  vertical: {
    width: 1, // 默认宽度会被覆盖
    height: '100%',
  },
  segmentContainer: {
    flexDirection: 'row',
  },
  horizontalSegmentContainer: {
    flexDirection: 'row',
  },
  verticalSegmentContainer: {
    flexDirection: 'column',
  },
  dashSegment: {
    backgroundColor: '#999',
  },
  horizontalSegment: {},
  verticalSegment: {},
});

export default DashedLine;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值