проблемы с модальным выпадающим списком react-native с источником данных массива объектов

#javascript #react-native #react-native-dropdown-picker

Вопрос:

я наконец нашел выпадающее меню, которое кажется подходящим для моих нужд, но у меня есть некоторые проблемы с этим инструментом..

мои выпадающие данные представляют собой массив объектов с парами меток и значений в нем.. когда я пытаюсь использовать это в качестве источника для выпадающего списка, мне приходится использовать функцию отображения из ModalDropdown для правильного отображения моих меток.. прочитав официальную документацию, я нашел подобное решение, и оно, похоже, работает нормально, за исключением одной проблемы: элементы в моем раскрывающемся списке не завершены после начальной отрисовки, и количество опций изменится, если пользователь выберет один из этих параметров в списке.. очень странное поведение, на мой взгляд, и я действительно не могу сказать, почему это происходит и что с этим делать.. если я переключу источник данных на простой строковый массив(data2) без обработки отрисовки, все будет работать нормально, и полный список будет отрисован без каких-либо проблем… так что, возможно, проблема кроется в функции renderDropDownList, но, поскольку это тоже кажется очень простым, я не вижу в этом проблемы. другая идея заключается в том, что, возможно, значение / индекс по умолчанию может помочь? но пока безрезультатно.. может быть, кто-нибудь мог бы помочь мне найти решение для этого, я был бы очень признателен 🙂

 короткий gif, показывающий проблему

 import ModalDropdown from 'react-native-modal-dropdown';
import { Card } from 'react-native-elements';
import  React, { useState } from 'react';


function Home() {

  const [open, setOpen] = useState(false);
  const [value, setValue] = useState(null);
  
  let data = [{label: 'Choose', value: '0'}, {label: '1 foo', value: '1'}, {label: '2 foo', value: '2'}, {label: '3 foos', value: '3'}, {label: '4 foos', value: '4'}, {label: '5 foos', value: '5'}, {label: '6 foos', value: '6'}, {label: '7 foos', value: '7'}, {label: '8 foos', value: '8'}, {label: '9 foos', value: '9'}, {label: '10 foos', value: '10'}, {label: '11 foos', value: '11'}, {label: '12 foos', value: '12'}, {label: '13 foos', value: '13'}, {label: '14 foos', value: '14'}, {label: '15 foos', value: '15'}, {label: '16 foos', value: '16'}, {label: '17 foos', value: '17'}, {label: '18 foos', value: '18'}, {label: '19 foos', value: '19'}, {label: '20 foos', value: '20'}];
  let data2 = ['1','2','3','4','5','6','7','8','9','10','11',]

  const setItem = value => {
    console.log("you touched option: "   value.value);
  }

  const renderDropDownList = (rowData) => {
    return (
      <View style={{backgroundColor: colors.cardBackgroundColor, alignItems: 'flex-end', marginLeft: 0}}>
        <Text style={{color: colors.textSubtitleColor, fontSize: 12}}>{rowData.label}</Text> 
      </View>
    );
  }

    const renderButtonText = (rowData) => {
      const {label, value} = rowData;
      return `${label}`;
    };


  return (
    <Card containerStyle={{height:200, backgroundColor: 'gray'}}>

        <ModalDropdown 
            options={data}
            renderRow={(rowData) => renderDropDownList(rowData)}
            renderButtonText={(rowData) => renderButtonText(rowData)}
            style={{backgroundColor:'transparent', borderColor: 'gray'}}
            dropdownStyle={{backgroundColor:'white', borderColor: 'gray', marginBottom: 2}}
            onSelect={(idx, value) => setItem(value)}
            />
     

     // ...
    </Card>

  );
};

export default Home;
 

Комментарии:

1. почему бы вам не использовать: github.com/react-native-picker/picker

2. потому что мне нужен стилизуемый выпадающий список … и все остальные, кого я пробовал, не смогли стилизовать эту часть средства выбора..

3. дополнение: выбор react-native поддерживает только стиль в выпадающем списке в iOS, он мне нужен для Android.. и этот выпадающий список кажется идеальным, множество опций для настройки..мне просто нужно исправить эту проблему..как-то

Ответ №1:

я нашел решение проблемы, которая у меня была здесь

настройка стиля каждого элемента может быть выполнена только в одном месте, у меня это было дважды, один раз в функции рендеринга и один раз в качестве опоры «Выпадающий стиль». как оказалось, эти двое докучали друг другу 😀

смотрите мой рабочий код ниже:

  import React, { useState } from 'react';
 import {StyleSheet, View, Text, TouchableHighlight} from 'react-native';
 import { Icon} from 'native-base';
 import { useTheme} from '@react-navigation/native';
 import ModalDropdown from 'react-native-modal-dropdown';
 
 function myPicker() {
 
    const { colors } = useTheme(); // works
    
    const renderDropDownList = (rowData, rowID, highlighted) => {
        return  <Text style={{color: colors.textSubtitleColor, fontSize: 11, fontWeight:"300", padding: 2}}>{rowData.label}</Text>
    }

    const renderButtonText = (rowData) => {
        const {label, value} = rowData;
        return <View><Text style={{fontSize: 11,fontWeight: "500", color: colors.textSubtitleColor}}>{label}</Text></View>;
    }

    const renderSeparator = (sectionID, rowID, adjacentRowHighlighted) => {
        if (rowID == items.length - 1) return;
        return <View style={{height: 1, width: 0, backgroundColor: 'gray'}}/>
        
    }

    const dropdown_adjustFrame = (style) => {
        // console.log(`frameStyle={width:${style.width}, height:${style.height}, top:${style.top}, left:${style.left}, right:${style.right}}`);
        style.width = 100;
        style.top  = 4;
        style.left -= 49;
        return style;
    }
      
    return (
          <View style={{flex: 5}}>
               <ModalDropdown 
                  options={items}
                  defaultValue="Choose"
                  textStyle={{color: colors.textSubtitleColor, fontSize: 10}}
                  renderRow={(rowData, rowID) => renderDropDownList(rowData, rowID)}
                  renderButtonText={(rowData) => renderButtonText(rowData)}
                  renderSeparator={(rowID) => renderSeparator(rowID)}
                  adjustFrame={style => dropdown_adjustFrame(style)}
                  style={{backgroundColor:'transparent', borderColor: 'gray', paddingRight: 10, alignItems: 'flex-end'}}
                  dropdownStyle={{backgroundColor:colors.frameBackground, 
                                  paddingRight: 10, 
                                  paddingLeft: 10, 
                                  paddingRight: 5, 
                                  alignItems: 'flex-end', 
                                  borderWidth: 2,
                                  borderColor: colors.borderColor,
                                  borderRadius: 5,}}
                  // dropdownTextStyle={{color: colors.textSubtitleColor, fontSize: 5, fontWeight:"100"}}
                  onSelect={(idx, value) => setItem(value)}
              />
        </View>
    );
 
 
 }