React Native Paper List.Accordion右侧自定义箭头图标实现问题
解决React Native Paper List.Accordion右侧图标替换问题
嘿,我明白你的困扰——List.Accordion默认的右侧指示器图标不是你想要的,而且官方没直接提供right属性来替换它。别担心,有几个实用的办法能搞定这个问题:
方法1:使用新版组件自带的expandIcon/collapseIcon属性(推荐)
如果你的react-native-paper版本是v4及以上,其实List.Accordion已经提供了直接自定义展开/折叠图标的属性,完全不用绕弯路。你只需要传入你想要的Icon组件即可:
import { List, Icon } from 'react-native-paper'; // ... {bleDevices.length > 0 && ( <List.Section> <List.Accordion title="Dispositivos encontrados" left={props => <Icon name="arrow-down" size={24} />} // 自定义展开时的图标 expandIcon={<Icon name="arrow-down" size={24} />} // 自定义折叠时的图标 collapseIcon={<Icon name="arrow-up" size={24} />} > {_.map(bleDevices, (device, index) => ( <List.Item key={index} title={`${device.name || 'device'} (${device.rssi}) `} description={`${device.localName} (${device.id})`} right={props => ( <Button onPress={() => toggleConnectDevice(device.name)}> Conectar </Button> )} /> ))} </List.Accordion> </List.Section> )}
注意:我还帮你修正了onPress的写法——原来的toggleConnectDevice(device.name)会直接执行函数,应该改成箭头函数包裹,避免组件渲染时就触发调用。
方法2:旧版本兼容方案(自定义标题+隐藏默认图标)
如果你还在使用较旧版本的react-native-paper,没有expandIcon属性,可以通过手动管理展开状态、隐藏默认图标,再自定义标题栏的方式实现:
import { useState } from 'react'; import { View, Text } from 'react-native'; import { List, Icon, PaperProvider, useTheme } from 'react-native-paper'; // ... const [isAccordionExpanded, setIsAccordionExpanded] = useState(false); const theme = useTheme(); // 复制主题并隐藏默认的accordion图标 const modifiedTheme = { ...theme, icons: { ...theme.icons, accordion: () => null, }, }; return ( <PaperProvider theme={modifiedTheme}> {bleDevices.length > 0 && ( <List.Section> <List.Accordion expanded={isAccordionExpanded} onPress={() => setIsAccordionExpanded(!isAccordionExpanded)} left={props => <Icon name="arrow-down" size={24} />} > {/* 自定义标题栏,包含我们想要的右侧箭头 */} <View style={{ flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', paddingHorizontal: 16, paddingVertical: 12, width: '100%' }}> <Text style={theme.typography.title}>Dispositivos encontrados</Text> <Icon name={isAccordionExpanded ? 'arrow-up' : 'arrow-down'} size={24} /> </View> {/* 原有的子列表内容 */} {_.map(bleDevices, (device, index) => ( <List.Item key={index} title={`${device.name || 'device'} (${device.rssi}) `} description={`${device.localName} (${device.id})`} right={props => ( <Button onPress={() => toggleConnectDevice(device.name)}> Conectar </Button> )} /> ))} </List.Accordion> </List.Section> )} </PaperProvider> );
这个方法的核心是:
- 通过修改主题隐藏默认的右侧指示器图标
- 手动管理Accordion的展开状态
- 在Accordion内部添加自定义的标题栏,自己控制右侧箭头的显示
内容的提问来源于stack exchange,提问作者Vagner Wentz
相关产品推荐
相关产品推荐

