web-dev-qa-db-fra.com

Comment ajuster la disposition lorsque le clavier virtuel apparaît

Je voudrais ajuster/redimensionner la mise en page lorsque le clavier logiciel est activé, comme ci-dessous:

Avant et après:

enter image description hereenter image description here


Ressources de couple trouvées dans SO: 

  1. Comment garder tous les champs et textes visibles lorsque le clavier virtuel est affiché
  2. Le clavier logiciel Android gâche la mise en page quand apparaît
  3. Ajuste la disposition lorsque le clavier virtuel est activé

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 devrait fonctionner sur le téléphone avec toutes les tailles d'écran.
  • Remarquez que l'espace de marge/remplissage dans "FACEBOOK" et "Inscrivez-vous pour Facebook" a changé avant et après. 
  • Aucune vue de défilement n'est impliquée.
128
Roy Lee

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.

enter image description here

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>
164
Venkatesh S

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).

29
Yani2000

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);
17
Ashish Jaiswal

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 ScrollViews fillViewPort .

11
tir38

Il peut fonctionner pour tout type de mise en page.

  1. ajoutez ceci à votre balise d'activité dans AndroidManifest.xml

Android: windowSoftInputMode = "ajuster-redimensionner"

par exemple:

<activity Android:name=".ActivityLogin"
    Android:screenOrientation="portrait"
    Android:theme="@style/AppThemeTransparent"
    Android:windowSoftInputMode="adjustResize"/>
  1. ajoutez ceci à votre balise de mise en page dans activitypage.xml qui changera sa position.

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">
7
user3725137

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>

4
Morten Holmgaard

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.

3
CoolMind

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.

2

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

2
vovahost

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!

1
Peter94

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é.

1
NocTurn

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>
0
Anh Duy

Ajouter cette ligne dans le fichier manifeste:

Android:windowSoftInputMode="adjustResize"
0

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();
    }
}
0
Arthur Melo