我正在尝试将KeyboardAvoidingView与behavior="padding"
一起使用。
出于某种原因,当我尝试在TextInput
中输入任何文本时,TextInput下方有一个空格。随附的是正在发生的事情以及代码。有没有人有任何想法在这里发生什么?
render() {
return (
<KeyboardAvoidingView style={{ flex: 1}} behavior="padding">
< View
style={{
flex: 1,
backgroundColor: "#FFFFFF",
}}
>
<ScrollView
contentContainerStyle={{ justifyContent: "flex-end", flex: 1 }}>
<ChatInfo />
</ScrollView>
<View style={styles.container}>
<TextInput
style={styles.input}
underlineColorAndroid="transparent"
autoCapitalize="none"
onChangeText={text => this.setState({ text: text })}
value={this.state.text}
/>
<TouchableOpacity
style={styles.submitButton}
onPress={this.submitName}
>
<Text style={styles.submitButtonText}> SEND </Text>
</TouchableOpacity>
</View>
</ View>
</KeyboardAvoidingView>
);
}
}
export default connect()(ChatScreen);
const styles = StyleSheet.create({
input: {
margin: 2,
paddingLeft: 15,
flex: 1,
height: 40,
padding: 10,
fontSize: 14,
fontWeight: "400"
},
container: {
borderTopWidth: 1,
minWidth: "100%",
borderColor: "#cccccc",
height: 44,
flexDirection: "row",
justifyContent: "space-between",
backgroundColor: "#fff"
},
submitButtonText: {
color: "#0a9ffc",
fontSize: 14,
fontWeight: "500"
},
submitButton: {
backgroundColor: "#fff",
padding: 10,
margin: 2,
height: 40,
alignItems: "center",
justifyContent: "center"
}
});
答案 0 :(得分:60)
如果您使用反应导航,这会受到反应导航标题的影响。标头的高度在不同的移动屏幕上有所不同。因此,您必须获取标题的高度并将其传递给keyboardVerticalOffset道具。
import { Header } from 'react-navigation';
<KeyboardAvoidingView
keyboardVerticalOffset = {Header.HEIGHT + 20} // adjust the value here if you need more padding
style = {{ flex: 1 }}
behavior = "padding" >
<ScrollView>
<TextInput/>
<TextInput/>
<TextInput/>
<TextInput/>
<TextInput/>
<TextInput/>
</ScrollView>
</KeyboardAvoidingView>
答案 1 :(得分:14)
这是KeyboardAvoidingView和Android的已知问题。有多种方法可以解决这个问题。
React Native文档说:
如果没有任何行为道具,Android可能表现得更好,而iOS则相反。
因此,如果您只使用Android,您可以删除行为道具,它应该可以立即使用。为获得最佳效果,请将android:windowSoftInputMode="adjustResize"
添加到您的清单中。
或者你可以给出一个适合你的偏移值:
KeyboardAvoidingView keyboardVerticalOffset={-500} behavior="padding"
对于ios有条件地做同样的事情:
behavior= {(Platform.OS === 'ios')? "padding" : null}
keyboardVerticalOffset={Platform.select({ios: 0, android: 500})}
答案 2 :(得分:6)
这似乎只是部分解决方案,尽管它最初可以工作,但是如果使用避免键盘布局的键盘将android手机锁定在屏幕上,则在解锁时最终会再次在键盘上方出现多余的填充。
从android:windowSoftInputMode="adjustResize"
删除AndroidManifest.xml
...
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
android:windowSoftInputMode="adjustResize"
>
...
...
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
>
...
如果我正确理解了该问题,那么我一直在处理同一件事。通过在清单中添加android:windowSoftInputMode="adjustResize"
,Android系统将尝试执行与KeyboardAvoidingView
相同的工作。这导致仅在Android键盘上方添加额外的间距。
如果在两个平台上都可以使用,则每次使用键盘输入时都必须在iOS上进行处理,因此最好通过清单中的android:windowSoftInputMode="adjustResize"
并使用{{ 1}}。
答案 3 :(得分:4)
这里的许多答案都显示了条件行为道具值。这样。
// incorrect ?
<KeyboardAvoidingView
style = {{ flex: 1 }}
behavior={Platform.OS === "ios" ? "padding" : null}>
</KeyboardAvoidingView>
但是这会将behavior
道具在Android上设置为null。
Android和iOS与该道具的交互方式不同。
如果完全不提供行为支持,Android可能会表现更好,而iOS则相反。
有条件地展开behavior
道具可提供精确的解决方案。
它在iOS上添加了道具,而在Android上却保留了它。
// correct ?
<KeyboardAvoidingView
style = {{ flex: 1 }}
{...(Platform.OS === 'ios' && { behavior: 'padding' })}
</KeyboardAvoidingView>
这是一个解决方案,如果使用styled-components
且在Android上不使用不必要的KeyboardAvoidingView。
import { KeyboardAvoidingView as Kav, Platform, View } from 'react-native';
import styled from 'styled-components/native';
// If ios we change the component type and, via the `attrs` method, add a behavior prop. This
// approach leaves Android alone. Because it already works.
export const ScreenContainer = styled(Platform.OS === 'ios' ? Kav : View).attrs({
behavior: Platform.OS === 'ios' && 'padding',
})`
flex: 1;
`;
答案 4 :(得分:3)
KeyboardAvoidingView
必须是ScrollView
孩子,而不是相反。这样它的行为正常(正常我用它的目的)。试一试,让我知道它是怎么回事。
<ScrollView>
<KeyboardAvoidingView styles={styles.container} behavior='padding'>
</KeyboardAvoidingView>
</ScrollView>
答案 5 :(得分:2)
对于 React Native Navigation v5,您可以使用以下内容:
import { useHeaderHeight } from '@react-navigation/stack';
...
const Component = () => (
<KeyboardAvoidingView
keyboardVerticalOffset={ useHeaderHeight() } // <-- for v5
behavior="padding"
style={{ flex: 1 }}
>
<TextInput
style={{ height: 30, width: "100%, borderWidth: 1 }}
/>
</KeyboardAvoidingView
)
https://reactnavigation.org/docs/stack-navigator#headertransparent
答案 6 :(得分:2)
<KeyboardAvoidingView behavior={Platform.OS === "ios" ? "padding" : null}
style={{flex: 1 }}>
在上面的代码段中,flex设置为1,即使没有打开键盘,默认情况下也会在键盘上方呈现文本输入字段。而且,当键盘弹出时,输入字段会因键盘高度的偏移而进一步向上推。
将flex设置为0可以解决此问题,就像我的情况一样。
<KeyboardAvoidingView behavior={Platform.OS === "ios" ? "padding" : null}
style={{flex: 0 }}>
<View>
...
</View>
</KeyboardAvoidingView>
答案 7 :(得分:2)
KeyboardAvoidingView的主要问题是;缺少对它如何工作的了解。
我发现下面的链接非常有帮助
https://medium.com/@nickyang0501/keyboardavoidingview-not-working-properly-c413c0a200d4
希望有帮助
答案 8 :(得分:2)
我认为这是因为behavior props value,所以我认为在Keyboardavoidview中添加这一行会有所帮助
<KeyboardAvoidingView
style = {{ flex: 1 }}
behavior={Platform.OS === "ios" ? "padding" : null}>
</KeyboardAvoidingView>
答案 9 :(得分:2)
<KeyboardAvoidingView styles={styles.container} behavior = 'padding' enabled>
<ScrollView>
<View>
....
</View>
</ScrollView>
</KeyboardAvoidingView>
答案 10 :(得分:1)
我认为最好的方法是为此创建一个HOC,此外,通过使用react-native-iphone-x-helper中的getBottomSpace,您可以解决iPhone X和...的重叠问题。
def update51P(self, obj):
app = MDApp.get_running_app()
print(app.Alpick51P)
print(app.Aldelay51P)
print(app.Trpick51P)
print(app.InverseCurve)
答案 11 :(得分:1)
应用 ScrollView
后,问题就解决了。
答案 12 :(得分:0)
<KeyboardAvoidingView style={styles.keyboardcontainer} behavior="padding"
keyboardVerticalOffset={Platform.select({ios :120, android : 500})}
enabled>
<View style={{flex: 1 }}>
// Your Code
</View>
</KeyboardAvoidingView>
答案 13 :(得分:0)
我的问题是使用keyboardHidesTabBar
选项。以下设置对我有用:
const AppBottomTabNavigator = createBottomTabNavigator(
{
...
},
{
tabBarOptions: {
keyboardHidesTabBar: Platform.OS !== 'ios',
},
},
);
组件:
import React from 'react';
import {
Keyboard,
KeyboardAvoidingView,
Platform,
StyleSheet,
Text,
TextInput,
TouchableWithoutFeedback,
View,
} from 'react-native';
import { Header } from 'react-navigation-stack';
const styles = StyleSheet.create({
container: {
flex: 1,
},
center: {
justifyContent: 'center',
alignItems: 'center',
},
textInput: {
height: 40,
borderColor: 'gray',
borderWidth: 1,
},
});
const MyScreen = () => {
return (
<KeyboardAvoidingView
behavior={Platform.OS === 'ios' ? 'padding' : null}
keyboardVerticalOffset={Header.HEIGHT}
style={styles.container}
>
<TouchableWithoutFeedback onPress={Keyboard.dismiss}>
<View style={styles.container}>
<View style={[styles.container, styles.center]}>
<Text>Hello!</Text>
</View>
<TextInput style={styles.textInput} placeholder="Message" />
</View>
</TouchableWithoutFeedback>
</KeyboardAvoidingView>
);
};
export default MyScreen;
答案 14 :(得分:0)
我的问题不是检查此平台类型
将以下代码添加到KeyboardAvoidView
中为我修复了
behavior={Platform.OS === "ios" ? "padding" : 'height'}
答案 15 :(得分:0)
虽然它不是一个正确的答案,但是有一个非常流行的库可以解决这种类型的问题,它被称为可以在具有可用键盘区域的情况下使用scrollview。您可以通过以下链接查看 https://www.npmjs.com/package/react-native-keyboard-aware-scrollview
答案 16 :(得分:0)
我遇到了类似的问题,因为我正在使用带有底部标签的#include <cstdio>
#include <Windows.h>
// Windows multimedia device
#include <Mmdeviceapi.h>
#include <Functiondiscoverykeys_devpkey.h>
// WASAPI
#include <Audiopolicy.h>
#include <Audioclient.h>
#include <random>
class Noise_Gen {
public:
Noise_Gen() : format(), engine(__rdtsc()), float_dist(-1.f, 1.f) {};
void SetFormat(WAVEFORMATEX* wfex) {
if(wfex->wFormatTag == WAVE_FORMAT_EXTENSIBLE) {
format = *reinterpret_cast<WAVEFORMATEXTENSIBLE*>(wfex);
} else {
format.Format = *wfex;
format.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
INIT_WAVEFORMATEX_GUID(&format.SubFormat, wfex->wFormatTag);
format.Samples.wValidBitsPerSample = format.Format.wBitsPerSample;
format.dwChannelMask = 0;
}
}
// (The size of an audio frame = nChannels * wBitsPerSample)
void FillBuffer(UINT32 bufferFrameCount, BYTE* pData, DWORD* flags) {
const UINT16 formatTag = EXTRACT_WAVEFORMATEX_ID(&format.SubFormat);
if(formatTag == WAVE_FORMAT_IEEE_FLOAT) {
float* fData = (float*)pData;
for(UINT32 i = 0; i < format.Format.nChannels * bufferFrameCount; i++) {
fData[i] = float_dist(engine);
}
} else if(formatTag == WAVE_FORMAT_PCM) {
using rndT = decltype(engine)::result_type;
UINT32 iterations = format.Format.nBlockAlign * bufferFrameCount / sizeof(rndT);
UINT32 leftoverBytes = format.Format.nBlockAlign * bufferFrameCount % sizeof(rndT);
rndT* iData = (rndT*)pData;
UINT32 i = 0;
for(; i < iterations; i++) {
iData[i] = engine();
}
if(leftoverBytes != 0) {
rndT lastRnd = engine();
BYTE* pLastBytes = pData + i * sizeof(rndT);
for(UINT32 j = 0; j < leftoverBytes; ++j) {
pLastBytes[j] = lastRnd >> (j * 8) & 0xFF;
}
}
} else {
//memset(pData, 0, wfex.Format.nBlockAlign * bufferFrameCount);
*flags = AUDCLNT_BUFFERFLAGS_SILENT;
}
}
private:
WAVEFORMATEXTENSIBLE format;
std::mt19937_64 engine;
std::uniform_real_distribution<float> float_dist;
};
// REFERENCE_TIME time units per second and per millisecond
#define REFTIMES_PER_SEC 10000000ll
#define REFTIMES_PER_MILLISEC 10000
#define EXIT_ON_ERROR(hres) \
if (FAILED(hres)) { goto Exit; }
#define SAFE_RELEASE(punk) \
if ((punk) != NULL) \
{ (punk)->Release(); (punk) = NULL; }
HRESULT PlayAudioStream(Noise_Gen* pMySource) {
HRESULT hr;
REFERENCE_TIME hnsRequestedDuration = REFTIMES_PER_SEC;
REFERENCE_TIME hnsActualDuration;
IMMDeviceEnumerator* pEnumerator = NULL;
IPropertyStore* pPropertyStore = NULL;
IMMDevice* pDevice = NULL;
IAudioClient* pAudioClient = NULL;
IAudioRenderClient* pRenderClient = NULL;
WAVEFORMATEX* pwfx = NULL;
UINT32 bufferFrameCount;
BYTE* pData;
DWORD flags = 0;
PROPVARIANT name;
hr = CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL,
CLSCTX_ALL, IID_PPV_ARGS(&pEnumerator));
EXIT_ON_ERROR(hr);
hr = pEnumerator->GetDefaultAudioEndpoint(
eRender, eConsole, &pDevice);
EXIT_ON_ERROR(hr);
hr = pDevice->OpenPropertyStore(STGM_READ, &pPropertyStore);
EXIT_ON_ERROR(hr);
PropVariantInit(&name);
hr = pPropertyStore->GetValue(PKEY_Device_FriendlyName, &name);
EXIT_ON_ERROR(hr);
printf("%S", name.pwszVal);
printf("\n");
hr = pDevice->Activate(__uuidof(pAudioClient), CLSCTX_ALL,
NULL, (void**) &pAudioClient);
EXIT_ON_ERROR(hr);
hr = pAudioClient->GetMixFormat(&pwfx);
EXIT_ON_ERROR(hr);
hr = pAudioClient->Initialize(AUDCLNT_SHAREMODE_SHARED,
0, hnsRequestedDuration,
0, pwfx, NULL);
EXIT_ON_ERROR(hr);
// Tell the audio source which format to use.
pMySource->SetFormat(pwfx);
// Get the actual size of the allocated buffer.
hr = pAudioClient->GetBufferSize(&bufferFrameCount);
EXIT_ON_ERROR(hr);
hr = pAudioClient->GetService(IID_PPV_ARGS(&pRenderClient));
EXIT_ON_ERROR(hr);
// Grab the entire buffer for the initial fill operation.
hr = pRenderClient->GetBuffer(bufferFrameCount, &pData);
EXIT_ON_ERROR(hr);
// Load the initial data into the shared buffer.
pMySource->FillBuffer(bufferFrameCount, pData, &flags);
hr = pRenderClient->ReleaseBuffer(bufferFrameCount, flags);
EXIT_ON_ERROR(hr);
// Calculate the actual duration of the allocated buffer.
hnsActualDuration = REFTIMES_PER_SEC * bufferFrameCount / pwfx->nSamplesPerSec;
hr = pAudioClient->Start(); // Start playing.
EXIT_ON_ERROR(hr);
// Each loop fills about half of the shared buffer.
DWORD sleepTime;
while(flags != AUDCLNT_BUFFERFLAGS_SILENT) {
// Sleep for half the buffer duration.
sleepTime = (DWORD) (hnsActualDuration / REFTIMES_PER_MILLISEC / 2);
if(sleepTime != 0)
Sleep(sleepTime);
// See how much buffer space is available.
UINT32 numFramesPadding;
hr = pAudioClient->GetCurrentPadding(&numFramesPadding);
EXIT_ON_ERROR(hr);
UINT32 numFramesAvailable = bufferFrameCount - numFramesPadding;
// Grab all the available space in the shared buffer.
hr = pRenderClient->GetBuffer(numFramesAvailable, &pData);
EXIT_ON_ERROR(hr);
// Get next 1/2-second of data from the audio source.
pMySource->FillBuffer(numFramesAvailable, pData, &flags);
hr = pRenderClient->ReleaseBuffer(numFramesAvailable, flags);
EXIT_ON_ERROR(hr);
}
// Wait for last data in buffer to play before stopping.
sleepTime = (DWORD) (hnsActualDuration / REFTIMES_PER_MILLISEC / 2);
if(sleepTime != 0)
Sleep(sleepTime);
hr = pAudioClient->Stop(); // Stop playing.
EXIT_ON_ERROR(hr);
Exit:
CoTaskMemFree(pwfx);
SAFE_RELEASE(pRenderClient);
SAFE_RELEASE(pAudioClient);
SAFE_RELEASE(pDevice);
SAFE_RELEASE(pPropertyStore); // you forgot to free the property store
SAFE_RELEASE(pEnumerator);
return hr;
}
int main() {
HRESULT hr = CoInitialize(nullptr);
if(FAILED(hr)) { return hr; }
Noise_Gen ng;
PlayAudioStream(&ng);
CoUninitialize();
}
。
从@react-navigation
开始,您可以通过以下两种方式之一来获取底部标签栏的高度(API reference):
"@react-navigation/bottom-tabs": "^5.11.2"
或
import { BottomTabBarHeightContext } from '@react-navigation/bottom-tabs';
// ...
<BottomTabBarHeightContext.Consumer>
{tabBarHeight => (
/* render something */
)}
</BottomTabBarHeightContext.Consumer>
,然后将其设置为import { useBottomTabBarHeight } from '@react-navigation/bottom-tabs';
// ...
const tabBarHeight = useBottomTabBarHeight();
的偏移量:
KeyboardAvoidingView
答案 17 :(得分:0)
请记住始终是您的顶级父级,具有 flex:1 然后子级是您的文本输入容器,如果您使用此方法,则它始终是其测试方法。
<KeyboardAvoidingView style={{ flex: 1 }}
behavior={Platform.OS === "ios" ? "position" : null} enabled>
<ScrollView>
<View>
<View >
<Text maxFontSizeMultiplier={1.5} >
Sign in to your account{" "}
</Text>
<View
behavior="padding"
enabled
>
<TextInput
placeholder="Email address"
placeholderTextColor={Colors.grey}
style={styles.textInput}
onChangeText={(e) => setEmail(e.trim())}
autoCapitalize="none"
returnKeyType={"done"}
/>
</View>
</View>
</ScrollView>
</KeyboardAvoidingView>