React Native, создать несколько флажков

#javascript #reactjs #react-native

#javascript #reactjs #react-native

Вопрос:

Я пытаюсь создать несколько флажков для своего приложения, как на изображении ниже. Я создал его, но столкнулся с проблемой, что его выравнивание не очень хорошее.

Вот мой код, в котором я пытаюсь его создать, я создал для этого отдельный компонент, чтобы я мог использовать его в нескольких местах. Я использую только код facebook, который выглядит плохо. Есть ли какая-либо библиотека для этого или лучший способ сделать это? Это выглядит не очень хорошо по сравнению с изображением.

 //component code

function Choice({data, onValueChange, style}) {
  const [selectedIndex, setSelectedIndex] = useState(-1);

  const FilterButton = ({
    callback,
    text,
    id,
    selectedIndex,
    btnstyles,
    btnTxtStyles,
    btnstylesSelect,
    btnTxtStylesSelect,
    imageStyle,
  }) => {
    const clicked = selectedIndex === id;
    return (
      <View style={{flexDirection: 'row'}}>
        {!clicked ? (
          <>
            <TouchableOpacity
              style={[btnstyles]}
              onPress={() => {
                callback(id);
              }}></TouchableOpacity>
          </>
        ) : (
          <>
            <TouchableOpacity
              style={btnstylesSelect}
              onPress={() => {
                callback(id);
              }}>
              <Image source={imagePath.tick} style={{borderRadius: 5}} />
            </TouchableOpacity>
          </>
        )}
      </View>
    );
  };

  return (
    <View style={[style]}>
      {data.map((x, i) => (
        <FilterButton
          text={x.title}
          id={i}
          btnstyles={x.btnstyles}
          btnTxtStyles={x.btnTxtStyles}
          selectedIndex={selectedIndex}
          btnTxtStylesSelect={x.btnTxtStylesSelect}
          imageStyle={x.imageStyle}
          btnstylesSelect={x.btnstylesSelect}
          callback={(id) => {
            setSelectedIndex(id);
            if (onValueChange) {
              onValueChange(id);
            }
          }}
        />
      ))}
    </View>
  );
}

//Main code

 <View
              style={{
                flexDirection: 'row',
              }}>
              <Text style={{...styles.time1, ...commonStyles.fontSize14}}>
                1hr
              </Text>
              <Text style={{...styles.time2, ...commonStyles.fontSize14}}>
                2hr
              </Text>
              <Text style={{...styles.time2, ...commonStyles.fontSize14}}>
                3hr
              </Text>
              <Text style={{...styles.time2, ...commonStyles.fontSize14}}>
                4hr
              </Text>
            </View>
          

  

Если кто-нибудь знает, как сделать это лучше, или какую-либо библиотеку для этого, пожалуйста, предложите.

введите описание изображения здесь

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

1. Можете ли вы объяснить проблему, с которой вы столкнулись с кодом?

2. Эй, ну, я хочу сделать флажок, как на изображении, в разделе facebook есть 4 флажка, я хочу, чтобы я мог создать 1 поле, но не знаю, как сделать 4

Ответ №1:

Я изменил название ваших компонентов для лучшего понимания:

 // ChoicesHeaders.js

import Checkbox from './CheckBox';

const ChoicesHeaders = ({
  headersName,
  choicesHeaderStyles,
  choicesHeaderItemStyles,
}) => {
  return (
    <View style={choicesHeaderStyles}>
      {headersName.map((header) => (
        <View style={choicesHeaderItemStyles}>
          <Text>{header}</Text>
        </View>
      ))}
    </View>
  );
};

export default ChoicesHeaders;
  
 // Checkbox.js

const Checkbox = ({
  id,
  btnstyles,
  btnstylesSelect,
  checked,
  selectedIndex,
  onCheckboxChange,
}) => {
  return selectedIndex !== id ? (
    <TouchableOpacity
      style={btnstyles}
      onPress={() => {
        onCheckboxChange(id);
      }}></TouchableOpacity>
  ) : (
    <TouchableOpacity
      style={btnstylesSelect}
      onPress={() => {
        onCheckboxChange(id);
      }}></TouchableOpacity>
  );
};

export default Checkbox;
  
 // Choice.js

import Checkbox from './CheckBox';

const Choice = ({
  callback,
  text,
  btnstyles,
  btnTxtStyles,
  btnstylesSelect,
  btnTxtStylesSelect,
  onValueChange,
  choicesCount
}) => {
  const [selectedIndex, setSelectedIndex] = React.useState(-1);
  const handleCheckboxChange = (id) => {
    setSelectedIndex(id)
    if (onValueChange) {
      onValueChange(text, id);
    }
  };

  return (
    <View style={{ flexDirection: 'row', alignItems: 'center' }}>
      <View style={btnTxtStyles}>
        <Text>{text}</Text>
      </View>
      {Array.from({length: choicesCount}).map((item, index) => (
      <Checkbox
        id={index}
        btnstyles={btnstyles}
        btnstylesSelect={btnstylesSelect}
        selectedIndex={selectedIndex}
        onCheckboxChange={handleCheckboxChange}
      />
      ))}
    </View>
  );
};

export default Choice;

  
 // App.js

import Choice from './components/Choice';
import ChoicesHeader from './components/ChoicesHeader';
// or any pure javascript modules available in npm
import { Card } from 'react-native-paper';


const data = [
  { title: 'Instagram', /* extra properties(e.g. keys to save in db) */},
  { title: 'Facebook',  },
  { title: 'Twitter',   },
  { title: 'Linkdin',   },
];

const choicesHeaders=['1 hr', '2 hr', '3 hr', '4 hr'];

export default function App() {
  const handleValueChange = (socialMediaName, checkboxId) => {
    // do what ever you want with this two
  };

  return (
    <View style={styles.container}>
      <ChoicesHeader
        headersName={choicesHeaders}
        choicesHeaderStyles={styles.choicesHeader}
        choicesHeaderItemStyles={styles.choicesHeaderItem}
      />
      {data.map((x) => (
        <Choice
          text={x.title}
          btnTxtStyles={styles.btnTxtStyles}
          btnstyles={styles.btnstyles}
          btnstylesSelect={styles.btnstylesSelect}
          onValueChange={handleValueChange}
          choicesCount={choicesHeaders.length}
        />
      ))}
    </View>
  );
}

const checkBoxBaseStyles = {
    height: 40,
    width: 40,
    margin: 10,
};

const labelDimentions = {
  width: 100
};

const styles = StyleSheet.create({
  btnstyles: {
    ...checkBoxBaseStyles,
    borderWidth: 1,
    borderColor: 'orange',
  },
  btnstylesSelect: {
    ...checkBoxBaseStyles,
    backgroundColor: 'orange',
  },
  btnTxtStyles: {
    ...labelDimentions,
  },
  choicesHeader: {
    flexDirection: 'row',
    alignItems: 'center',
    marginLeft: labelDimentions.width
  },
  choicesHeaderItem: {
    ...checkBoxBaseStyles,
    textAlign: 'center'
  },
});

  

ссылка на закуску к выставке

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

1. как насчет текста (1 час, 2 часа)? ваш код работает правильно, но как я устанавливаю верхний текст?

2. Можете ли вы сказать мне, где именно вы хотите поместить верхний текст? и какие проблемы у вас есть? @DarkPrince

3. Я уверен, что, как и на изображении (о котором идет речь), вы можете видеть 1 час 2 часа 3 часа 4 часа вверх по 1-й строке окна, я хочу, чтобы верхний текст был таким

4. Я изменил код внутри ответа. Я изменил некоторую часть кода для повторного использования стилей. вы можете увидеть изменения в expo link. @DarkPrince

5. Я должен сказать, что было бы лучше, если бы мы снова изменили название компонентов: все приложение —> SocialMediaActivityQuestion, ChoiceHeaders —> Заголовок, Выбор —> SocialMediaItem

Ответ №2:

Это определенно не идеально, но вот хотя бы рабочий пример текста над флажками. Вместо того, чтобы связывать метки с флажками, я просто «разместил» их над флажками.

в App.js — измените возврат вашего приложения на:

  return (
    <View>
      <View style={{ flexDirection: 'row', alignItems: 'center', marginLeft:100}}>
          <Text style={styles.labelStyles}>1hr</Text>
          <Text style={styles.labelStyles}>2hr</Text>
          <Text style={styles.labelStyles}>3hr</Text>
          <Text style={styles.labelStyles}>4hr</Text>
      </View>
      <Choice data={data} onValueChange={handleValueChange} />
    </View>
  );
  

Затем просто добавьте несколько стилей в свой const styles , что-то вроде этого:

 labelStyles: {
    margin:10,
    fontSize:13,
    color:'#afafb2'
  },
  

Для представления игровой площадки:
https://snack.expo.io/RGzGbUadq

Надеюсь, это поможет вам получить представление, если что-нибудь! 🙂