软键盘出现时如何调整布局

我想在软键盘激活时调整/重新调整布局大小,如下所示:

前后对比:

enter image description hereenter image description here


在SO中发现了一对资源:

  1. 如何保持所有字段和文本可见,而软键盘显示
  2. android软键盘破坏布局时出现
  3. 当软键盘打开时调整布局

但是问题&我的答案相当模糊,下面这个问题更清楚地说明了我想要什么。

要求:

  • 它应该适用于任何屏幕尺寸的手机。
  • 注意到“FACEBOOK”和“Sign Up for .”的空白/填充空间 Facebook“前后都发生了变化。李< / >
  • 不涉及滚动视图。
238358 次浏览

只需添加

android:windowSoftInputMode="adjustResize"

在你的AndroidManifest.xml中声明这个特定的活动,这将调整布局调整大小选项。

enter image description here

下面是一些布局设计的源代码

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >


<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginTop="20dp"
android:text="FaceBook"
android:textAppearance="?android:attr/textAppearanceLarge" />


<EditText
android:id="@+id/editText1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/textView1"
android:layout_marginTop="30dp"
android:ems="10"
android:hint="username" >


<requestFocus />
</EditText>


<EditText
android:id="@+id/editText2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/editText1"
android:layout_marginTop="20dp"
android:ems="10"
android:hint="password" />


<Button
android:id="@+id/button1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/editText2"
android:layout_centerHorizontal="true"
android:layout_marginLeft="18dp"
android:layout_marginTop="20dp"
android:text="Log In" />


<TextView
android:id="@+id/textView2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_marginTop="17dp"
android:gravity="center"
android:text="Sign up for facebook"
android:textAppearance="?android:attr/textAppearanceLarge" />


</RelativeLayout>

Android Developer有正确的答案,但提供的源代码相当冗长,并没有实际实现图中描述的模式。

下面是一个更好的模板:

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true">


<RelativeLayout android:layout_width="match_parent"
android:layout_height="match_parent">


<LinearLayout android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">


<!-- stuff to scroll -->


</LinearLayout>


<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true">


<!-- footer -->


</FrameLayout>


</RelativeLayout>


</ScrollView>

它由你决定什么视图你使用“滚动”和“页脚”部分。还要知道你可能必须设置__abc fillViewPort . < / p >

在您的清单中添加这一行,您的活动被调用

android:windowSoftInputMode="adjustPan|adjustResize"

你可以在你的onCreate中添加这一行

getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE|WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
这个问题几年前就有人问过了,“Secret Andro Geni”有一个很好的基础解释,“tir38”也对完整的解决方案做了很好的尝试,但遗憾的是,这里没有完整的解决方案。 我已经花了几个小时来解决问题,下面是我的完整解决方案,底部有详细的解释:

<?xml version="1.0" encoding="utf-8"?>
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true">


<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp">


<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_above="@+id/mainLayout"
android:layout_alignParentTop="true"
android:id="@+id/headerLayout">


<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:gravity="center_horizontal">


<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/textView1"
android:text="facebook"
android:textStyle="bold"
android:ellipsize="marquee"
android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceLarge" />


</LinearLayout>


</RelativeLayout>


<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:id="@+id/mainLayout"
android:orientation="vertical">


<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/editText1"
android:ems="10"
android:hint="Email or Phone"
android:inputType="textVisiblePassword">


<requestFocus />
</EditText>


<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:id="@+id/editText2"
android:ems="10"
android:hint="Password"
android:inputType="textPassword" />


<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:id="@+id/button1"
android:text="Log In"
android:onClick="login" />


</LinearLayout>


<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_below="@+id/mainLayout"
android:id="@+id/footerLayout">


<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true">


<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">


<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/textView2"
android:text="Sign Up for Facebook"
android:layout_centerHorizontal="true"
android:layout_alignBottom="@+id/helpButton"
android:ellipsize="marquee"
android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceSmall" />


<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:id="@+id/helpButton"
android:text="\?"
android:onClick="help" />


</RelativeLayout>


</LinearLayout>


</RelativeLayout>


</RelativeLayout>


</ScrollView>

AndroidManifest.xml中,不要忘记设置:

android:windowSoftInputMode="adjustResize"

<activity>标记,你想要这样的布局。

想法:

我已经意识到RelativeLayout是横跨所有可用空间的布局,然后在键盘弹出时调整大小。

LinearLayout是在调整大小过程中不会被调整大小的布局。

这就是为什么你需要在ScrollView之后有一个RelativeLayout来跨越所有可用的屏幕空间。你需要在RelativeLayout中有一个LinearLayout,否则当调整大小发生时,你的内部会被压碎。一个很好的例子是“headerLayout”。如果里面没有LinearLayoutRelativeLayout“facebook”文本就会被压碎,不会显示。

在“facebook”登录图片张贴在问题中,我还注意到,整个登录部分(mainLayout)是垂直于整个屏幕居中,因此属性:

android:layout_centerVertical="true"

LinearLayout布局上。因为mainLayout在LinearLayout中,这意味着该部分不会被调整大小(再次参见有问题的图片)。

对我来说,这很有帮助。

main_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main2"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:orientation="vertical"
tools:context="com.livewallpaper.profileview.loginact.Main2Activity">


<TextView
android:layout_weight="1"
android:layout_width="match_parent"
android:text="Title"
android:gravity="center"
android:layout_height="0dp" />
<LinearLayout
android:layout_weight="1"
android:layout_width="match_parent"
android:layout_height="0dp">
<EditText
android:hint="enter here"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
<TextView
android:layout_weight="1"
android:text="signup for App"
android:gravity="bottom|center_horizontal"
android:layout_width="match_parent"
android:layout_height="0dp" />
</LinearLayout>

manifest文件中使用

<activity android:name=".MainActivity"
android:screenOrientation="portrait"
android:windowSoftInputMode="adjustResize"/>
现在是最重要的部分! 在ActivityApplication标签中使用这样的主题
android:theme="@style/AppTheme"

主题是这样的

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
<item name="windowActionModeOverlay">true</item>
</style>

所以我错过了主题。这让我一整天都很沮丧。

你可以简单地在AndroidManifest.xml文件中设置这些选项。

<activity
android:name=".YourACtivityName"
android:windowSoftInputMode="stateVisible|adjustResize">

谷歌不建议使用adjustPan,因为用户可能需要关闭键盘才能看到所有输入字段。

更多信息:Android应用程序清单

它可以工作于所有类型的布局。

  1. 将此添加到AndroidManifest.xml中的activity标签中

android: windowSoftInputMode = " adjustResize "

例如:

<activity android:name=".ActivityLogin"
android:screenOrientation="portrait"
android:theme="@style/AppThemeTransparent"
android:windowSoftInputMode="adjustResize"/>
  1. 将此添加到activitypage.xml中的布局标签上,将改变其位置。

android: fitsSystemWindows = " true "

而且

android: layout_alignParentBottom = " true "

例如:

<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:fitsSystemWindows="true">

对我来说,它是用下面这行代码实现的:

getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
把它放到onCreate方法中。 最好!< / p >

这使得它可以显示任何想要的布局之前隐藏的键盘。

将此添加到AndroidManifest.xml中的activity标签中

android: windowSoftInputMode = " adjustResize "

< p >
用ScrollView包围根视图,最好使用scrollbars=none。ScrollView不会正确地改变你的布局,除了用来解决这个问题 然后在你想要完全显示在键盘上方的视图上设置fitsSystemWindows="true"。 这将使您的EditText在键盘上方可见,并且可以向下滚动到EditText下面的部分,但在视图中使用fitsSystemWindows="true"

android: fitsSystemWindows = " true "

例如:

<ScrollView
android:id="@+id/scrollView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="none">


<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true">


...


</android.support.constraint.ConstraintLayout>
</ScrollView>

如果你想在键盘出现时显示fitsSystemWindows="true"视图的完整部分,你需要一些代码来将视图滚动到底部:

// Code is in Kotlin


setupKeyboardListener(scrollView) // call in OnCreate or similar




private fun setupKeyboardListener(view: View) {
view.viewTreeObserver.addOnGlobalLayoutListener {
val r = Rect()
view.getWindowVisibleDisplayFrame(r)
if (Math.abs(view.rootView.height - (r.bottom - r.top)) > 100) { // if more than 100 pixels, its probably a keyboard...
onKeyboardShow()
}
}
}


private fun onKeyboardShow() {
scrollView.scrollToBottomWithoutFocusChange()
}


fun ScrollView.scrollToBottomWithoutFocusChange() { // Kotlin extension to scrollView
val lastChild = getChildAt(childCount - 1)
val bottom = lastChild.bottom + paddingBottom
val delta = bottom - (scrollY + height)
smoothScrollBy(0, delta)
}

完整布局示例:

<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true">


<RelativeLayout
android:id="@+id/statisticsLayout"
android:layout_width="match_parent"
android:layout_height="340dp"
android:background="@drawable/some"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">


<ImageView
android:id="@+id/logoImageView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="64dp"
android:src="@drawable/some"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />


</RelativeLayout>


<RelativeLayout
android:id="@+id/authenticationLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginEnd="32dp"
android:layout_marginStart="32dp"
android:layout_marginTop="20dp"
android:focusableInTouchMode="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/statisticsLayout">


<android.support.design.widget.TextInputLayout
android:id="@+id/usernameEditTextInputLayout"
android:layout_width="match_parent"
android:layout_height="68dp">


<EditText
android:id="@+id/usernameEditText"
android:layout_width="match_parent"
android:layout_height="wrap_content" />


</android.support.design.widget.TextInputLayout>


<android.support.design.widget.TextInputLayout
android:id="@+id/passwordEditTextInputLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/usernameEditTextInputLayout">


<EditText
android:id="@+id/passwordEditText"
android:layout_width="match_parent"
android:layout_height="wrap_content" />


</android.support.design.widget.TextInputLayout>


<Button
android:id="@+id/loginButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/passwordEditTextInputLayout"
android:layout_centerHorizontal="true"
android:layout_marginBottom="10dp"
android:layout_marginTop="20dp" />


<Button
android:id="@+id/forgotPasswordButton"
android:layout_width="wrap_content"
android:layout_height="40dp"
android:layout_below="@id/loginButton"
android:layout_centerHorizontal="true" />


</RelativeLayout>


</android.support.constraint.ConstraintLayout>

很多答案都是正确的。在AndroidManifest中我写了:

<activity
android:name=".SomeActivity"
android:configChanges="orientation|keyboardHidden|screenSize" // Optional, doesn't affect.
android:theme="@style/AppTheme.NoActionBar"
android:windowSoftInputMode="adjustResize" />

在我的例子中,我在styles.xml中添加了一个主题,但你可以使用你自己的主题:

<style name="AppTheme.NoActionBar" parent="AppTheme">
<!--  Hide ActionBar -->
<item name="windowNoTitle">true</item>
<item name="windowActionBar">false</item>
</style>

我注意到,如果我使用全屏主题,调整大小不会发生:

<style name="AppTheme.FullScreenTheme" parent="AppTheme">
<!--  Hide ActionBar -->
<item name="windowNoTitle">true</item>
<item name="windowActionBar">false</item>
<!--  Hide StatusBar -->
<item name="android:windowFullscreen">true</item>
</style>

同样在我的情况下,adjustResize工作,但adjustPan不行。

对于全屏幕布局,请参见当软键盘可见时,如何在全屏模式下调整布局https://gist.github.com/grennis/2e3cd5f7a9238c59861015ce0a7c5584中的变通方法。

同样https://medium.com/@sandeeptengale/problem-solved-3-android-full-screen-view-translucent-scrollview-adjustresize-keyboard-b0547c7ced32工作,但它的状态栏是透明的,所以电池,时钟,Wi-Fi图标是可见的。

如果你用文件>创建一个活动,新建>活动>全屏活动,在代码中使用:

fullscreen_content.systemUiVisibility =
View.SYSTEM_UI_FLAG_LOW_PROFILE or
View.SYSTEM_UI_FLAG_FULLSCREEN or
View.SYSTEM_UI_FLAG_LAYOUT_STABLE or
View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY or
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION or
View.SYSTEM_UI_FLAG_HIDE_NAVIGATION

你也不会得到什么结果。你可以在根容器中使用android:fitsSystemWindows="true",但是会出现StatusBar。所以从第一个环节开始使用变通方法。

我使用这个扩展类框架 当我需要重新计算高度大小onLayout我覆盖onmeasure 和减去keyboardHeight使用getKeyboardHeight()

我的创建框架谁需要调整大小与软键盘

SizeNotifierFrameLayout frameLayout = new SizeNotifierFrameLayout(context) {
private boolean first = true;


@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);


if (changed) {
fixLayoutInternal(first);
first = false;
}
}


@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(heightMeasureSpec) - getKeyboardHeight(), MeasureSpec.EXACTLY));
}


@Override
protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
boolean result = super.drawChild(canvas, child, drawingTime);
if (child == actionBar) {
parentLayout.drawHeaderShadow(canvas, actionBar.getMeasuredHeight());
}
return result;
}




};

SizeNotifierFrameLayout

public class SizeNotifierFrameLayout extends FrameLayout {


public interface SizeNotifierFrameLayoutDelegate {
void onSizeChanged(int keyboardHeight, boolean isWidthGreater);
}


private Rect                            rect            = new Rect();
private Drawable                        backgroundDrawable;
private int                             keyboardHeight;
private int                             bottomClip;
private SizeNotifierFrameLayoutDelegate delegate;
private boolean                         occupyStatusBar = true;


public SizeNotifierFrameLayout(Context context) {
super(context);
setWillNotDraw(false);
}


public Drawable getBackgroundImage() {
return backgroundDrawable;
}


public void setBackgroundImage(Drawable bitmap) {
backgroundDrawable = bitmap;
invalidate();
}


public int getKeyboardHeight() {
View rootView = getRootView();
getWindowVisibleDisplayFrame(rect);
int usableViewHeight = rootView.getHeight() - (rect.top != 0 ? AndroidUtilities.statusBarHeight : 0) - AndroidUtilities.getViewInset(rootView);
return usableViewHeight - (rect.bottom - rect.top);
}


public void notifyHeightChanged() {
if (delegate != null) {
keyboardHeight = getKeyboardHeight();
final boolean isWidthGreater = AndroidUtilities.displaySize.x > AndroidUtilities.displaySize.y;
post(new Runnable() {
@Override
public void run() {
if (delegate != null) {
delegate.onSizeChanged(keyboardHeight, isWidthGreater);
}
}
});
}
}


public void setBottomClip(int value) {
bottomClip = value;
}


public void setDelegate(SizeNotifierFrameLayoutDelegate delegate) {
this.delegate = delegate;
}


public void setOccupyStatusBar(boolean value) {
occupyStatusBar = value;
}


protected boolean isActionBarVisible() {
return true;
}


@Override
protected void onDraw(Canvas canvas) {
if (backgroundDrawable != null) {
if (backgroundDrawable instanceof ColorDrawable) {
if (bottomClip != 0) {
canvas.save();
canvas.clipRect(0, 0, getMeasuredWidth(), getMeasuredHeight() - bottomClip);
}
backgroundDrawable.setBounds(0, 0, getMeasuredWidth(), getMeasuredHeight());
backgroundDrawable.draw(canvas);
if (bottomClip != 0) {
canvas.restore();
}
} else if (backgroundDrawable instanceof BitmapDrawable) {
BitmapDrawable bitmapDrawable = (BitmapDrawable) backgroundDrawable;
if (bitmapDrawable.getTileModeX() == Shader.TileMode.REPEAT) {
canvas.save();
float scale = 2.0f / AndroidUtilities.density;
canvas.scale(scale, scale);
backgroundDrawable.setBounds(0, 0, (int) Math.ceil(getMeasuredWidth() / scale), (int) Math.ceil(getMeasuredHeight() / scale));
backgroundDrawable.draw(canvas);
canvas.restore();
} else {
int actionBarHeight =
(isActionBarVisible() ? ActionBar.getCurrentActionBarHeight() : 0) + (Build.VERSION.SDK_INT >= 21 && occupyStatusBar ? AndroidUtilities.statusBarHeight : 0);
int   viewHeight = getMeasuredHeight() - actionBarHeight;
float scaleX     = (float) getMeasuredWidth() / (float) backgroundDrawable.getIntrinsicWidth();
float scaleY     = (float) (viewHeight + keyboardHeight) / (float) backgroundDrawable.getIntrinsicHeight();
float scale      = scaleX < scaleY ? scaleY : scaleX;
int   width      = (int) Math.ceil(backgroundDrawable.getIntrinsicWidth() * scale);
int   height     = (int) Math.ceil(backgroundDrawable.getIntrinsicHeight() * scale);
int   x          = (getMeasuredWidth() - width) / 2;
int   y          = (viewHeight - height + keyboardHeight) / 2 + actionBarHeight;
canvas.save();
canvas.clipRect(0, actionBarHeight, width, getMeasuredHeight() - bottomClip);
backgroundDrawable.setBounds(x, y, x + width, y + height);
backgroundDrawable.draw(canvas);
canvas.restore();
}
}
} else {
super.onDraw(canvas);
}
}


@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
notifyHeightChanged();
}
}

这个代码适用于我。当键盘出现时,你可以滚动屏幕

< img src = " https://i.stack.imgur.com/pVbk8.png " width = " 250 " > < / p >

在AndroidManifest.xml

<activity android:name=".signup.screen_2.SignUpNameAndPasswordActivity"
android:screenOrientation="portrait"
android:windowSoftInputMode="adjustResize">
</activity>

activity_sign_up.xml

<?xml version="1.0" encoding="utf-8"?>
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
tools:context=".signup.screen_2.SignUpNameAndPasswordActivity">
<LinearLayout
android:fitsSystemWindows="true"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">


<LinearLayout
android:layout_marginTop="@dimen/dp_24"
android:layout_marginStart="@dimen/dp_24"
android:layout_marginEnd="@dimen/dp_24"
android:id="@+id/lin_name_password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">


<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:fontFamily="sans-serif-medium"
android:text="@string/name_and_password"
android:textColor="@color/colorBlack"
android:layout_marginTop="@dimen/dp_5"
android:textSize="@dimen/ts_16"/>


<EditText
android:id="@+id/edit_full_name"
android:layout_width="match_parent"
android:layout_height="@dimen/dp_44"
app:layout_constraintTop_toTopOf="parent"
android:hint="@string/email_address_hint"
android:inputType="textPersonName"
android:imeOptions="flagNoFullscreen"
android:textSize="@dimen/ts_15"
android:background="@drawable/rounded_border_edittext"
android:layout_marginTop="@dimen/dp_15"
android:paddingStart="@dimen/dp_8"
android:paddingEnd="@dimen/dp_8"
android:maxLength="100"
android:maxLines="1"/>


<EditText
android:id="@+id/edit_password"
android:layout_width="match_parent"
android:layout_height="@dimen/dp_44"
app:layout_constraintTop_toTopOf="parent"
android:hint="@string/password"
android:inputType="textPassword"
android:imeOptions="flagNoFullscreen"
android:textSize="@dimen/ts_15"
android:background="@drawable/rounded_border_edittext"
android:layout_marginTop="@dimen/dp_15"
android:paddingStart="@dimen/dp_8"
android:paddingEnd="@dimen/dp_8"
android:maxLength="100"
android:maxLines="1"/>


<TextView
android:id="@+id/btn_continue_and_sync_contacts"
android:layout_width="match_parent"
android:layout_height="@dimen/dp_44"
android:gravity="center"
android:clickable="true"
android:focusable="true"
android:layout_marginTop="@dimen/dp_15"
android:background="@drawable/btn_blue_selector"
android:enabled="false"
android:text="@string/continue_and_sync_contacts"
android:textColor="@color/colorWhite"
android:textSize="@dimen/ts_15"
android:textStyle="bold"/>


<TextView
android:id="@+id/btn_continue_without_syncing_contacts"
android:layout_width="match_parent"
android:layout_height="@dimen/dp_44"
android:gravity="center"
android:clickable="true"
android:focusable="true"
android:layout_marginTop="@dimen/dp_10"
android:enabled="false"
android:text="@string/continue_without_syncing_contacts"
android:textColor="@color/colorBlue"
android:textSize="@dimen/ts_15"
android:textStyle="bold"/>


</LinearLayout>
<!--RelativeLayout is scaled when keyboard appears-->
<RelativeLayout
android:layout_marginStart="@dimen/dp_24"
android:layout_marginEnd="@dimen/dp_24"
android:layout_marginBottom="@dimen/dp_20"
android:layout_width="match_parent"
android:layout_height="match_parent">


<LinearLayout
android:layout_alignParentBottom="true"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/tv_learn_more_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clickable="true"
android:focusable="true"
android:layout_gravity="center_horizontal"
android:text="@string/learn_more_syncing_contacts"
android:textColor="@color/black_alpha_70"
android:gravity="center"
android:layout_marginBottom="1dp"
android:textSize="@dimen/ts_13"/>


<TextView
android:id="@+id/tv_learn_more_2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clickable="true"
android:focusable="true"
android:layout_gravity="center_horizontal"
android:text="@string/learn_more"
android:fontFamily="sans-serif-medium"
android:textColor="@color/black_alpha_70"
android:textSize="@dimen/ts_13"/>
</LinearLayout>
</RelativeLayout>
</LinearLayout>
</ScrollView>

rounded_border_edittext.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_activated="true">
<shape android:shape="rectangle">
<solid android:color="#F6F6F6"/>
<corners android:radius="3dp"/>
<stroke
android:width="1dp"
android:color="@color/red"/>
</shape>
</item>
<item android:state_activated="false">
<shape android:shape="rectangle">
<solid android:color="#F6F6F6"/>
<corners android:radius="3dp"/>
<stroke
android:width="1dp"
android:color="@color/colorGray"/>
</shape>
</item>
</selector>

btn_blue_selector.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_enabled="true" android:state_pressed="true">
<shape android:shape="rectangle">
<corners android:radius="3dp"/>
<solid android:color="@color/colorBlueLight"/>
<stroke android:width="1dp" android:color="@color/colorBlueLight"/>
</shape>
</item>
<item android:state_enabled="true">
<shape android:shape="rectangle">
<corners android:radius="3dp"/>
<solid android:color="@color/colorBlue"/>
<stroke android:width="1dp" android:color="@color/colorBlue"/>
</shape>
</item>
<item android:state_enabled="false">
<shape android:shape="rectangle">
<corners android:radius="3dp"/>
<solid android:color="@color/colorBlueAlpha"/>
<stroke android:width="0dp" android:color="@color/colorBlueAlpha"/>
</shape>
</item>
</selector>

对于那些使用ConstraintLayout的人,android:windowSoftInputMode="adjustPan|adjustResize"将不起作用。

你能做的是使用软键盘监听器,从上层视图的从底到底设置视图的约束,然后为每个视图设置垂直偏差(作为约束之间的位置百分比)到水平指导方针(也是按百分比定位,但指向父)。

对于每个视图,我们只需要在键盘显示的是时将app:layout_constraintBottom_toBottomOf更改为@+id/guideline,当然这是通过编程实现的。

        <ImageView
android:id="@+id/loginLogo"
...
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.15" />




<RelativeLayout
android:id="@+id/loginFields"
...
app:layout_constraintVertical_bias=".15"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toBottomOf="@+id/loginLogo">


<Button
android:id="@+id/login_btn"
...
app:layout_constraintVertical_bias=".25"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toBottomOf="@+id/loginFields"/>

一般来说,软键盘占屏幕高度的比例不超过50%。因此,您可以将指导原则设置为0.5。

        <android.support.constraint.Guideline
android:id="@+id/guideline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.5"/>

现在,通过编程,当键盘为没有显示时,我们可以将所有app:layout_constraintBottom_toBottomOf设置回父类型,反之亦然。

            unregistrar = KeyboardVisibilityEvent.registerEventListener(this, isOpen -> {
loginLayout.startAnimation(AnimationManager.getFade(200));
if (isOpen) {
setSoftKeyViewParams(loginLogo, R.id.guideline, ConstraintLayout.LayoutParams.PARENT_ID, -1, "235:64", 0.15f,
63, 0, 63, 0);
setSoftKeyViewParams(loginFields, R.id.guideline, -1, R.id.loginLogo, null, 0.15f,
32, 0, 32, 0);
setSoftKeyViewParams(loginBtn, R.id.guideline, -1, R.id.useFingerPrintIdText, null, 0.5f,
32, 0, 32, 0);
} else {
setSoftKeyViewParams(loginLogo, ConstraintLayout.LayoutParams.PARENT_ID, ConstraintLayout.LayoutParams.PARENT_ID, -1, "235:64", 0.15f,
63, 0, 63, 0);
setSoftKeyViewParams(loginFields, ConstraintLayout.LayoutParams.PARENT_ID, -1, R.id.loginLogo,null, 0.15f,
32, 0, 32, 0);
setSoftKeyViewParams(loginBtn, ConstraintLayout.LayoutParams.PARENT_ID, -1, R.id.useFingerPrintIdText,null, 0.25f,
32, 0, 32, 0);
}
});

调用这个方法:

    private void setSoftKeyViewParams(View view, int bottomToBottom, int topToTop, int topToBottom, String ratio, float verticalBias,
int left, int top, int right, int bottom) {
ConstraintLayout.LayoutParams viewParams = new ConstraintLayout.LayoutParams(view.getLayoutParams().width, view.getLayoutParams().height);
viewParams.dimensionRatio = ratio;
viewParams.bottomToBottom = bottomToBottom;
viewParams.topToTop = topToTop;
viewParams.topToBottom = topToBottom;
viewParams.endToEnd = ConstraintLayout.LayoutParams.PARENT_ID;
viewParams.startToStart = ConstraintLayout.LayoutParams.PARENT_ID;
viewParams.verticalBias = verticalBias;
viewParams.setMargins(Dimensions.dpToPx(left), Dimensions.dpToPx(top), Dimensions.dpToPx(right), Dimensions.dpToPx(bottom));
view.setLayoutParams(viewParams);
}

重要的是要确保在显示键盘和不显示键盘时正确地设置垂直偏置。

将这一行添加到清单文件中:

android:windowSoftInputMode="adjustResize"

在Xamarin注册以下代码在您的活动

 WindowSoftInputMode = Android.Views.SoftInput.AdjustResize | Android.Views.SoftInput.AdjustPan

我使用相对布局,如果你使用约束布局,上面的代码将工作在下面的代码

芬兰湾的科特林ConstraintLayout中,只需添加:

android:windowSoftInputMode="stateHidden|adjustResize"

android:windowSoftInputMode="stateVisible|adjustResize"

您可以从manifest中设置活动启动后需要的状态。

在你的AndroidManifest.xml中,像这样:

      <activity
android:name=".ActivityName"
android:windowSoftInputMode="stateHidden|adjustResize"
/>

在kotlin很简单

在你的片段中

requireActivity().window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE or WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN)

在你的布局中:

android:fitsSystemWindows="true"