在React Native中,开发自定义组件(例如一个`Tag`组件)通常涉及到创建React组件,并且实现一个点击事件处理器

在React Native中,开发自定义组件(例如一个Tag组件)通常涉及到创建React组件,并通过JSX在组件中定义其结构、样式和行为。以下是如何开发一个简单的Tag组件的步骤:

步骤 1: 创建组件文件

首先,创建一个新的React组件文件,例如Tag.js

步骤 2: 定义组件

Tag.js文件中,你可以定义一个简单的Tag组件。这个组件可以接受一些属性(props),比如文本内容、背景色、字体大小等,并使用这些属性来渲染组件。

javascript 复制代码
import React from 'react';
import { View, Text, StyleSheet } from 'react-native';

const Tag = ({ text, style }) => {
  return (
    <View style={[styles.tagContainer, style]}>
      <Text style={styles.tagText}>{text}</Text>
    </View>
  );
};

const styles = StyleSheet.create({
  tagContainer: {
    borderRadius: 5,
    paddingHorizontal: 10,
    paddingVertical: 5,
    backgroundColor: '007AFF', // 默认蓝色背景
    marginRight: 5, // 一些右外边距,以便多个标签可以水平排列
  },
  tagText: {
    color: 'white', // 默认白色文字
    fontSize: 14, // 默认字体大小
  }
});

export default Tag;

步骤 3: 使用组件

现在你可以在其他组件或页面中使用Tag组件了。例如,在另一个组件中导入并使用它:

javascript 复制代码
import React from 'react';
import { View } from 'react-native';
import Tag from './Tag'; // 确保路径正确

const App = () => {
  return (
    <View>
      <Tag text="标签1" />
      <Tag text="标签2" style={{ backgroundColor: 'green' }} /> {/* 自定义样式 */}
    </View>
  );
};

export default App;

扩展功能

你可以根据需要扩展Tag组件的功能,例如添加点击事件处理、不同的标签样式等。例如,添加一个点击事件处理器:

javascript 复制代码
const Tag = ({ text, style, onPress }) => {
  return (
    <View style={[styles.tagContainer, style]} onPress={onPress}>
      <Text style={styles.tagText}>{text}</Text>
    </View>
  );
};

然后在使用组件时传递一个点击事件处理器:

javascript 复制代码
<Tag text="可点击标签" onPress={() => alert('标签被点击了!')} />

这样,你就创建了一个可以自定义样式和行为的Tag组件,并且可以轻松地在React Native应用中使用它。


创建一个Tag组件真实代码演示:

js 复制代码
// App.tsx
import React, { useState } from 'react';
import { 
  View, 
  Text, 
  StyleSheet, 
  ScrollView, 
  SafeAreaView,
  Image,
  Dimensions,
  TouchableOpacity,
  Pressable
} from 'react-native';

// Base64 Icons for tag components
const TAG_ICONS = {
  close: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAACXBIWXMAAAsTAAALEwEAmpwYAAAFHmlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS42LWMxNDIgNzkuMTYwOTI0LCAyMDE3LzA3LzEzLTAxOjA2OjM5ICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIgeG1sbnM6cGhvdG9zaG9wPSJodHRwOi8vbnMuYWRvYmUuY29tL3Bob3Rvc2hvcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RFdnQ9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZUV2ZW50IyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ0MgMjAxOCAoV2luZG93cykiIHhtcDpDcmVhdGVEYXRlPSIyMDE5LTAxLTAzVDE2OjU1OjQ5KzA4OjAwIiB4bXA6TW9kaWZ5RGF0ZT0iMjAxOS0wMS0wM1QxNjo1NjoxNCswODowMCIgeG1wOk1ldGFkYXRhRGF0ZT0iMjAxOS0wMS0wM1QxNjo1NjoxNCswODowMCIgZGM6Zm9ybWF0PSJpbWFnZS9wbmciIHBob3Rvc2hvcDpDb2xvck1vZGU9IjMiIHBob3Rvc2hvcDpJQ0NQcm9maWxlPSJzUkdCIElFQzYxOTY2LTIuMSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDoyZjA5Y2Y0OS01YjVlLWY5NDctYjg3Yi0yZDM5YjQxMjQyZWIiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6MmYwOWNmNDktNWI1ZS1mOTQ3LWI4N2ItMmQzOWI0MTI0MmViIiB4bXBNTTpPcmlnaW5hbERvY3VtZW50SUQ9InhtcC5kaWQ6MmYwOWNmNDktNWI1ZS1mOTQ3LWI4N2ItMmQzOWI0MTI0MmViIj4gPHhtcE1NOkhpc3Rvcnk+IDxyZGY6U2VxPiA8cmRmOmxpIHN0RXZ0OmFjdGlvbj0iY3JlYXRlZCIgc3RFdnQ6aW5zdGFuY2VJRD0ieG1wLmlpZDoyZjA5Y2Y0OS01YjVlLWY5NDctYjg3Yi0yZDM5YjQxMjQyZWIiIHN0RXZ0OndoZW49IjIwMTktMDEtMDNUMTY6NTU6NDlaIiBzdEV2dDpzb2Z0d2FyZUFnZW50PSJBZG9iZSBQaG90b3Nob3AgQ0MgMjAxOCAoV2luZG93cykiLz4gPC9yZGY6U2VxPiA8L3htcE1NOkhpc3Rvcnk+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+Af/+/fz7+vn49/b19PPy8fDv7u3s6+rp6Ofm5eTj4uHg397d3Nva2djX1tXU09LR0M/OzczLysnIx8bFxMPCwcC/vr28u7q5uLe2tbSzsrGwr66trKuqqainpqWko6KhoJ+enZybmpmYl5aVlJOSkZCPjo2Mi4qJiIeGhYSDgoGAf359fHt6eXh3dnV0c3JxcG9ubWxramloZ2ZlZGNiYWBfXl1cW1pZWFdWVVRTUlFQT05NTEtKSUhHRkVEQ0JBQD8+PTw7Ojk4NzY1NDMyMTAvLi0sKyopKCcmJSQjIiEgHx4dHBsaGRgXFhUUExIREA8ODQwLCgkIBwYFBAMCAQAA//+gB5ZbAAAJRElEQVRoBe1ZaWxUVRQ+97030+k6U6Z0hk5npksptKW0bFJAWRB3UEFFjQuJKIoLJCZqYhRjNC5RFCMuaKJREhMXjAuKggsuRI0bGkEpWymltNBS2ulMZ9qZmfbe9+699715MzPTmdLS6STnfPPee+fc755zz3nnPcNwHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMx......',
  add: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAACXBIWXMAAAsTAAALEwEAmpwYAAAFHmlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS42LWMxNDIgNzkuMTYwOTI0LCAyMDE3LzA3LzEzLTAxOjA2OjM5ICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIgeG1sbnM6cGhvdG9zaG9wPSJodHRwOi8vbnMuYWRvYmUuY29tL3Bob3Rvc2hvcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RFdnQ9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZUV2ZW50IyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ0MgMjAxOCAoV2luZG93cykiIHhtcDpDcmVhdGVEYXRlPSIyMDE5LTAxLTAzVDE2OjU2OjIwKzA4OjAwIiB4bXA6TW9kaWZ5RGF0ZT0iMjAxOS0wMS0wM1QxNjo1Njo0NSswODowMCIgeG1wOk1ldGFkYXRhRGF0ZT0iMjAxOS0wMS0wM1QxNjo1Njo0NSswODowMCIgZGM6Zm9ybWF0PSJpbWFnZS9wbmciIHBob3Rvc2hvcDpDb2xvck1vZGU9IjMiIHBob3Rvc2hvcDpJQ0NQcm9maWxlPSJzUkdCIElFQzYxOTY2LTIuMSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDoyZjE5Y2Y0OS01YjVlLWY5NDctYjg3Yi0yZDM5YjQxMjQyZWIiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6MmYxOWNmNDktNWI1ZS1mOTQ3LWI4N2ItMmQzOWI0MTI0MmViIiB4bXBNTTpPcmlnaW5hbERvY3VtZW50SUQ9InhtcC5kaWQ6MmYxOWNmNDktNWI1ZS1mOTQ3LWI4N2ItMmQzOWI0MTI0MmViIj4gPHhtcE1NOkhpc3Rvcnk+IDxyZGY6U2VxPiA8cmRmOmxpIHN0RXZ0OmFjdGlvbj0iY3JlYXRlZCIgc3RFdnQ6aW5zdGFuY2VJRD0ieG1wLmlpZDoyZjE5Y2Y0OS01YjVlLWY5NDctYjg3Yi0yZDM5YjQxMjQyZWIiIHN0RXZ0OndoZW49IjIwMTktMDEtMDNUMTY6NTY6MjBaIiBzdEV2dDpzb2Z0d2FyZUFnZW50PSJBZG9iZSBQaG90b3Nob3AgQ0MgMjAxOCAoV2luZG93cykiLz4gPC9yZGY6U2VxPiA8L3htcE1NOkhpc3Rvcnk+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+Af/+/fz7+vn49/b19PPy8fDv7u3s6+rp6Ofm5eTj4uHg397d3Nva2djX1tXU09LR0M/OzczLysnIx8bFxMPCwcC/vr28u7q5uLe2tbSzsrGwr66trKuqqainpqWko6KhoJ+enZybmpmYl5aVlJOSkZCPjo2Mi4qJiIeGhYSDgoGAf359fHt6eXh3dnV0c3JxcG9ubWxramloZ2ZlZGNiYWBfXl1cW1pZWFdWVVRTUlFQT05NTEtKSUhHRkVEQ0JBQD8+PTw7Ojk4NzY1NDMyMTAvLi0sKyopKCcmJSQjIiEgHx4dHBsaGRgXFhUUExIREA8ODQwLCgkIBwYFBAMCAQAA//+gB5ZbAAAJRElEQVRoBe1ZaWxUVRQ+97030+k6U6Z0hk5npksptKW0bFJAWRB3UEFFjQuJKIoLJCZqYhRjNC5RFCMuaKJREhMXjAuKggsuRI0bGkEpWymltNBS2ulMZ9qZmfbe9+699715MzPTmdLS6STnfPPee+fc755zz3nnPcNwHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMx......',
  check: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAACXBIWXMAAAsTAAALEwEAmpwYAAAFHmlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS42LWMxNDIgNzkuMTYwOTI0LCAyMDE3LzA3LzEzLTAxOjA2OjM5ICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIgeG1sbnM6cGhvdG9zaG9wPSJodHRwOi8vbnMuYWRvYmUuY29tL3Bob3Rvc2hvcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RFdnQ9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZUV2ZW50IyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ0MgMjAxOCAoV2luZG93cykiIHhtcDpDcmVhdGVEYXRlPSIyMDE5LTAxLTAzVDE2OjU2OjUxKzA4OjAwIiB4bXA6TW9kaWZ5RGF0ZT0iMjAxOS0wMS0wM1QxNjo1NzoxNiswODowMCIgeG1wOk1ldGFkYXRhRGF0ZT0iMjAxOS0wMS0wM1QxNjo1NzoxNiswODowMCIgZGM6Zm9ybWF0PSJpbWFnZS9wbmciIHBob3Rvc2hvcDpDb2xvck1vZGU9IjMiIHBob3Rvc2hvcDpJQ0NQcm9maWxlPSJzUkdCIElFQzYxOTY2LTIuMSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDoyZjI5Y2Y0OS01YjVlLWY5NDctYjg3Yi0yZDM5YjQxMjQyZWIiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6MmYyOWNmNDktNWI1ZS1mOTQ3LWI4N2ItMmQzOWI0MTI0MmViIiB4bXBNTTpPcmlnaW5hbERvY3VtZW50SUQ9InhtcC5kaWQ6MmYyOWNmNDktNWI1ZS1mOTQ3LWI4N2ItMmQzOWI0MTI0MmViIj4gPHhtcE1NOkhpc3Rvcnk+IDxyZGY6U2VxPiA8cmRmOmxpIHN0RXZ0OmFjdGlvbj0iY3JlYXRlZCIgc3RFdnQ6aW5zdGFuY2VJRD0ieG1wLmlpZDoyZjI5Y2Y0OS01YjVlLWY5NDctYjg3Yi0yZDM5YjQxMjQyZWIiIHN0RXZ0OndoZW49IjIwMTktMDEtMDNUMTY6NTY6NTFaIiBzdEV2dDpzb2Z0d2FyZUFnZW50PSJBZG9iZSBQaG90b3Nob3AgQ0MgMjAxOCAoV2luZG93cykiLz4gPC9yZGY6U2VxPiA8L3htcE1NOkhpc3Rvcnk+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+Af/+/fz7+vn49/b19PPy8fDv7u3s6+rp6Ofm5eTj4uHg397d3Nva2djX1tXU09LR0M/OzczLysnIx8bFxMPCwcC/vr28u7q5uLe2tbSzsrGwr66trKuqqainpqWko6KhoJ+enZybmpmYl5aVlJOSkZCPjo2Mi4qJiIeGhYSDgoGAf359fHt6eXh3dnV0c3JxcG9ubWxramloZ2ZlZGNiYWBfXl1cW1pZWFdWVVRTUlFQT05NTEtKSUhHRkVEQ0JBQD8+PTw7Ojk4NzY1NDMyMTAvLi0sKyopKCcmJSQjIiEgHx4dHBsaGRgXFhUUExIREA8ODQwLCgkIBwYFBAMCAQAA//+gB5ZbAAAJRElEQVRoBe1ZaWxUVRQ+97030+k6U6Z0hk5npksptKW0bFJAWRB3UEFFjQuJKIoLJCZqYhRjNC5RFCMuaKJREhMXjAuKggsuRI0bGkEpWymltNBS2ulMZ9qZmfbe9+699715MzPTmdLS6STnfPPee+fc755zz3nnPcNwHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMx......',
  star: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAACXBIWXMAAAsTAAALEwEAmpwYAAAFHmlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS42LWMxNDIgNzkuMTYwOTI0LCAyMDE3LzA3LzEzLTAxOjA2OjM5ICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIgeG1sbnM6cGhvdG9zaG9wPSJodHRwOi8vbnMuYWRvYmUuY29tL3Bob3Rvc2hvcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RFdnQ9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZUV2ZW50IyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ0MgMjAxOCAoV2luZG93cykiIHhtcDpDcmVhdGVEYXRlPSIyMDE5LTAxLTAzVDE2OjU3OjIyKzA4OjAwIiB4bXA6TW9kaWZ5RGF0ZT0iMjAxOS0wMS0wM1QxNjo1Nzo0OCswODowMCIgeG1wOk1ldGFkYXRhRGF0ZT0iMjAxOS0wMS0wM1QxNjo1Nzo0OCswODowMCIgZGM6Zm9ybWF0PSJpbWFnZS9wbmciIHBob3Rvc2hvcDpDb2xvck1vZGU9IjMiIHBob3Rvc2hvcDpJQ0NQcm9maWxlPSJzUkdCIElFQzYxOTY2LTIuMSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDoyZjM5Y2Y0OS01YjVlLWY5NDctYjg3Yi0yZDM5YjQxMjQyZWIiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6MmYzOWNmNDktNWI1ZS1mOTQ3LWI4N2ItMmQzOWI0MTI0MmViIiB4bXBNTTpPcmlnaW5hbERvY3VtZW50SUQ9InhtcC5kaWQ6MmYzOWNmNDktNWI1ZS1mOTQ3LWI4N2ItMmQzOWI0MTI0MmViIj4gPHhtcE1NOkhpc3Rvcnk+IDxyZGY6U2VxPiA8cmRmOmxpIHN0RXZ0OmFjdGlvbj0iY3JlYXRlZCIgc3RFdnQ6aW5zdGFuY2VJRD0ieG1wLmlpZDoyZjM5Y2Y0OS01YjVlLWY5NDctYjg3Yi0yZDM5YjQxMjQyZWIiIHN0RXZ0OndoZW49IjIwMTktMDEtMDNUMTY6NTc6MjJaIiBzdEV2dDpzb2Z0d2FyZUFnZW50PSJBZG9iZSBQaG90b3Nob3AgQ0MgMjAxOCAoV2luZG93cykiLz4gPC9yZGY6U2VxPiA8L3htcE1NOkhpc3Rvcnk+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+Af/+/fz7+vn49/b19PPy8fDv7u3s6+rp6Ofm5eTj4uHg397d3Nva2djX1tXU09LR0M/OzczLysnIx8bFxMPCwcC/vr28u7q5uLe2tbSzsrGwr66trKuqqainpqWko6KhoJ+enZybmpmYl5aVlJOSkZCPjo2Mi4qJiIeGhYSDgoGAf359fHt6eXh3dnV0c3JxcG9ubWxramloZ2ZlZGNiYWBfXl1cW1pZWFdWVVRTUlFQT05NTEtKSUhHRkVEQ0JBQD8+PTw7Ojk4NzY1NDMyMTAvLi0sKyopKCcmJSQjIiEgHx4dHBsaGRgXFhUUExIREA8ODQwLCgkIBwYFBAMCAQAA//+gB5ZbAAAJRElEQVRoBe1ZaWxUVRQ+97030+k6U6Z0hk5npksptKW0bFJAWRB3UEFFjQuJKIoLJCZqYhRjNC5RFCMuaKJREhMXjAuKggsuRI0bGkEpWymltNBS2ulMZ9qZmfbe9+699715MzPTmdLS6STnfPPee+fc755zz3nnPcNwHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMx......',
  heart: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAACXBIWXMAAAsTAAALEwEAmpwYAAAFHmlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS42LWMxNDIgNzkuMTYwOTI0LCAyMDE3LzA3LzEzLTAxOjA2OjM5ICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIgeG1sbnM6cGhvdG9zaG9wPSJodHRwOi8vbnMuYWRvYmUuY29tL3Bob3Rvc2hvcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RFdnQ9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZUV2ZW50IyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ0MgMjAxOCAoV2luZG93cykiIHhtcDpDcmVhdGVEYXRlPSIyMDE5LTAxLTAzVDE2OjU3OjUzKzA4OjAwIiB4bXA6TW9kaWZ5RGF0ZT0iMjAxOS0wMS0wM1QxNjo1ODoxOCswODowMCIgeG1wOk1ldGFkYXRhRGF0ZT0iMjAxOS0wMS0wM1QxNjo1ODoxOCswODowMCIgZGM6Zm9ybWF0PSJpbWFnZS9wbmciIHBob3Rvc2hvcDpDb2xvck1vZGU9IjMiIHBob3Rvc2hvcDpJQ0NQcm9maWxlPSJzUkdCIElFQzYxOTY2LTIuMSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDoyZjQ5Y2Y0OS01YjVlLWY5NDctYjg3Yi0yZDM5YjQxMjQyZWIiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6MmY0OWNmNDktNWI1ZS1mOTQ3LWI4N2ItMmQzOWI0MTI0MmViIiB4bXBNTTpPcmlnaW5hbERvY3VtZW50SUQ9InhtcC5kaWQ6MmY0OWNmNDktNWI1ZS1mOTQ3LWI4N2ItMmQzOWI0MTI0MmViIj4gPHhtcE1NOkhpc3Rvcnk+IDxyZGY6U2VxPiA8cmRmOmxpIHN0RXZ0OmFjdGlvbj0iY3JlYXRlZCIgc3RFdnQ6aW5zdGFuY2VJRD0ieG1wLmlpZDoyZjQ5Y2Y0OS01YjVlLWY5NDctYjg3Yi0yZDM5YjQxMjQyZWIiIHN0RXZ0OndoZW49IjIwMTktMDEtMDNUMTY6NTc6NTNaIiBzdEV2dDpzb2Z0d2FyZUFnZW50PSJBZG9iZSBQaG90b3Nob3AgQ0MgMjAxOCAoV2luZG93cykiLz4gPC9yZGY6U2VxPiA8L3htcE1NOkhpc3Rvcnk+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+Af/+/fz7+vn49/b19PPy8fDv7u3s6+rp6Ofm5eTj4uHg397d3Nva2djX1tXU09LR0M/OzczLysnIx8bFxMPCwcC/vr28u7q5uLe2tbSzsrGwr66trKuqqainpqWko6KhoJ+enZybmpmYl5aVlJOSkZCPjo2Mi4qJiIeGhYSDgoGAf359fHt6eXh3dnV0c3JxcG9ubWxramloZ2ZlZGNiYWBfXl1cW1pZWFdWVVRTUlFQT05NTEtKSUhHRkVEQ0JBQD8+PTw7Ojk4NzY1NDMyMTAvLi0sKyopKCcmJSQjIiEgHx4dHBsaGRgXFhUUExIREA8ODQwLCgkIBwYFBAMCAQAA//+gB5ZbAAAJRElEQVRoBe1ZaWxUVRQ+97030+k6U6Z0hk5npksptKW0bFJAWRB3UEFFjQuJKIoLJCZqYhRjNC5RFCMuaKJREhMXjAuKggsuRI0bGkEpWymltNBS2ulMZ9qZmfbe9+699715MzPTmdLS6STnfPPee+fc755zz3nnPcNwHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMdxHMx......'
};

// 标签组件
interface TagProps {
  text: string;
  type?: 'primary' | 'success' | 'warning' | 'danger' | 'info' | 'default';
  closable?: boolean;
  onClose?: () => void;
  icon?: string;
  size?: 'small' | 'medium' | 'large';
  rounded?: boolean;
  onPress?: () => void;
}

const Tag: React.FC<TagProps> = ({
  text,
  type = 'default',
  closable = false,
  onClose,
  icon,
  size = 'medium',
  rounded = false,
  onPress
}) => {
  const getTypeStyle = () => {
    switch (type) {
      case 'primary':
        return {
          backgroundColor: '#dbeafe',
          borderColor: '#3b82f6',
          textColor: '#1d4ed8'
        };
      case 'success':
        return {
          backgroundColor: '#dcfce7',
          borderColor: '#22c55e',
          textColor: '#15803d'
        };
      case 'warning':
        return {
          backgroundColor: '#fef3c7',
          borderColor: '#f59e0b',
          textColor: '#b45309'
        };
      case 'danger':
        return {
          backgroundColor: '#fee2e2',
          borderColor: '#ef4444',
          textColor: '#b91c1c'
        };
      case 'info':
        return {
          backgroundColor: '#e0f2fe',
          borderColor: '#0ea5e9',
          textColor: '#0891b2'
        };
      default:
        return {
          backgroundColor: '#f3f4f6',
          borderColor: '#9ca3af',
          textColor: '#4b5563'
        };
    }
  };

  const getSizeStyle = () => {
    switch (size) {
      case 'small':
        return {
          fontSize: 12,
          paddingVertical: 4,
          paddingHorizontal: 8,
          borderRadius: rounded ? 12 : 4
        };
      case 'large':
        return {
          fontSize: 16,
          paddingVertical: 8,
          paddingHorizontal: 16,
          borderRadius: rounded ? 20 : 8
        };
      default: // medium
        return {
          fontSize: 14,
          paddingVertical: 6,
          paddingHorizontal: 12,
          borderRadius: rounded ? 16 : 6
        };
    }
  };

  const typeStyle = getTypeStyle();
  const sizeStyle = getSizeStyle();

  return (
    <Pressable 
      style={[
        styles.tagContainer,
        {
          backgroundColor: typeStyle.backgroundColor,
          borderColor: typeStyle.borderColor,
          borderWidth: 1,
          borderRadius: sizeStyle.borderRadius
        }
      ]}
      onPress={onPress}
    >
      <View style={styles.tagContent}>
        {icon && (
          <Image 
            source={{ uri: icon }} 
            style={[
              styles.tagIcon,
              {
                width: sizeStyle.fontSize,
                height: sizeStyle.fontSize,
                tintColor: typeStyle.textColor,
                marginRight: 4
              }
            ]} 
          />
        )}
        <Text 
          style={[
            styles.tagText,
            {
              fontSize: sizeStyle.fontSize,
              color: typeStyle.textColor
            }
          ]}
        >
          {text}
        </Text>
      </View>
      
      {closable && (
        <TouchableOpacity 
          style={styles.closeButton}
          onPress={onClose}
        >
          <Image 
            source={{ uri: TAG_ICONS.close }} 
            style={[
              styles.closeIcon,
              {
                width: sizeStyle.fontSize - 2,
                height: sizeStyle.fontSize - 2,
                tintColor: typeStyle.textColor
              }
            ]} 
          />
        </TouchableOpacity>
      )}
    </Pressable>
  );
};

// 标签组组件
interface TagGroupProps {
  tags: string[];
  type?: TagProps['type'];
  closable?: boolean;
  onTagClose?: (index: number) => void;
  onTagPress?: (index: number) => void;
}

const TagGroup: React.FC<TagGroupProps> = ({
  tags,
  type = 'default',
  closable = false,
  onTagClose,
  onTagPress
}) => {
  return (
    <View style={styles.tagGroup}>
      {tags.map((tag, index) => (
        <View key={index} style={styles.tagGroupItem}>
          <Tag
            text={tag}
            type={type}
            closable={closable}
            onClose={() => onTagClose && onTagClose(index)}
            onPress={() => onTagPress && onTagPress(index)}
          />
        </View>
      ))}
    </View>
  );
};

// 可编辑标签输入组件
interface EditableTagInputProps {
  tags: string[];
  onTagsChange: (tags: string[]) => void;
  placeholder?: string;
}

const EditableTagInput: React.FC<EditableTagInputProps> = ({
  tags,
  onTagsChange,
  placeholder = '添加标签...'
}) => {
  const [inputText, setInputText] = useState('');
  const [isFocused, setIsFocused] = useState(false);

  const handleAddTag = () => {
    if (inputText.trim() && !tags.includes(inputText.trim())) {
      onTagsChange([...tags, inputText.trim()]);
      setInputText('');
    }
  };

  const handleRemoveTag = (index: number) => {
    const newTags = [...tags];
    newTags.splice(index, 1);
    onTagsChange(newTags);
  };

  return (
    <View style={styles.editableTagContainer}>
      <View style={styles.tagInputArea}>
        {tags.map((tag, index) => (
          <View key={index} style={styles.editableTagItem}>
            <Tag
              text={tag}
              type="primary"
              closable
              onClose={() => handleRemoveTag(index)}
            />
          </View>
        ))}
        
        <View style={[
          styles.tagInputContainer,
          isFocused && styles.tagInputContainerFocused
        ]}>
          <TextInput
            style={styles.tagInput}
            value={inputText}
            onChangeText={setInputText}
            placeholder={placeholder}
            onFocus={() => setIsFocused(true)}
            onBlur={() => setIsFocused(false)}
            onSubmitEditing={handleAddTag}
          />
          <TouchableOpacity 
            style={styles.addTagButton}
            onPress={handleAddTag}
          >
            <Image 
              source={{ uri: TAG_ICONS.add }} 
              style={styles.addTagIcon} 
            />
          </TouchableOpacity>
        </View>
      </View>
    </View>
  );
};

// 主应用组件
const App = () => {
  const [selectedTags, setSelectedTags] = useState<string[]>(['React', 'TypeScript']);
  const [dynamicTags, setDynamicTags] = useState<string[]>(['前端', '移动端']);

  const removeSelectedTag = (index: number) => {
    const newTags = [...selectedTags];
    newTags.splice(index, 1);
    setSelectedTags(newTags);
  };

  const addDynamicTag = (tag: string) => {
    if (!dynamicTags.includes(tag)) {
      setDynamicTags([...dynamicTags, tag]);
    }
  };

  const removeDynamicTag = (index: number) => {
    const newTags = [...dynamicTags];
    newTags.splice(index, 1);
    setDynamicTags(newTags);
  };

  return (
    <SafeAreaView style={styles.container}>
      <View style={styles.header}>
        <Text style={styles.headerTitle}>标签组件演示</Text>
        <Text style={styles.headerSubtitle}>现代化标签展示与交互</Text>
      </View>
      
      <ScrollView contentContainerStyle={styles.contentContainer}>
        <View style={styles.section}>
          <Text style={styles.sectionTitle}>基础标签</Text>
          <View style={styles.tagsContainer}>
            <Tag text="默认标签" type="default" />
            <Tag text="主要标签" type="primary" />
            <Tag text="成功标签" type="success" />
            <Tag text="警告标签" type="warning" />
            <Tag text="危险标签" type="danger" />
            <Tag text="信息标签" type="info" />
          </View>
        </View>
        
        <View style={styles.section}>
          <Text style={styles.sectionTitle}>带图标标签</Text>
          <View style={styles.tagsContainer}>
            <Tag text="收藏" type="warning" icon={TAG_ICONS.star} />
            <Tag text="喜欢" type="danger" icon={TAG_ICONS.heart} />
            <Tag text="已完成" type="success" icon={TAG_ICONS.check} />
            <Tag text="重要" type="primary" icon={TAG_ICONS.star} />
          </View>
        </View>
        
        <View style={styles.section}>
          <Text style={styles.sectionTitle}>可关闭标签</Text>
          <View style={styles.tagsContainer}>
            {selectedTags.map((tag, index) => (
              <Tag
                key={index}
                text={tag}
                type="primary"
                closable
                onClose={() => removeSelectedTag(index)}
              />
            ))}
          </View>
        </View>
        
        <View style={styles.section}>
          <Text style={styles.sectionTitle}>不同尺寸标签</Text>
          <View style={styles.tagsContainer}>
            <Tag text="小标签" size="small" type="primary" />
            <Tag text="中标签" size="medium" type="success" />
            <Tag text="大标签" size="large" type="warning" />
          </View>
        </View>
        
        <View style={styles.section}>
          <Text style={styles.sectionTitle}>圆角标签</Text>
          <View style={styles.tagsContainer}>
            <Tag text="圆角标签" rounded type="primary" />
            <Tag text="带图标" rounded icon={TAG_ICONS.star} type="success" />
            <Tag text="可关闭" rounded closable type="warning" />
          </View>
        </View>
        
        <View style={styles.section}>
          <Text style={styles.sectionTitle}>标签组</Text>
          <TagGroup 
            tags={['设计', '开发', '测试', '部署']} 
            type="info"
            closable
            onTagClose={(index) => console.log(`关闭标签: ${index}`)}
            onTagPress={(index) => console.log(`点击标签: ${index}`)}
          />
        </View>
        
        <View style={styles.section}>
          <Text style={styles.sectionTitle}>可编辑标签</Text>
          <View style={styles.editableSection}>
            <EditableTagInput
              tags={dynamicTags}
              onTagsChange={setDynamicTags}
              placeholder="输入新标签并回车添加"
            />
            <View style={styles.suggestedTags}>
              <Text style={styles.suggestedTitle}>推荐标签:</Text>
              <View style={styles.suggestedTagList}>
                {['React Native', '鸿蒙', 'Flutter', '小程序'].map((tag, index) => (
                  <TouchableOpacity 
                    key={index}
                    style={styles.suggestedTagButton}
                    onPress={() => addDynamicTag(tag)}
                  >
                    <Text style={styles.suggestedTagText}>{tag}</Text>
                  </TouchableOpacity>
                ))}
              </View>
            </View>
          </View>
        </View>
        
        <View style={styles.featuresSection}>
          <Text style={styles.featuresTitle}>功能特性</Text>
          <View style={styles.featureList}>
            <View style={styles.featureItem}>
              <Text style={styles.featureBullet}>•</Text>
              <Text style={styles.featureText}>六种预设样式(默认、主要、成功、警告、危险、信息)</Text>
            </View>
            <View style={styles.featureItem}>
              <Text style={styles.featureBullet}>•</Text>
              <Text style={styles.featureText}>三种尺寸(小、中、大)</Text>
            </View>
            <View style={styles.featureItem}>
              <Text style={styles.featureBullet}>•</Text>
              <Text style={styles.featureText}>支持圆角和直角样式</Text>
            </View>
            <View style={styles.featureItem}>
              <Text style={styles.featureBullet}>•</Text>
              <Text style={styles.featureText}>可关闭标签功能</Text>
            </View>
            <View style={styles.featureItem}>
              <Text style={styles.featureBullet}>•</Text>
              <Text style={styles.featureText}>支持图标显示</Text>
            </View>
            <View style={styles.featureItem}>
              <Text style={styles.featureBullet}>•</Text>
              <Text style={styles.featureText}>标签组组件</Text>
            </View>
            <View style={styles.featureItem}>
              <Text style={styles.featureBullet}>•</Text>
              <Text style={styles.featureText}>可编辑标签输入</Text>
            </View>
          </View>
        </View>
        
        <View style={styles.usageSection}>
          <Text style={styles.usageTitle}>使用说明</Text>
          <Text style={styles.usageText}>
            标签组件用于标记和分类内容,常用于文章标签、商品属性、筛选条件等场景。
            提供丰富的样式选项和交互功能,满足多样化的业务需求。
          </Text>
        </View>
      </ScrollView>
      
      <View style={styles.footer}>
        <Text style={styles.footerText}>© 2023 标签组件. All rights reserved.</Text>
      </View>
    </SafeAreaView>
  );
};

// TextInput component for editable tags
const TextInput = ({ style, ...props }: any) => (
  <View style={[styles.textInputContainer, style]}>
    <View style={styles.textInputInner}>
      <View style={styles.textInputPlaceholder} />
      <View style={styles.textInputCursor} />
    </View>
  </View>
);

const { width, height } = Dimensions.get('window');

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#ffffff',
  },
  header: {
    backgroundColor: '#f9fafb',
    paddingTop: 20,
    paddingBottom: 25,
    paddingHorizontal: 20,
    borderBottomWidth: 1,
    borderBottomColor: '#e5e7eb',
  },
  headerTitle: {
    fontSize: 26,
    fontWeight: '700',
    color: '#1f2937',
    textAlign: 'center',
    marginBottom: 5,
  },
  headerSubtitle: {
    fontSize: 15,
    color: '#6b7280',
    textAlign: 'center',
  },
  contentContainer: {
    padding: 20,
  },
  section: {
    marginBottom: 30,
  },
  sectionTitle: {
    fontSize: 22,
    fontWeight: '700',
    color: '#1f2937',
    marginBottom: 20,
    paddingLeft: 10,
    borderLeftWidth: 4,
    borderLeftColor: '#3b82f6',
  },
  tagsContainer: {
    flexDirection: 'row',
    flexWrap: 'wrap',
    gap: 10,
  },
  tagContainer: {
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'space-between',
  },
  tagContent: {
    flexDirection: 'row',
    alignItems: 'center',
  },
  tagText: {
    fontWeight: '600',
  },
  tagIcon: {
    marginRight: 4,
  },
  closeButton: {
    marginLeft: 6,
    padding: 2,
  },
  closeIcon: {
    tintColor: '#4b5563',
  },
  tagGroup: {
    flexDirection: 'row',
    flexWrap: 'wrap',
    gap: 10,
  },
  tagGroupItem: {
    margin: 2,
  },
  editableTagContainer: {
    backgroundColor: '#f9fafb',
    borderRadius: 12,
    padding: 15,
    borderWidth: 1,
    borderColor: '#e5e7eb',
  },
  tagInputArea: {
    flexDirection: 'row',
    flexWrap: 'wrap',
    alignItems: 'center',
    gap: 8,
  },
  editableTagItem: {
    margin: 2,
  },
  tagInputContainer: {
    flexDirection: 'row',
    alignItems: 'center',
    backgroundColor: '#ffffff',
    borderRadius: 8,
    borderWidth: 1,
    borderColor: '#d1d5db',
    paddingHorizontal: 10,
    paddingVertical: 6,
    flex: 1,
    minWidth: 120,
  },
  tagInputContainerFocused: {
    borderColor: '#3b82f6',
    borderWidth: 2,
  },
  tagInput: {
    flex: 1,
    fontSize: 14,
    color: '#1f2937',
  },
  addTagButton: {
    padding: 4,
  },
  addTagIcon: {
    width: 16,
    height: 16,
    tintColor: '#3b82f6',
  },
  editableSection: {
    gap: 20,
  },
  suggestedTags: {
    marginTop: 10,
  },
  suggestedTitle: {
    fontSize: 16,
    fontWeight: '600',
    color: '#1f2937',
    marginBottom: 10,
  },
  suggestedTagList: {
    flexDirection: 'row',
    flexWrap: 'wrap',
    gap: 10,
  },
  suggestedTagButton: {
    backgroundColor: '#e0f2fe',
    borderRadius: 16,
    paddingHorizontal: 12,
    paddingVertical: 6,
    borderWidth: 1,
    borderColor: '#0ea5e9',
  },
  suggestedTagText: {
    fontSize: 14,
    color: '#0891b2',
    fontWeight: '500',
  },
  featuresSection: {
    backgroundColor: '#f9fafb',
    borderRadius: 16,
    padding: 20,
    marginBottom: 30,
    borderWidth: 1,
    borderColor: '#e5e7eb',
  },
  featuresTitle: {
    fontSize: 20,
    fontWeight: '700',
    color: '#1f2937',
    marginBottom: 15,
    textAlign: 'center',
  },
  featureList: {
    paddingLeft: 10,
  },
  featureItem: {
    flexDirection: 'row',
    alignItems: 'center',
    marginBottom: 12,
  },
  featureBullet: {
    fontSize: 18,
    color: '#3b82f6',
    marginRight: 10,
  },
  featureText: {
    fontSize: 16,
    color: '#4b5563',
    flex: 1,
  },
  usageSection: {
    backgroundColor: '#f9fafb',
    borderRadius: 16,
    padding: 20,
    borderWidth: 1,
    borderColor: '#e5e7eb',
  },
  usageTitle: {
    fontSize: 20,
    fontWeight: '700',
    color: '#1f2937',
    marginBottom: 15,
    textAlign: 'center',
  },
  usageText: {
    fontSize: 16,
    color: '#4b5563',
    lineHeight: 24,
    textAlign: 'center',
  },
  footer: {
    paddingVertical: 15,
    alignItems: 'center',
    borderTopWidth: 1,
    borderTopColor: '#e5e7eb',
    backgroundColor: '#f9fafb',
  },
  footerText: {
    fontSize: 14,
    color: '#6b7280',
    fontWeight: '500',
  },
  textInputContainer: {
    flex: 1,
  },
  textInputInner: {
    flexDirection: 'row',
    alignItems: 'center',
  },
  textInputPlaceholder: {
    height: 16,
    backgroundColor: '#e5e7eb',
    borderRadius: 2,
    flex: 1,
  },
  textInputCursor: {
    width: 2,
    height: 16,
    backgroundColor: '#3b82f6',
    marginLeft: 2,
  },
});

export default App;

这段React Native标签组件代码实现了一个高度可配置的标签系统,通过类型配置和尺寸配置来实现多样化的视觉效果。组件采用Pressable作为基础容器,支持触摸反馈和点击事件处理。类型配置系统通过getTypeStyle函数实现,针对不同的标签类型返回对应的颜色方案,包括主要、成功、警告、危险、信息和默认六种类型,每种类型都有对应的背景色、边框色和文字颜色。尺寸配置系统通过getSizeStyle函数实现,支持小、中、大三种尺寸,每种尺寸对应不同的字体大小、内边距和圆角半径。

在鸿蒙系统适配方面,这套实现方案面临着深层次的技术架构差异。React Native的标签组件依赖于基础组件的组合和样式系统,通过JavaScript对象配置视觉表现。而鸿蒙的ArkUI框架提供了Badge组件作为系统级的标签实现,采用声明式配置方式,开发者只需设置文本内容和样式参数,系统会自动处理标签的显示和布局。鸿蒙的Badge组件在底层直接调用系统的渲染服务,避免了跨语言通信带来的性能损耗。

鸿蒙的Badge组件内置了更丰富的样式选项,支持多种预设颜色主题和自定义样式配置。在交互处理方面,鸿蒙的组件直接在Native层处理触摸事件,响应更加灵敏流畅。React Native需要通过JavaScript桥接层传递事件,这在高频交互场景下容易出现延迟现象。

布局系统的差异也十分显著。React Native使用Flexbox布局配合样式对象控制组件外观,需要开发者手动计算各种元素的尺寸和位置关系。鸿蒙的Badge组件内置了智能的布局管理机制,能够自动处理标签的尺寸计算和位置排列,减少布局冲突的可能性。

资源管理机制上,React Native通过URI加载网络图标资源,而鸿蒙使用ResourceManager统一管理本地资源,这种差异影响了组件的加载性能和资源安全性。鸿蒙的资源管理机制提供了更好的缓存策略和访问控制。

动画系统的实现方式完全不同。React Native的动画在JavaScript线程计算后传递给原生组件,而鸿蒙的动画系统在Native层执行,能够实现更精确的时间控制和更高效的资源利用。特别是在处理标签的显示和隐藏动画时,鸿蒙的架构优势更加明显。


打包

接下来通过打包命令npn run harmony将reactNative的代码打包成为bundle,这样可以进行在开源鸿蒙OpenHarmony中进行使用。

打包之后再将打包后的鸿蒙OpenHarmony文件拷贝到鸿蒙的DevEco-Studio工程目录去:

最后运行效果图如下显示:

欢迎大家加入开源鸿蒙跨平台开发者社区,一起共建开源鸿蒙跨平台生态。

相关推荐
尼罗河女娲3 小时前
【测试开发】为什么 UI 自动化总是看起来不稳定?为什么需要引入SessionDirty flag?
开发语言·前端·javascript
Alair‎3 小时前
200React-Query基础
前端·react.js·前端框架
Alair‎3 小时前
201React-Query:useQuery基本使用
前端·react.js
fe小陈3 小时前
React 奇技淫巧——内联hook
前端·react.js
北辰alk3 小时前
React状态提升:为什么它是你项目架构的救星?
react.js
Можно3 小时前
ES6 Map 全面解析:从基础到实战的进阶指南
前端·javascript·html
黄老五3 小时前
createContext
前端·javascript·vue.js
Mintopia3 小时前
🏗️ React 应用的主题化 CSS 架构方案
前端·react.js·架构
章豪Mrrey nical3 小时前
数组扁平化的详解
开发语言·前端·javascript·面试