Je voudrais ajuster/redimensionner la mise en page lorsque le clavier logiciel est activé, comme ci-dessous:
Avant et après:
Ressources de couple trouvées dans SO:
Mais les questions et réponses sont plutôt ambiguës, voici la question avec une image plus claire de ce que je veux.
Exigences:
Il suffit d'ajouter
Android:windowSoftInputMode="adjustResize"
dans votre fichier AndroidManifest.xml où vous déclarez cette activité particulière et cela ajustera l'option de redimensionnement de la présentation.
du code source ci-dessous pour le schéma de configuration
<?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>
Cette question a été posée il y a quelques années et "Secret Andro Geni" a une bonne explication de base et "tir38" a également fait une bonne tentative pour la solution complète, mais hélas il n'y a pas de solution complète publiée ici . Passez quelques heures à comprendre et voici ma solution complète avec une explication détaillée en bas:
<?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>
Et dans AndroidManifest.xml , n'oubliez pas de définir:
Android:windowSoftInputMode="adjustResize"
sur la balise <activity>
que vous voulez une telle disposition.
Pensées:
J'ai réalisé que RelativeLayout
sont les dispositions qui couvrent tout l'espace disponible et qui sont ensuite redimensionnées lorsque le clavier apparaît.
Et LinearLayout
sont des dispositions qui ne sont pas redimensionnées lors du processus de redimensionnement.
C'est pourquoi vous devez avoir 1 RelativeLayout
immédiatement après ScrollView
pour couvrir tout l'espace disponible à l'écran. Et vous devez avoir une LinearLayout
dans une RelativeLayout
sinon votre intérieur serait écrasé lorsque le redimensionnement aura lieu. Le bon exemple est "headerLayout". S'il n'y avait pas de LinearLayout
dans ce RelativeLayout
"Facebook" le texte serait écrasé et ne serait pas affiché.
Dans les images de connexion "facebook" postées dans la question, j'ai également remarqué que toute la partie connexion (mainLayout) est centrée verticalement par rapport à tout l'écran, d'où l'attribut:
Android:layout_centerVertical="true"
sur la disposition LinearLayout
. Et comme mainLayout est dans une LinearLayout
, cela signifie que cette partie ne sera pas redimensionnée (voir à nouveau la photo en question).
Ajoutez cette ligne dans votre manifeste où votre activité est appelée
Android:windowSoftInputMode="adjustPan|adjustResize"
ou
vous pouvez ajouter cette ligne dans votre onCreate
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE|WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
Le développeur Android a la bonne réponse, mais le code source fourni est assez détaillé et n'implémente pas le modèle décrit dans le diagramme.
Voici un meilleur modèle:
<?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>
C’est à vous de choisir les vues que vous utiliserez pour les parties "défilement" et "pied de page". Sachez également que vous devez probablement définir ScrollView
s fillViewPort .
Il peut fonctionner pour tout type de mise en page.
Android: windowSoftInputMode = "ajuster-redimensionner"
par exemple:
<activity Android:name=".ActivityLogin"
Android:screenOrientation="portrait"
Android:theme="@style/AppThemeTransparent"
Android:windowSoftInputMode="adjustResize"/>
Android: fitsSystemWindows = "true"
et
Android: layout_alignParentBottom = "true"
par exemple:
<RelativeLayout
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:layout_alignParentBottom="true"
Android:fitsSystemWindows="true">
Cela permet d'afficher n'importe quelle mise en page précédemment masquée par le clavier.
Ajoutez ceci à la balise d'activité dans AndroidManifest.xml
Android: windowSoftInputMode = "ajuster-redimensionner"
Entourez votre vue racine avec une ScrollView, de préférence avec des barres de défilement = aucune. ScrollView ne changera rien à votre mise en page, à moins qu’il ne soit utilisé pour résoudre ce problème.
Ensuite, définissez fitsSystemWindows = "true" sur la vue que vous voulez rendre complètement affichée au-dessus du clavier . Cela rendra votre texte d'édition visible au-dessus du clavier et permettra de faire défiler les parties situées en dessous du texte d'édition, mais en dessous. la vue avec fitsSystemWindows = "true".
Android: fitsSystemWindows = "true"
Par exemple:
<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>
Si vous souhaitez afficher la totalité de la vue de fitsSystemWindows = "true" au-dessus du clavier au moment où le clavier apparaît, vous aurez besoin d'un code pour faire défiler la vue vers le bas:
// 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)
}
Exemple de mise en page complète:
<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>
Beaucoup de réponses sont justes. Dans AndroidManifest
j'ai écrit:
<activity
Android:name=".SomeActivity"
Android:configChanges="orientation|keyboardHidden|screenSize" // Optional, doesn't affect.
Android:theme="@style/AppTheme.NoActionBar"
Android:windowSoftInputMode="adjustResize" />
Dans mon cas, j'ai ajouté un thème dans styles.xml
, mais vous pouvez utiliser le vôtre:
<style name="AppTheme.NoActionBar" parent="AppTheme">
<!-- Hide ActionBar -->
<item name="windowNoTitle">true</item>
<item name="windowActionBar">false</item>
</style>
J'ai remarqué que si j'utilise le thème plein écran, le redimensionnement ne se produit pas:
<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>
Dans mon cas également, adjustResize
fonctionne, mais adjustPan
ne fonctionne pas.
Pour dispositions en plein écran voir une solution de contournement dans Android Comment ajuster la disposition en mode plein écran lorsque le clavier est visible ou dans https://Gist.github.com/grennis/2e3cd5f7a9238c59861015ce0a7c5584 .
Aussi https://medium.com/@sandeeptengale/problem-solved-3-Android-full-screen-view-translucent-scrollview-adjustresize-keyboard-b0547c7ced32 fonctionne, mais StatusBar est transparent, donc batterie, horloge, les icônes Wi-Fi sont visibles.
Si vous créez une activité avec Fichier> Nouveau> Activité> Activité en plein écran, où le code est utilisé:
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
vous n'obtiendrez pas non plus de résultat. Vous pouvez utiliser Android:fitsSystemWindows="true"
dans un conteneur racine, mais StatusBar apparaît. Utilisez donc des solutions de contournement du premier lien.
Dans mon cas, cela a aidé.
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>
Utilisez ceci dans le fichier manifest
<activity Android:name=".MainActivity"
Android:screenOrientation="portrait"
Android:windowSoftInputMode="adjustResize"/>
Maintenant, la partie la plus importante! Utilisez un thème comme celui-ci dans les balises Activity
ou Application
.
Android:theme="@style/AppTheme"
Et le thème a pris comme ça
<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>
Il me manquait donc le thème. Ce qui m'a fait frustré toute la journée.
Vous pouvez simplement définir ces options dans le fichier AndroidManifest.xml.
<activity
Android:name=".YourACtivityName"
Android:windowSoftInputMode="stateVisible|adjustResize">
L'utilisation de adjustPan
n'est pas recommandée par Google, car il se peut que l'utilisateur doive fermer le clavier pour voir tous les champs de saisie.
Plus d'infos: Android App Manifest
Pour moi, cela a fonctionné avec cette ligne de code:
getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
Il suffit de le mettre dans la méthode onCreate . Le meilleur!
Pour ceux qui utilisent ConstraintLayout , Android:windowSoftInputMode="adjustPan|adjustResize"
ne fonctionnera pas.
Ce que vous pouvez faire est d'utiliser un écouteur au clavier , définir les contraintes des vues de de bas en bas des vues supérieures, définissez ensuite un biais vertical pour chaque vue (sous forme de pourcentage de position entre contraintes) sur une ligne directrice horizontale (également positionnée par pourcentage, mais par rapport au parent).
Pour chaque vue, il suffit de changer app:layout_constraintBottom_toBottomOf
en @+id/guideline
lorsque le clavier est affiché , par programme bien sûr.
<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"/>
Généralement, un clavier logiciel ne prend pas plus de 50% de la hauteur de l'écran. Ainsi, vous pouvez définir la recommandation à 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"/>
Maintenant par programmation, lorsque le clavier est non affiché , nous pouvons remettre tous les app:layout_constraintBottom_toBottomOf
au parent, et vice-versa.
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);
}
});
Appelez cette méthode:
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);
}
L'important est de définir le biais vertical de manière à ce que la mise à l'échelle s'effectue correctement lorsque le clavier est affiché et non illustré.
Ce code fonctionne pour moi. Lorsque le clavier apparaît, vous pouvez faire défiler l'écran
Dans 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>
Ajouter cette ligne dans le fichier manifeste:
Android:windowSoftInputMode="adjustResize"
J'utilise ce cadre de classe étendu Et lorsque j'ai besoin de recalculer la taille de la taille onLayout, je remplace onmeasure .__ et soustrais keyboardHeight à l'aide de getKeyboardHeight ().
Mon cadre de création qui a besoin d'être redimensionné avec le clavier logiciel
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();
}
}