粘贴两个柔性元件,在React性原生中动态增长

new9mtju  于 2023-01-09  发布在  React
关注(0)|答案(1)|浏览(98)

使用react-native,我希望TextInput与MaterialIcons.Button在同一行中卡住。
我希望所有元素水平居中,但使用以下代码无法实现:

import React from 'react';
import {
  StyleSheet, TextInput, View,
} from 'react-native';
import MaterialIcons from 'react-native-vector-icons/MaterialIcons';

const WordInput = () => {
  return (
    <View style={styles.container}>
      <View style={styles.textInputContainer}>
        <TextInput
          textAlign="left"
        />
      </View>
      
      <View style={styles.arrowButtonContainer}>
        <MaterialIcons.Button
          name="arrow-forward-ios"
        />
      </View>
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    flexDirection: 'row',
    flex: 1,
  },
  textInputContainer: {
    flex: 1,
    alignItems: 'flex-end',
    justifyContent: 'center',
  },
  arrowButtonContainer: {
    flex: 1,
    alignItems: 'flex-start',
    justifyContent: 'center',
  },
});

下面是关联的expo snack link
问题是当我在TextInput中键入文本时,Button根本不移动。我希望它在TextInput的宽度增加时动态向右移动。整体应该水平居中。
有人知道我该怎么做吗?
谢谢!

vyswwuz2

vyswwuz21#

不幸的是,<TextInput>在默认情况下不支持任何类型的“自动增长”行为,但是您可以使用隐藏的<Text>层自己实现一些东西,该层具有与<TextInput>相同的字体样式和大小规则。你可以测量这个元素的布局并将测量的宽度应用到你的<TextInput>组件。

import { useState } from 'react';
import { StyleSheet, TextInput, View, Dimensions, Text } from 'react-native';
import MaterialIcons from 'react-native-vector-icons/MaterialIcons';

export default function App() {
  const [value, setValue] = useState();
  const [containerWidth, setContainerWidth] = useState(
    Dimensions.get('window').width
  );
  const [textWidth, setTextWidth] = useState(0);
  const [buttonWidth, setButtonWidth] = useState(0);

  const inputWidth = Math.min(textWidth, containerWidth - buttonWidth);

  return (
    <View style={styles.root}>
      <View
        style={styles.inner}
        onLayout={(e) => setContainerWidth(e.nativeEvent.layout.width)}>
        <Text
          style={styles.hiddenText}
          onLayout={(e) => setTextWidth(e.nativeEvent.layout.width)}
          numberOfLines={1}
          accessibilityElementsHidden
          importantForAccessibility="no-hide-decendants">
          {value}
        </Text>
        <TextInput
          textAlign="left"
          placeholder="enter text"
          style={[styles.input, { width: inputWidth }]}
          onChangeText={setValue}
        />
        <View onLayout={(e) => setButtonWidth(e.nativeEvent.layout.width)}>
          <MaterialIcons.Button name="arrow-forward-ios" />
        </View>
      </View>
    </View>
  );
}

const styles = StyleSheet.create({
  root: {
    flex: 1,
    justifyContent: 'center',
  },
  inner: {
    flexDirection: 'row',
    justifyContent: 'center',
    borderWidth: 1,
    borderColor: 'red',
  },
  input: {
    borderWidth: 1,
    borderColor: 'green',
    minWidth: 100,
  },
  hiddenText: {
    position: 'absolute',
    top: 0,
    left: 0,
    opacity: 0,
  },
});

这是一个expo snack example

相关问题