react-native-ui-kitten中的复选框组:CheckboxGroup使用指南

react-native-ui-kitten中的复选框组:CheckboxGroup使用指南

【免费下载链接】react-native-ui-kitten :boom: React Native UI Library based on Eva Design System :new_moon_with_face::sparkles:Dark Mode 【免费下载链接】react-native-ui-kitten 项目地址: https://gitcode.com/gh_mirrors/re/react-native-ui-kitten

复选框(Checkbox)是移动应用中常用的交互组件,允许用户从一组选项中选择一个或多个项目。在react-native-ui-kitten中,虽然没有单独的CheckboxGroup组件,但我们可以通过组合多个Checkbox组件实现复选框组的功能。本文将详细介绍如何创建和使用复选框组,以及如何处理选中状态和事件。

复选框基础

react-native-ui-kitten提供了基础的Checkbox组件,位于src/components/ui/checkbox/checkbox.component.tsx。该组件支持以下主要属性:

  • checked:是否选中,默认为false
  • indeterminate:是否为不确定状态(半选)
  • onChange:状态变化时的回调函数
  • status:状态样式,可选值包括'basic'、'primary'、'success'、'info'、'warning'、'danger'或'control'

基础使用示例:

import React, { useState } from 'react';
import { CheckBox } from '@ui-kitten/components';

const BasicCheckboxExample = () => {
  const [checked, setChecked] = useState(false);

  return (
    <CheckBox
      checked={checked}
      onChange={(newChecked) => setChecked(newChecked)}
    >
      同意服务条款
    </CheckBox>
  );
};

创建复选框组

由于react-native-ui-kitten没有提供现成的CheckboxGroup组件,我们需要手动创建一个复选框组。以下是一个实现方案:

import React, { useState } from 'react';
import { View, StyleSheet } from 'react-native';
import { CheckBox } from '@ui-kitten/components';

const CheckboxGroupExample = () => {
  const [selectedOptions, setSelectedOptions] = useState<string[]>([]);
  const options = [
    { id: 'option1', label: '选项一' },
    { id: 'option2', label: '选项二' },
    { id: 'option3', label: '选项三' },
  ];

  const toggleOption = (optionId: string) => {
    setSelectedOptions(prev => 
      prev.includes(optionId)
        ? prev.filter(id => id !== optionId)
        : [...prev, optionId]
    );
  };

  return (
    <View style={styles.groupContainer}>
      {options.map(option => (
        <CheckBox
          key={option.id}
          checked={selectedOptions.includes(option.id)}
          onChange={(checked) => checked && toggleOption(option.id)}
          style={styles.checkbox}
        >
          {option.label}
        </CheckBox>
      ))}
    </View>
  );
};

const styles = StyleSheet.create({
  groupContainer: {
    flexDirection: 'column',
    gap: 16,
  },
  checkbox: {
    marginVertical: 4,
  },
});

实现全选与反选功能

在实际应用中,我们经常需要全选、反选和取消全选的功能。以下是一个带有全选功能的复选框组示例:

import React, { useState, useEffect } from 'react';
import { View, StyleSheet } from 'react-native';
import { CheckBox } from '@ui-kitten/components';

const CheckboxGroupWithSelectAllExample = () => {
  const [selectedOptions, setSelectedOptions] = useState<string[]>([]);
  const [selectAll, setSelectAll] = useState(false);
  const [indeterminate, setIndeterminate] = useState(false);
  
  const options = [
    { id: 'option1', label: '选项一' },
    { id: 'option2', label: '选项二' },
    { id: 'option3', label: '选项三' },
    { id: 'option4', label: '选项四' },
  ];

  // 监听选项变化,更新全选状态
  useEffect(() => {
    if (selectedOptions.length === 0) {
      setSelectAll(false);
      setIndeterminate(false);
    } else if (selectedOptions.length === options.length) {
      setSelectAll(true);
      setIndeterminate(false);
    } else {
      setSelectAll(false);
      setIndeterminate(true);
    }
  }, [selectedOptions, options.length]);

  const toggleOption = (optionId: string) => {
    setSelectedOptions(prev => 
      prev.includes(optionId)
        ? prev.filter(id => id !== optionId)
        : [...prev, optionId]
    );
  };

  const handleSelectAll = () => {
    if (selectAll) {
      setSelectedOptions([]);
    } else {
      setSelectedOptions(options.map(option => option.id));
    }
  };

  return (
    <View style={styles.container}>
      <CheckBox
        checked={selectAll}
        indeterminate={indeterminate}
        onChange={(checked) => handleSelectAll()}
        style={styles.selectAllCheckbox}
      >
        全选
      </CheckBox>
      
      <View style={styles.groupContainer}>
        {options.map(option => (
          <CheckBox
            key={option.id}
            checked={selectedOptions.includes(option.id)}
            onChange={(checked) => checked && toggleOption(option.id)}
            style={styles.checkbox}
          >
            {option.label}
          </CheckBox>
        ))}
      </View>
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    padding: 16,
  },
  selectAllCheckbox: {
    marginBottom: 16,
  },
  groupContainer: {
    flexDirection: 'column',
    gap: 16,
    marginLeft: 16,
  },
  checkbox: {
    marginVertical: 4,
  },
});

复选框组的状态管理

在复杂应用中,我们可能需要将复选框组的状态提升到父组件或使用状态管理库(如Redux、MobX)进行管理。以下是一个使用React Context API管理复选框组状态的示例:

import React, { createContext, useContext, useState, ReactNode } from 'react';
import { CheckBox } from '@ui-kitten/components';

// 创建上下文
type CheckboxGroupContextType = {
  selectedOptions: string[];
  toggleOption: (optionId: string) => void;
};

const CheckboxGroupContext = createContext<CheckboxGroupContextType | undefined>(undefined);

// 提供上下文
export const CheckboxGroupProvider: React.FC<{
  children: ReactNode;
  initialSelected?: string[];
}> = ({ children, initialSelected = [] }) => {
  const [selectedOptions, setSelectedOptions] = useState<string[]>(initialSelected);

  const toggleOption = (optionId: string) => {
    setSelectedOptions(prev => 
      prev.includes(optionId)
        ? prev.filter(id => id !== optionId)
        : [...prev, optionId]
    );
  };

  return (
    <CheckboxGroupContext.Provider value={{ selectedOptions, toggleOption }}>
      {children}
    </CheckboxGroupContext.Provider>
  );
};

// 自定义Hook
export const useCheckboxGroup = () => {
  const context = useContext(CheckboxGroupContext);
  if (context === undefined) {
    throw new Error('useCheckboxGroup must be used within a CheckboxGroupProvider');
  }
  return context;
};

// 消费上下文的复选框项
export const CheckboxGroupItem: React.FC<{
  optionId: string;
  label: string;
}> = ({ optionId, label }) => {
  const { selectedOptions, toggleOption } = useCheckboxGroup();

  return (
    <CheckBox
      checked={selectedOptions.includes(optionId)}
      onChange={(checked) => checked && toggleOption(optionId)}
    >
      {label}
    </CheckBox>
  );
};

// 使用示例
const ContextExample = () => {
  return (
    <CheckboxGroupProvider initialSelected={['option2']}>
      <View style={{ flexDirection: 'column', gap: 16, padding: 16 }}>
        <CheckboxGroupItem optionId="option1" label="选项一" />
        <CheckboxGroupItem optionId="option2" label="选项二" />
        <CheckboxGroupItem optionId="option3" label="选项三" />
      </View>
    </CheckboxGroupProvider>
  );
};

自定义复选框组样式

react-native-ui-kitten的Checkbox组件支持自定义样式,我们可以通过以下方式自定义复选框组的外观:

import React, { useState } from 'react';
import { View, StyleSheet } from 'react-native';
import { CheckBox } from '@ui-kitten/components';

const StyledCheckboxGroupExample = () => {
  const [selectedOptions, setSelectedOptions] = useState<string[]>([]);
  const options = [
    { id: 'option1', label: '红色主题' },
    { id: 'option2', label: '蓝色主题' },
    { id: 'option3', label: '绿色主题' },
  ];

  const toggleOption = (optionId: string) => {
    setSelectedOptions(prev => 
      prev.includes(optionId)
        ? prev.filter(id => id !== optionId)
        : [...prev, optionId]
    );
  };

  return (
    <View style={styles.container}>
      {options.map((option, index) => (
        <CheckBox
          key={option.id}
          checked={selectedOptions.includes(option.id)}
          onChange={(checked) => checked && toggleOption(option.id)}
          status={index === 0 ? 'danger' : index === 1 ? 'primary' : 'success'}
          style={styles.checkbox}
        >
          {option.label}
        </CheckBox>
      ))}
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    padding: 16,
    backgroundColor: '#f5f5f5',
    borderRadius: 8,
  },
  checkbox: {
    marginVertical: 8,
    padding: 8,
    borderRadius: 4,
    backgroundColor: 'white',
  },
});

复选框组的实际应用场景

1. 表单中的多选项

在用户注册或设置页面,我们经常需要用户选择多个兴趣标签:

import React, { useState } from 'react';
import { View, StyleSheet, Button, Alert } from 'react-native';
import { CheckBox, Text } from '@ui-kitten/components';

const InterestSelectionForm = () => {
  const [selectedInterests, setSelectedInterests] = useState<string[]>([]);
  
  const interests = [
    { id: 'sports', label: '体育' },
    { id: 'music', label: '音乐' },
    { id: 'reading', label: '阅读' },
    { id: 'travel', label: '旅行' },
    { id: 'coding', label: '编程' },
  ];

  const toggleInterest = (interestId: string) => {
    setSelectedInterests(prev => 
      prev.includes(interestId)
        ? prev.filter(id => id !== interestId)
        : [...prev, interestId]
    );
  };

  const handleSubmit = () => {
    Alert.alert('已选择兴趣', selectedInterests.join(', '));
  };

  return (
    <View style={styles.container}>
      <Text style={styles.title}>选择您的兴趣爱好(可多选)</Text>
      
      <View style={styles.checkboxContainer}>
        {interests.map(interest => (
          <CheckBox
            key={interest.id}
            checked={selectedInterests.includes(interest.id)}
            onChange={(checked) => checked && toggleInterest(interest.id)}
            style={styles.checkbox}
          >
            {interest.label}
          </CheckBox>
        ))}
      </View>
      
      <Button 
        title="提交" 
        onPress={handleSubmit}
        disabled={selectedInterests.length === 0}
      />
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    padding: 16,
  },
  title: {
    fontSize: 18,
    marginBottom: 16,
  },
  checkboxContainer: {
    marginBottom: 24,
  },
  checkbox: {
    marginVertical: 8,
  },
});

2. 筛选功能实现

复选框组也常用于实现列表筛选功能:

import React, { useState } from 'react';
import { View, StyleSheet, FlatList, Text } from 'react-native';
import { CheckBox, Card } from '@ui-kitten/components';

// 产品数据
const products = [
  { id: '1', name: '手机', category: 'electronics' },
  { id: '2', name: '衬衫', category: 'clothing' },
  { id: '3', name: '笔记本电脑', category: 'electronics' },
  { id: '4', name: '牛仔裤', category: 'clothing' },
  { id: '5', name: '耳机', category: 'electronics' },
  { id: '6', name: '运动鞋', category: 'clothing' },
];

// 分类数据
const categories = [
  { id: 'electronics', label: '电子产品' },
  { id: 'clothing', label: '服装' },
];

const ProductFilterExample = () => {
  const [selectedCategories, setSelectedCategories] = useState<string[]>([]);
  
  const toggleCategory = (categoryId: string) => {
    setSelectedCategories(prev => 
      prev.includes(categoryId)
        ? prev.filter(id => id !== categoryId)
        : [...prev, categoryId]
    );
  };
  
  // 根据选中的分类筛选产品
  const filteredProducts = selectedCategories.length > 0
    ? products.filter(product => selectedCategories.includes(product.category))
    : products;

  return (
    <View style={styles.container}>
      <View style={styles.filterContainer}>
        <Text style={styles.filterTitle}>分类筛选</Text>
        {categories.map(category => (
          <CheckBox
            key={category.id}
            checked={selectedCategories.includes(category.id)}
            onChange={(checked) => checked && toggleCategory(category.id)}
            style={styles.checkbox}
          >
            {category.label}
          </CheckBox>
        ))}
      </View>
      
      <View style={styles.productListContainer}>
        <Text style={styles.productListTitle}>
          {selectedCategories.length > 0 
            ? `筛选结果 (${filteredProducts.length})` 
            : `全部产品 (${products.length})`}
        </Text>
        
        <FlatList
          data={filteredProducts}
          keyExtractor={item => item.id}
          renderItem={({ item }) => (
            <Card style={styles.productCard}>
              <Text style={styles.productName}>{item.name}</Text>
              <Text style={styles.productCategory}>
                {categories.find(c => c.id === item.category)?.label}
              </Text>
            </Card>
          )}
        />
      </View>
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    padding: 16,
  },
  filterContainer: {
    marginBottom: 24,
    padding: 16,
    backgroundColor: '#f5f5f5',
    borderRadius: 8,
  },
  filterTitle: {
    fontSize: 16,
    marginBottom: 16,
    fontWeight: 'bold',
  },
  checkbox: {
    marginVertical: 8,
  },
  productListContainer: {
    flex: 1,
  },
  productListTitle: {
    fontSize: 16,
    marginBottom: 16,
    fontWeight: 'bold',
  },
  productCard: {
    padding: 16,
    marginBottom: 16,
  },
  productName: {
    fontSize: 16,
    marginBottom: 8,
  },
  productCategory: {
    fontSize: 14,
    color: '#666',
  },
});

总结

虽然react-native-ui-kitten没有提供现成的CheckboxGroup组件,但通过组合多个Checkbox组件并自行管理状态,我们可以轻松实现功能完善的复选框组。本文介绍了基础使用、全选功能、状态管理、样式自定义和实际应用场景等内容,希望能帮助您更好地在项目中使用复选框组。

官方文档:src/components/ui/checkbox/checkbox.component.tsx

【免费下载链接】react-native-ui-kitten :boom: React Native UI Library based on Eva Design System :new_moon_with_face::sparkles:Dark Mode 【免费下载链接】react-native-ui-kitten 项目地址: https://gitcode.com/gh_mirrors/re/react-native-ui-kitten

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值