reactjs 如何使用Scrollview与KeyboardAvoidingView

q8l4jmvw  于 4个月前  发布在  React
关注(0)|答案(1)|浏览(32)

我是一个新手,我想知道如何在下面的场景中使用scrollView和keyboardAvoid。我已经搜索了一些相关的信息,但仍然没有线索。
下图可能比解释更直观。
enter image description here

import  React,{useRef,useEffect,useState} from 'react';
import { Text, View, StyleSheet,TextInput,ScrollView,KeyboardAvoidingView,TouchableOpacity } from 'react-native';

export default function App() {
  const [selectedItem,setSeLectedItem] = useState(null)
  const [userTyping,setUserTyping] = useState(false);

    const selected = (index) => {
    setUserTyping(true)
      setSeLectedItem(index)
    }
  const onBlur=()=>{
    setUserTyping(false)
  }

  return (
    <View style={styles.container}>
            <KeyboardAvoidingView style={{flex:1}}>
            <ScrollView style={styles.scroll} >
                    {
                        ['1', '2', '3', '4','5','6','7'].map((item,index) => (
                            <TouchableOpacity onPress={()=>selected(index)} key={item}>
                            <View style={[styles.itemWrapper,selectedItem===index &&styles.selectedItem]}>
                                <Text style={styles.itemText}>TEST {item}</Text>
                                {
                                    (selectedItem===index)&&userTyping&&
                                    <InputFC 
                                        style={styles.itemInput} 
                                        placeholder='NO TEXT' 
                                        placeholderTextColor={'white'} 
                                        autoCapitalize={'none'}
                                        onBlur={onBlur}
                                    />
                                }                           
                            </View>
                        </TouchableOpacity>
                        ))
                    }
                </ScrollView>
            </KeyboardAvoidingView>
    </View>
  );
}

const InputFC = (props) => {
    const {style,placeholder,placeholderTextColor,autoCapitalize,onBlur} = props
    const inputRef = useRef(null);
    
    useEffect(()=>{
        if(inputRef.current) inputRef?.current?.focus()
    })
    
    return (
    <TextInput 
        style={style} 
        ref={inputRef}
        placeholder={placeholder}
        placeholderTextColor={placeholderTextColor} 
        autoCapitalize={autoCapitalize}
    onBlur={onBlur}
    />)
}

const styles = StyleSheet.create({
    container: {
        flex: 1,
        backgroundColor: '#24292e',
    },
    scroll: {
        flex: 1,
        paddingHorizontal: 20,
    },

    itemWrapper:{
        width: '100%',
        paddingLeft:20,
        paddingVertical:20,
        marginBottom: 20,
        backgroundColor: '#6b6965',
        borderRadius:20,
    },
    itemText:{
        fontSize:20,
        fontWeight:'bold',
        color:'white',
        alignItems:'center',
        justifyContent:'center',
        marginBottom:5,
    }
    ,
    itemInput:{
        fontSize:20,
        color:'white',
    },
    selectedItem:{
        borderWidth:3,
        borderColor:'#2188ff'
    }
});

字符串
简化的在线演示:
https://snack.expo.dev/@bravo20203/demo-about-scrollview
谢谢.

f0ofjuux

f0ofjuux1#

您可以通过将flex: 1更改为不同的组件并添加

behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
style={{flex: 1}}

字符串
KeyboardAvoidingView。我还将您的内容 Package 到SafeAreaView中,因此它不会进入iOS的头部。
由于您在按下时动态扩展TextInput,这会更改其高度,因此我向KeyboardAvoidingView添加了keyboardVerticalOffset并使溢出可见。
最后的代码如下。

import { useEffect, createRef, useState, useRef } from "react";
import { useHeaderHeight } from "@react-navigation/elements";
import {
  Text,
  View,
  KeyboardAvoidingView,
  ScrollView,
  TextInput,
  Platform,
  TouchableOpacity,
  StyleSheet,
  SafeAreaView,
} from "react-native";

export default function App() {
  const [selectedItem, setSeLectedItem] = useState(null);
  const [userTyping, setUserTyping] = useState(false);

  const selected = (index) => {
    setUserTyping(true);
    setSeLectedItem(index);
  };
  const onBlur = () => {
    setUserTyping(false);
  };

  return (
    <SafeAreaView style={styles.container}>
      <KeyboardAvoidingView
        behavior={Platform.OS === "ios" ? "padding" : "height"}
        style={Platform.OS === "ios" && { flex: 1 }}
        keyboardVerticalOffset={30}
      >
        <ScrollView style={styles.scroll}>
          {["1", "2", "3", "4", "5", "6", "7"].map((item, index) => (
            <TouchableOpacity onPress={() => selected(index)} key={item}>
              <View
                style={[
                  styles.itemWrapper,
                  selectedItem === index && styles.selectedItem,
                ]}
              >
                <Text style={styles.itemText}>TEST {item}</Text>
                {selectedItem === index && userTyping && (
                  <InputFC
                    style={styles.itemInput}
                    placeholder="NO TEXT"
                    placeholderTextColor={"white"}
                    autoCapitalize={"none"}
                    onBlur={onBlur}
                  />
                )}
              </View>
            </TouchableOpacity>
          ))}
        </ScrollView>
      </KeyboardAvoidingView>
    </SafeAreaView>
  );
}

const InputFC = (props) => {
  const { style, placeholder, placeholderTextColor, autoCapitalize, onBlur } =
    props;
  const inputRef = useRef(null);

  useEffect(() => {
    if (inputRef.current) inputRef?.current?.focus();
  });

  return (
    <TextInput
      style={style}
      ref={inputRef}
      placeholder={placeholder}
      placeholderTextColor={placeholderTextColor}
      autoCapitalize={autoCapitalize}
      onBlur={onBlur}
    />
  );
};

const styles = StyleSheet.create({
  container: {
    backgroundColor: "#24292e",
    flex: 1,
  },
  scroll: {
    paddingHorizontal: 20,
    overflow: "visible",
  },

  itemWrapper: {
    width: "100%",
    paddingLeft: 20,
    paddingVertical: 20,
    marginBottom: 20,
    backgroundColor: "#6b6965",
    borderRadius: 20,
  },
  itemText: {
    fontSize: 20,
    fontWeight: "bold",
    color: "white",
    alignItems: "center",
    justifyContent: "center",
    marginBottom: 5,
  },
  itemInput: {
    fontSize: 20,
    color: "white",
  },
  selectedItem: {
    borderWidth: 3,
    borderColor: "#2188ff",
  },
});


我已经更新了your snack here。请注意,我只在iOS上测试了这个。
如果键盘在选择时打开,则所选输入现在完全可见。

相关问题