Как я могу реализовать текст, который будет поддерживать объект стилей в этом повторно используемом компоненте?

Я нашел эту небольшую библиотеку на github. Я хотел бы внести в него некоторые изменения. Как я могу добавить текст, который поддерживает объект стиля, внутри переключателя (этот компонент)? Поэтому при использовании на других экранах можно внедрить любой текст внутри него и изменить стили по умолчанию. На данный момент он не включает даже текстовую реализацию по умолчанию. Вот код.

import React, { Component } from 'react'
import { StyleSheet, TouchableOpacity } from 'react-native'
import { View } from 'react-native-animatable'
import PropTypes from 'prop-types'

const DEFAULT_SIZE_MULTIPLIER = 0.7
const DEFAULT_OUTER_BORDER_WIDTH_MULTIPLIER = 0.2

export default class RadioButton extends Component {
  static propTypes = {
    size: PropTypes.number,
    innerColor: PropTypes.string,
    outerColor: PropTypes.string,
    isSelected: PropTypes.bool,
    onPress: PropTypes.func
  }

  static defaultProps = {
    size: 35,
    innerColor: 'dodgerblue',
    outerColor: 'dodgerblue',
    isSelected: false,
    onPress: () => null
  }

  render () {
    const { size, innerColor, outerColor, isSelected, onPress } = this.props
    const outerStyle = {
      borderColor: outerColor,
      width: size + size * DEFAULT_SIZE_MULTIPLIER,
      height: size + size * DEFAULT_SIZE_MULTIPLIER,
      borderRadius: (size + size * DEFAULT_SIZE_MULTIPLIER) / 2,
      borderWidth: size * DEFAULT_OUTER_BORDER_WIDTH_MULTIPLIER
    }

    const innerStyle = {
      width: size,
      height: size,
      borderRadius: size / 2,
      backgroundColor: innerColor
    }

    return (
      <TouchableOpacity style={[styles.radio, outerStyle]} onPress={onPress}>
        {isSelected ? <View style={innerStyle} {...this.props} /> : null}
      </TouchableOpacity>
    )
  }
}

const styles = StyleSheet.create({
  radio: {
    justifyContent: 'center',
    alignItems: 'center',
    alignSelf: 'center'
  }
})

Как я могу реализовать ту новую функцию, которая была описана выше?


person Community    schedule 05.12.2017    source источник
comment
То, что у вас есть, должно работать, если вы объедините эти два объекта стиля: combinedStyles = Object.assign({}, styles.radio, outerStyle), а затем используете их <TouchableOpacity style={combinedStyles} >.   -  person bluehipy    schedule 05.12.2017


Ответы (2)


Это показывает, как заставить это работать шаг за шагом.

во-первых, код:

/// 1) Make a composition component
export default class RadioButtonText extends Component {
  static propTypes = {
    /// 2) Make all RadioButton props as this classes' props
    ...RadioButton.propTypes,

    /// 3) Two new props, one for string of text, one for text style.
    text: PropTypes.string,
    textStyle: PropTypes.oneOfType([
        PropTypes.object,
        PropTypes.number,
    ]),
  }

  static defaultProps = {
      ...RadioButton.defaultProps,
  }

  render() {
    return (
      <View>
        <!-- 4) Pass every props into RadioButton -->
        <RadioButton {...this.props} />
        <!-- 5) Apply text string, and style -->
        <Text style={this.props.textStyle}>{this.props.text}</Text>
      </View>
    )
  }
}

Шаги:

  1. Сделайте компонент композиции.

Создайте новый компонент, за исключением модификации с открытым исходным кодом, для облегчения контроля и понимания. Основная идея: левая сторона как <RadioButton />, правая сторона как <Text />, все выглядит хорошо.

  1. Сделать все реквизиты <RadioButton /> реквизитами этого класса.

Таким образом, мы можем передавать реквизиты из нового компонента <RadioButtonText /> в <RadioButton /> для каждого реквизита, такого как size, innerColor, outerColor.

  1. Два новых реквизита, один для строки текста, один для стиля текста.

Это все, что вам нужно для вашего требования. Хотя эти два реквизита тоже перейдут в <RadioButton />, это вообще не имеет значения (никакого эффекта).

  1. Передайте все реквизиты в <RadioButton />
  2. Применить текстовую строку и стиль

Применение:

<RadioButtonText
  {/* props for RadioButton */}
  size={10}
  isSelected={false}
  {/* props for RadioButtonText */}
  text='Radio Text!'
  textStyle={{fontSize: 18}}
/>
person Val    schedule 05.12.2017
comment
Большое спасибо за ответ. Но что, если я хочу реализовать этот текст внутри кнопки (в центре кнопки)? Я попробовал это вчера, и это выглядело как разрушенное. - person ; 05.12.2017
comment
Я добавляю еще один. посмотрите, поможет ли это. - person Val; 05.12.2017

Если вы действительно хотите изменить его, это может помочь.

<Text /> добавлен внутри <RadioButton />.

См. комментарий ниже.

import React, { Component } from 'react'
import { StyleSheet, TouchableOpacity } from 'react-native'
import { View } from 'react-native-animatable'
import PropTypes from 'prop-types'

const DEFAULT_SIZE_MULTIPLIER = 0.7
const DEFAULT_OUTER_BORDER_WIDTH_MULTIPLIER = 0.2

export default class RadioButton extends Component {
  static propTypes = {
    size: PropTypes.number,
    innerColor: PropTypes.string,
    outerColor: PropTypes.string,
    isSelected: PropTypes.bool,
    onPress: PropTypes.func,

    /// 1) Added new props
    text: PropTypes.string,
    textStyle: PropTypes.oneOfType([
        PropTypes.object,
        PropTypes.number,
    ]),
  }

  static defaultProps = {
    size: 35,
    innerColor: 'dodgerblue',
    outerColor: 'dodgerblue',
    isSelected: false,
    onPress: () => null
  }

  render () {
    const { size, innerColor, outerColor, isSelected, onPress } = this.props
    const outerStyle = {
      borderColor: outerColor,
      width: size + size * DEFAULT_SIZE_MULTIPLIER,
      height: size + size * DEFAULT_SIZE_MULTIPLIER,
      borderRadius: (size + size * DEFAULT_SIZE_MULTIPLIER) / 2,
      borderWidth: size * DEFAULT_OUTER_BORDER_WIDTH_MULTIPLIER
    }

    const innerStyle = {
      width: size,
      height: size,
      borderRadius: size / 2,
      backgroundColor: innerColor
    }

    /// 2) Style for unselected radio - was null in open source
    const innerStyleUnselected = {
        ...innerStyle,
        backgroundColor: transparent,
    }

    /// 3) Put text in. Make sure inner View not null
    return (
      <TouchableOpacity style={[styles.radio, outerStyle]} onPress={onPress}>
        <View style={isSelected ? innerStyle : innerStyleUnselected}>
            <Text style={this.props.textStyle}>{this.props.text}</Text>
        </View>
      </TouchableOpacity>
    )
  }
}

const styles = StyleSheet.create({
  radio: {
    justifyContent: 'center',
    alignItems: 'center',
    alignSelf: 'center'
  }
})
person Val    schedule 05.12.2017
comment
@Artyom, это была бы еще одна проблема со стилем. Мой ответ о том, как изменить открытый исходный код, чтобы добавить <Text />. Это может стать еще одной большой темой, если мы поговорим о том, как выровнять текст по вашему желанию. - person Val; 06.12.2017
comment
например, стиль textAlignVertical полезен для выравнивания текста. Но, к сожалению, это только для Android. Если вы хотите, чтобы это работало и для iOS, уже есть много других ответов. stackoverflow.com/questions/34969848 / - person Val; 06.12.2017