How to adjust layout when soft keyboard appears
我想在软键盘激活时调整/重新调整布局大小,如下所示:
之前和之后:
在SO中找到了几个资源:
但问题& 答案是相当模糊的,这里的问题是我想要的更清晰的画面。
要求:
- 它应该适用于任何屏幕尺寸的手机。
-
注意到"FACEBOOK"和"注册"中的边距/填充空间
Facebook"前后发生了变化。 - 不涉及滚动视图。
只需添加
1 | android:windowSoftInputMode="adjustResize" |
在AndroidManifest.xml中,您声明此特定活动,这将调整布局调整大小选项。
下面的一些源代码用于布局设计
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | <?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> |
几年前问了这个问题,"秘密Andro Geni"有一个很好的基础解释,"tir38"也对完整的解决方案做了很好的尝试,但是这里没有完整的解决方案。
我花了几个小时搞清楚事情,这是我的完整解决方案,底部有详细解释:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 | <?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中,不要忘记设置:
1 | android:windowSoftInputMode="adjustResize" |
在
思考:
我已经意识到
并且
这就是为什么你需要在
在问题中发布的"facebook"登录图片中我也注意到整个登录部分(mainLayout)相对于整个屏幕是垂直居中的,因此属性:
1 | android:layout_centerVertical="true" |
在
在您的Manifest中添加此行,您的Activity将被调用
1 | android:windowSoftInputMode="adjustPan|adjustResize" |
要么
你可以在
1 | getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE|WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE); |
Android Developer有正确的答案,但提供的源代码非常冗长,并没有实际实现图中描述的模式。
这是一个更好的模板:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | <?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> |
由您自己决定用于"滚动"和"页脚"部分的视图。也知道你可能需要设置
fillViewPort。
它可以适用于所有类型的布局。
android:windowSoftInputMode="adjustResize"
例如:
1 2 3 4 | <activity android:name=".ActivityLogin" android:screenOrientation="portrait" android:theme="@style/AppThemeTransparent" android:windowSoftInputMode="adjustResize"/> |
android:fitsSystemWindows="true"
和
android:layout_alignParentBottom="true"
例如:
1 2 3 4 5 | <RelativeLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:fitsSystemWindows="true"> |
这使得可以显示先前由键盘隐藏的任何所需布局。
将其添加到AndroidManifest.xml中的activity标记中
android:windowSoftInputMode="adjustResize"
使用ScrollView环绕根视图,最好使用scrollbars = none。除了用于解决此问题之外,ScrollView将不会使用您的布局更改任何内容。
然后在要在键盘上方完全显示的视图上设置fitsSystemWindows ="true"。
这将使您的EditText在键盘上方可见,并且可以向下滚动到EditText下方的部分,但在视图中使用fitsSystemWindows ="true"。
android:fitsSystemWindows="true"
例如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | <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"视图的完整部分,则需要一些代码将视图滚动到底部:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | // 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) } |
完整布局示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 | <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> |
很多答案都是对的。在
1 2 3 4 5 | <activity android:name=".SomeActivity" android:configChanges="orientation|keyboardHidden|screenSize" // Optional, doesn't affect. android:theme="@style/AppTheme.NoActionBar" android:windowSoftInputMode="adjustResize" /> |
在我的情况下,我在
1 2 3 4 5 | <style name="AppTheme.NoActionBar" parent="AppTheme"> <!-- Hide ActionBar --> <item name="windowNoTitle">true</item> <item name="windowActionBar">false</item> </style> |
我注意到,如果我使用全屏主题,则不会调整大小:
1 2 3 4 5 6 7 | <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> |
同样在我的情况下
有关全屏布局,请参阅Android中的解决方法当软键盘可见时,或者在https://gist.github.com/grennis/2e3cd5f7a9238c59861015ce0a7c5584中,如何在全屏模式下调整布局。
另外https://medium.com/@sandeeptengale/problem-solved-3-android-full-screen-view-translucent-scrollview-adjustresize-keyboard-b0547c7ced32有效,但它的StatusBar是透明的,所以电池,时钟,Wi- Fi图标可见。
如果使用"文件">"新建">"活动">"全屏活动"创建活动,则使用代码:
1 2 3 4 5 6 7 | 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 |
你也不会取得成果。您可以在根容器中使用
您只需在AndroidManifest.xml文件中设置这些选项即可。
1 2 3 | <activity android:name=".YourACtivityName" android:windowSoftInputMode="stateVisible|adjustResize"> |
Google不建议使用
更多信息:Android App Manifest
在我看来,它有所帮助。
main_layout.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | <?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> |
在
1 2 3 | <activity android:name=".MainActivity" android:screenOrientation="portrait" android:windowSoftInputMode="adjustResize"/> |
现在最重要的部分!
在
1 | android:theme="@style/AppTheme" |
主题就是这样的
1 2 3 4 5 6 7 8 9 | <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> |
所以我错过了这个主题。这让我整天感到沮丧。
对于使用ConstraintLayout的用户,
您可以做的是使用软键盘监听器,从上部视图的底部到底部设置视图的约束,然后为每个视图(作为约束之间的位置百分比)设置垂直偏差到水平指南(也按百分比定位) ,但对于父母)。
对于每个视图,我们只需要在显示键盘时将
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | <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。
1 2 3 4 5 6 | <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"/> |
现在以编程方式,当键盘未显示时,我们可以将所有
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | 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); } }); |
调用此方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 | 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); } |
重要的是确保在键盘显示和未显示时能够正确缩放的方式设置垂直偏置。
我使用这个扩展类框架
当我需要重新计算高度大小onLayout时,我会覆盖onmeasure
并使用getKeyboardHeight()减去keyboardHeight
我的创建框架需要使用软键盘调整大小
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | 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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 | 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(); } } |
对我来说,它适用于这行代码:
1 | getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN); |
只需将其放入onCreate方法即可。
最好!
将此行添加到Manifiest文件中:
1 | android:windowSoftInputMode="adjustResize" |
这段代码适合我。键盘出现时,您可以滚动屏幕
在AndroidManifest.xml中
1 2 3 4 | <activity android:name=".signup.screen_2.SignUpNameAndPasswordActivity" android:screenOrientation="portrait" android:windowSoftInputMode="adjustResize"> </activity> |
activity_sign_up.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 | <?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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | <?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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | <?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> |