You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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>
);

这个方法的核心是:

  1. 通过修改主题隐藏默认的右侧指示器图标
  2. 手动管理Accordion的展开状态
  3. 在Accordion内部添加自定义的标题栏,自己控制右侧箭头的显示

内容的提问来源于stack exchange,提问作者Vagner Wentz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 13:07:45