web-dev-qa-db-fra.com

Android Comment ajuster la disposition en mode plein écran lorsqu'un clavier virtuel est visible

J'ai beaucoup cherché à ajuster la disposition lorsque le clavier logiciel est actif et je l'ai mis en œuvre avec succès, mais le problème survient lorsque j'utilise Android:theme="@Android:style/Theme.NoTitleBar.Fullscreen" ceci dans ma balise d'activité dans le fichier manifeste.

Pour cela, j'ai utilisé Android:windowSoftInputMode="adjustPan|adjustResize|stateHidden" avec différentes options mais pas de chance.

Après cela, j’ai implémenté FullScreen par programme et essayé diverses dispositions pour travailler avec FullScreen mais en vain.

J'ai référencé ces liens et j'ai consulté de nombreux articles sur ce sujet:

http://Android-developers.blogspot.com/2009/04/updating-applications-for-on-screen.html

http://davidwparker.com/2011/08/30/Android-how-to-float-a-row-above-keyboard/

Voici le code XML:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout Android:id="@+id/masterContainerView"
    Android:layout_width="fill_parent" Android:layout_height="fill_parent"
    Android:orientation="vertical" xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:background="#ffffff">

    <ScrollView Android:id="@+id/parentScrollView"
        Android:layout_width="fill_parent" Android:layout_height="wrap_content">

        <LinearLayout Android:layout_width="fill_parent"
            Android:layout_height="fill_parent" Android:orientation="vertical">

            <TextView Android:id="@+id/setup_txt" Android:layout_width="wrap_content"
                Android:layout_height="wrap_content" Android:text="Setup - Step 1 of 3"
                Android:textColor="@color/top_header_txt_color" Android:textSize="20dp"
                Android:padding="8dp" Android:gravity="center_horizontal" />

            <TextView Android:id="@+id/txt_header" Android:layout_width="fill_parent"
                Android:layout_height="40dp" Android:text="AutoReply:"
                Android:textColor="@color/top_header_txt_color" Android:textSize="14dp"
                Android:textStyle="bold" Android:padding="10dp"
                Android:layout_below="@+id/setup_txt" />

            <EditText Android:id="@+id/edit_message"
                Android:layout_width="fill_parent" Android:layout_height="wrap_content"
                Android:text="Some text here." Android:textSize="16dp"
                Android:textColor="@color/setting_editmsg_color" Android:padding="10dp"
                Android:minLines="5" Android:maxLines="6" Android:layout_below="@+id/txt_header"
                Android:gravity="top" Android:scrollbars="vertical"
                Android:maxLength="132" />

            <ImageView Android:id="@+id/image_bottom"
                Android:layout_width="fill_parent" Android:layout_height="wrap_content"
                Android:layout_below="@+id/edit_message" />

        </LinearLayout>
    </ScrollView>

    <RelativeLayout Android:id="@+id/scoringContainerView"
        Android:layout_width="fill_parent" Android:layout_height="50px"
        Android:orientation="vertical" Android:layout_alignParentBottom="true"
        Android:background="#535254">

        <Button Android:id="@+id/btn_save" Android:layout_width="wrap_content"
            Android:layout_height="wrap_content" Android:layout_alignParentRight="true"
            Android:layout_marginTop="7dp" Android:layout_marginRight="15dp"
            Android:layout_below="@+id/edit_message"
            Android:text = "Save" />

        <Button Android:id="@+id/btn_cancel" Android:layout_width="wrap_content"
            Android:layout_height="wrap_content" Android:layout_marginTop="7dp"
            Android:layout_marginRight="10dp" Android:layout_below="@+id/edit_message"
            Android:layout_toLeftOf="@+id/btn_save" Android:text = "Cancel" />

    </RelativeLayout>
</RelativeLayout>

enter image description here

Je veux que les 2 boutons du bas soient orientés vers le haut lorsque le clavier logiciel apparaît en image.

enter image description here

167
Vineet Shukla
71
nmr

Sur la base de la solution de contournement de yghm, j'ai codé une classe de commodité qui me permet de résoudre le problème avec une ligne (après l'ajout de la nouvelle classe à mon code source bien sûr). Le one-liner est:

     AndroidBug5497Workaround.assistActivity(this);

Et la classe d'implémentation est:


public class AndroidBug5497Workaround {

    // For more information, see https://issuetracker.google.com/issues/36911528
    // To use this class, simply invoke assistActivity() on an Activity that already has its content view set.

    public static void assistActivity (Activity activity) {
        new AndroidBug5497Workaround(activity);
    }

    private View mChildOfContent;
    private int usableHeightPrevious;
    private FrameLayout.LayoutParams frameLayoutParams;

    private AndroidBug5497Workaround(Activity activity) {
        FrameLayout content = (FrameLayout) activity.findViewById(Android.R.id.content);
        mChildOfContent = content.getChildAt(0);
        mChildOfContent.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            public void onGlobalLayout() {
                possiblyResizeChildOfContent();
            }
        });
        frameLayoutParams = (FrameLayout.LayoutParams) mChildOfContent.getLayoutParams();
    }

    private void possiblyResizeChildOfContent() {
        int usableHeightNow = computeUsableHeight();
        if (usableHeightNow != usableHeightPrevious) {
            int usableHeightSansKeyboard = mChildOfContent.getRootView().getHeight();
            int heightDifference = usableHeightSansKeyboard - usableHeightNow;
            if (heightDifference > (usableHeightSansKeyboard/4)) {
                // keyboard probably just became visible
                frameLayoutParams.height = usableHeightSansKeyboard - heightDifference;
            } else {
                // keyboard probably just became hidden
                frameLayoutParams.height = usableHeightSansKeyboard;
            }
            mChildOfContent.requestLayout();
            usableHeightPrevious = usableHeightNow;
        }
    }

    private int computeUsableHeight() {
        Rect r = new Rect();
        mChildOfContent.getWindowVisibleDisplayFrame(r);
        return (r.bottom - r.top);
    }
}

J'espère que ça aide quelqu'un.

247
Joseph Johnson

Puisque la réponse a déjà été choisie et que le problème est connu pour être un bogue, j'ai pensé ajouter un "travail possible".

Vous pouvez basculer en mode plein écran lorsque le clavier virtuel est affiché. Cela permet au "adjustPan" de fonctionner correctement.

En d'autres termes, j'utilise toujours @ Android: style/Theme.Black.NoTitleBar.Fullscreen en tant que une partie du thème de l'application et stateVisible | adjustResize dans le cadre du mode de saisie logicielle de la fenêtre d'activité, mais faites-les fonctionner ensemble. Je dois basculer en mode plein écran avant que le clavier n'apparaisse.

Utilisez le code suivant:

Désactiver le mode plein écran

getWindow().addFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);

Activer le mode plein écran

getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);

Note - l'inspiration est venue de: Masquage du titre en mode plein écran

34
LEO

J'ai essayé le solution de Joseph Johnson , mais comme d'autres, j'ai rencontré le problème de l'intervalle entre le contenu et le clavier. Le problème se produit car le mode de saisie logicielle est toujours pan lors de l'utilisation du mode plein écran. Ce panoramique interfère avec la solution de Joseph lorsque vous activez un champ de saisie qui serait masqué par la saisie logicielle.

Lorsque l'entrée logicielle apparaît, le contenu est d'abord balayé en fonction de sa hauteur d'origine, puis redimensionné par la mise en page demandée par la solution de Joseph. Le redimensionnement et la mise en page ultérieure n'annulent pas le panoramique, ce qui crée un espace. L'ordre complet des événements est:

  1. Listener de mise en page globale
  2. Panoramique
  3. Mise en page du contenu (= redimensionnement effectif du contenu)

Il n'est pas possible de désactiver le panoramique, mais il est possible de forcer le décalage du panoramique à 0 en modifiant la hauteur du contenu. Cela peut être fait dans le programme d'écoute, car il est exécuté avant le panoramique. Le réglage de la hauteur du contenu sur la hauteur disponible permet une expérience utilisateur fluide, c’est-à-dire qu’elle ne scintille pas.

J'ai aussi fait ces changements. Si l'un de ces problèmes présente des problèmes, faites le moi savoir:

  • Détermination commutée de la hauteur disponible à utiliser getWindowVisibleDisplayFrame. Le Rect est mis en cache pour éviter un peu de déchets inutiles.
  • Autoriser l'écouteur à être supprimé aussi. Cela est utile lorsque vous réutilisez une activité pour différents fragments ayant différentes exigences en plein écran.
  • Ne faites pas de distinction entre le clavier affiché ou masqué, mais réglez toujours la hauteur du contenu sur la hauteur du cadre d'affichage visible.

Il a été testé sur un Nexus 5 et sur des émulateurs fonctionnant sous les niveaux d'API 16-24 avec des tailles d'écran allant de très petites à grandes.

Le code a été porté sur Kotlin, mais le portage de mes modifications sur Java est simple. Dis-moi si tu as besoin d'aide:

class AndroidBug5497Workaround constructor(activity: Activity) {
    private val contentContainer = activity.findViewById(Android.R.id.content) as ViewGroup
    private val rootView = contentContainer.getChildAt(0)
    private val rootViewLayout = rootView.layoutParams as FrameLayout.LayoutParams
    private val viewTreeObserver = rootView.viewTreeObserver
    private val listener = ViewTreeObserver.OnGlobalLayoutListener { possiblyResizeChildOfContent() }

    private val contentAreaOfWindowBounds = Rect()
    private var usableHeightPrevious = 0

    // I call this in "onResume()" of my fragment
    fun addListener() {
        viewTreeObserver.addOnGlobalLayoutListener(listener)
    }

    // I call this in "onPause()" of my fragment
    fun removeListener() {
        viewTreeObserver.removeOnGlobalLayoutListener(listener)
    }

    private fun possiblyResizeChildOfContent() {
        contentContainer.getWindowVisibleDisplayFrame(contentAreaOfWindowBounds)
        val usableHeightNow = contentAreaOfWindowBounds.height()
        if (usableHeightNow != usableHeightPrevious) {
            rootViewLayout.height = usableHeightNow
            // Change the bounds of the root view to prevent gap between keyboard and content, and top of content positioned above top screen Edge.
            rootView.layout(contentAreaOfWindowBounds.left, contentAreaOfWindowBounds.top, contentAreaOfWindowBounds.right, contentAreaOfWindowBounds.bottom)
            rootView.requestLayout()

            usableHeightPrevious = usableHeightNow
        }
    }
}
20
Johan Stuyts

Je viens de trouver une solution simple et fiable si vous utilisez l'approche d'interface utilisateur du système ( https://developer.Android.com/training/system-ui/immersive.html ).

Cela fonctionne dans le cas où vous utilisez View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN, par exemple. si vous utilisez CoordinatorLayout.

Cela ne fonctionnera pas pour WindowManager.LayoutParams.FLAG_FULLSCREEN (celui que vous pouvez également définir dans le thème avec Android:windowFullscreen), mais vous pouvez obtenir un effet similaire avec SYSTEM_UI_FLAG_LAYOUT_STABLE (qui "a le même effet visuel" - selon la documentation ) et cette solution devrait fonctionner à nouveau.

getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN
                    | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION /* If you want to hide navigation */
                    | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE)

Je l'ai testé sur mon appareil sous Marshmallow.

La clé est que les claviers logiciels font également partie des fenêtres système (telles que la barre d'état et la barre de navigation), de sorte que la WindowInsets envoyée par le système contient des informations précises et fiables à ce sujet.

Pour le cas d'utilisation tel que dans DrawerLayout où nous essayons de dessiner derrière la barre d'état, nous pouvons créer une mise en page qui ignore uniquement l'encart supérieur et applique l'encadré inférieur qui représente le clavier logiciel.

Voici ma coutume FrameLayout:

/**
 * Implements an effect similar to {@code Android:fitsSystemWindows="true"} on Lollipop or higher,
 * except ignoring the top system window inset. {@code Android:fitsSystemWindows="true"} does not
 * and should not be set on this layout.
 */
public class FitsSystemWindowsExceptTopFrameLayout extends FrameLayout {

    public FitsSystemWindowsExceptTopFrameLayout(Context context) {
        super(context);
    }

    public FitsSystemWindowsExceptTopFrameLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public FitsSystemWindowsExceptTopFrameLayout(Context context, AttributeSet attrs,
                                                 int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @RequiresApi(Build.VERSION_CODES.Lollipop)
    public FitsSystemWindowsExceptTopFrameLayout(Context context, AttributeSet attrs,
                                                 int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }

    @Override
    public WindowInsets onApplyWindowInsets(WindowInsets insets) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Lollipop) {
            setPadding(insets.getSystemWindowInsetLeft(), 0, insets.getSystemWindowInsetRight(),
                    insets.getSystemWindowInsetBottom());
            return insets.replaceSystemWindowInsets(0, insets.getSystemWindowInsetTop(), 0, 0);
        } else {
            return super.onApplyWindowInsets(insets);
        }
    }
}

Et pour l'utiliser:

<com.example.yourapplication.FitsSystemWindowsExceptTopFrameLayout
    xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent">

    <!-- Your original layout here -->
</com.example.yourapplication.FitsSystemWindowsExceptTopFrameLayout>

Cela devrait théoriquement fonctionner pour tout appareil sans modification insensée, bien mieux que tout piratage qui essaie de prendre un 1/3 ou 1/4 aléatoire de la taille de l'écran comme référence.

(Cela nécessite l'API 16+, mais j'utilise le mode plein écran uniquement sur Lollipop + pour dessiner derrière la barre d'état, c'est donc la meilleure solution dans ce cas.)

10
Hai Zhang

J'ai dû faire face à ce problème aussi et j'ai eu un travail autour duquel j'ai vérifié sur HTC One, Galaxy S1, S2, S3, note et HTC Sensation.

mettre un écouteur de mise en page globale sur la vue racine de votre mise en page

mRootView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener(){
            public void onGlobalLayout() {
                checkHeightDifference();
            }
    });

et là j'ai vérifié la différence de hauteur et si la différence de hauteur de l'écran est supérieure à un tiers de la hauteur de l'écran, nous pouvons supposer que le clavier est ouvert. l'a pris de cette réponse .

private void checkHeightDifference(){
    // get screen frame rectangle 
    Rect r = new Rect();
    mRootView.getWindowVisibleDisplayFrame(r);
    // get screen height
    int screenHeight = mRootView.getRootView().getHeight();
    // calculate the height difference
    int heightDifference = screenHeight - (r.bottom - r.top);

    // if height difference is different then the last height difference and
    // is bigger then a third of the screen we can assume the keyboard is open
    if (heightDifference > screenHeight/3 && heightDifference != mLastHeightDifferece) {
        // keyboard visiblevisible
        // get root view layout params
        FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) mRootView.getLayoutParams();
        // set the root view height to screen height minus the height difference
        lp.height = screenHeight - heightDifference;
        // call request layout so the changes will take affect
        .requestLayout();
        // save the height difference so we will run this code only when a change occurs.
        mLastHeightDifferece = heightDifference;
    } else if (heightDifference != mLastHeightDifferece) {
        // keyboard hidden
        PFLog.d("[ChatroomActivity] checkHeightDifference keyboard hidden");
        // get root view layout params and reset all the changes we have made when the keyboard opened.
        FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) mRootView.getLayoutParams();
        lp.height = screenHeight;
        // call request layout so the changes will take affect
        mRootView.requestLayout();
        // save the height difference so we will run this code only when a change occurs.
        mLastHeightDifferece = heightDifference;
    }
}

ce n'est probablement pas à l'épreuve des balles et peut-être que sur certains appareils cela ne fonctionnera pas, mais cela a fonctionné pour moi et j'espère que cela vous aidera aussi.

9
yghm

Veuillez noter que Android:windowSoftInputMode="adjustResize" ne fonctionne pas lorsque WindowManager.LayoutParams.FLAG_FULLSCREEN est défini pour une activité. Vous avez deux options.

  1. Désactivez le mode plein écran pour votre activité. L'activité n'est pas redimensionnée en mode plein écran. Vous pouvez le faire soit en XML (en modifiant le thème de l'activité), soit en code Java. Ajoutez les lignes suivantes dans votre méthode onCreate ().

    getWindow().addFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);   
    getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);`
    

OU

  1. Utilisez un autre moyen pour atteindre le mode plein écran. Ajoutez le code suivant dans votre méthode onCreate ().

    getWindow().addFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
    getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
    getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
    View decorView = getWindow().getDecorView();
    // Hide the status bar.
    int uiOptions = View.SYSTEM_UI_FLAG_FULLSCREEN;
    decorView.setSystemUiVisibility(uiOptions);`
    

Veuillez noter que la méthode 2 ne fonctionne que dans Android 4.1 et versions ultérieures.

7
Abhinav Chauhan

J'ai implémenté la solution Joseph Johnson et cela a bien fonctionné. J'ai remarqué qu'après l'utilisation de cette solution, le tiroir de l'application ne se fermait parfois pas correctement. J'ai ajouté une fonctionnalité pour supprimer l'écouteur removeOnGlobalLayoutListener lorsque l'utilisateur ferme le fragment où se trouvent les edittexts.

    //when the application uses full screen theme and the keyboard is shown the content not scrollable! 
//with this util it will be scrollable once again
//http://stackoverflow.com/questions/7417123/Android-how-to-adjust-layout-in-full-screen-mode-when-softkeyboard-is-visible
public class AndroidBug5497Workaround {


    private static AndroidBug5497Workaround mInstance = null;
    private View mChildOfContent;
    private int usableHeightPrevious;
    private FrameLayout.LayoutParams frameLayoutParams;
    private ViewTreeObserver.OnGlobalLayoutListener _globalListener;

    // For more information, see https://code.google.com/p/Android/issues/detail?id=5497
    // To use this class, simply invoke assistActivity() on an Activity that already has its content view set.

    public static AndroidBug5497Workaround getInstance (Activity activity) {
        if(mInstance==null)
        {
            synchronized (AndroidBug5497Workaround.class)
            {
                mInstance = new AndroidBug5497Workaround(activity);
            }
        }
        return mInstance;
    }

    private AndroidBug5497Workaround(Activity activity) {
        FrameLayout content = (FrameLayout) activity.findViewById(Android.R.id.content);
        mChildOfContent = content.getChildAt(0);
        frameLayoutParams = (FrameLayout.LayoutParams) mChildOfContent.getLayoutParams();

        _globalListener = new ViewTreeObserver.OnGlobalLayoutListener()
        {

            @Override
            public void onGlobalLayout()
            {
                 possiblyResizeChildOfContent();
            }
        };
    }

    public void setListener()
    {
         mChildOfContent.getViewTreeObserver().addOnGlobalLayoutListener(_globalListener);
    }

    public void removeListener()
    {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
            mChildOfContent.getViewTreeObserver().removeOnGlobalLayoutListener(_globalListener);
        } else {
            mChildOfContent.getViewTreeObserver().removeGlobalOnLayoutListener(_globalListener);
        }
    }

    private void possiblyResizeChildOfContent() {
        int usableHeightNow = computeUsableHeight();
        if (usableHeightNow != usableHeightPrevious) {
            int usableHeightSansKeyboard = mChildOfContent.getRootView().getHeight();
            int heightDifference = usableHeightSansKeyboard - usableHeightNow;
            if (heightDifference > (usableHeightSansKeyboard/4)) {
                // keyboard probably just became visible
                frameLayoutParams.height = usableHeightSansKeyboard - heightDifference;
            } else {
                // keyboard probably just became hidden
                frameLayoutParams.height = usableHeightSansKeyboard;
            }
            mChildOfContent.requestLayout();
            usableHeightPrevious = usableHeightNow;
        }
    }

    private int computeUsableHeight() {
        Rect r = new Rect();
        mChildOfContent.getWindowVisibleDisplayFrame(r);
        return (r.bottom - r.top);
    } 
}

utilise la classe où se trouvent mes edittexts

@Override
public void onStart()
{
    super.onStart();
    AndroidBug5497Workaround.getInstance(getActivity()).setListener();
}

@Override
public void onStop()
{
    super.onStop();
    AndroidBug5497Workaround.getInstance(getActivity()).removeListener();
}
6
visionix visionix

Pour que cela fonctionne avec FullScreen:

Utilisez le plug-in de clavier ionic. Cela vous permet d’écouter lorsque le clavier apparaît et disparaît.

OnDeviceReady ajoute ces écouteurs d'événement:

// Allow Screen to Move Up when Keyboard is Present
window.addEventListener('native.keyboardshow', onKeyboardShow);
// Reset Screen after Keyboard hides
window.addEventListener('native.keyboardhide', onKeyboardHide);

La logique:

function onKeyboardShow(e) {
    // Get Focused Element
    var thisElement = $(':focus');
    // Get input size
    var i = thisElement.height();
    // Get Window Height
    var h = $(window).height()
    // Get Keyboard Height
    var kH = e.keyboardHeight
    // Get Focused Element Top Offset
    var eH = thisElement.offset().top;
    // Top of Input should still be visible (30 = Fixed Header)
    var vS = h - kH;
    i = i > vS ? (vS - 30) : i;
    // Get Difference
    var diff = (vS - eH - i);
    if (diff < 0) {
        var parent = $('.myOuter-xs.myOuter-md');
        // Add Padding
        var marginTop = parseInt(parent.css('marginTop')) + diff - 25;
        parent.css('marginTop', marginTop + 'px');
    }
}

function onKeyboardHide(e) {
  // Remove All Style Attributes from Parent Div
  $('.myOuter-xs.myOuter-md').removeAttr('style');
}

Fondamentalement, si la différence est inférieure à 0, il s’agit de la quantité de pixels que le clavier couvre de votre saisie. Donc, si vous ajustez votre div parent par ceci, cela devrait le contrecarrer.

L’ajout de délais à la logique, par exemple 300 ms, devrait également optimiser les performances (ce qui permettra au temps d’apparaître au clavier.

5
tyler_mitchell

Ajoutez Android:fitsSystemWindows="true" à la mise en page, qui sera redimensionnée.

5
zayn

J'ai essayé le cours de Joseph Johnson, et cela a fonctionné, mais ne répondait pas vraiment à mes besoins. Plutôt que d'émuler Android: windowSoftInputMode = "adjustResize", je devais émuler Android: windowSoftInputMode = "adjustPan".

J'utilise ceci pour une vue Web en plein écran. Pour déplacer la vue du contenu à la position correcte, je dois utiliser une interface javascript qui fournit des détails sur la position de l’élément de page qui a le focus et reçoit donc l’entrée au clavier. J'ai omis ces détails, mais j'ai réécrit la classe de Joseph Johnson. Cela vous fournira une base très solide pour implémenter un panoramique personnalisé par rapport à son redimensionnement.

package some.package.name;

import some.package.name.JavaScriptObject;

import Android.app.Activity;
import Android.graphics.Rect;
import Android.view.View;
import Android.view.ViewTreeObserver;
import Android.widget.FrameLayout;

//-------------------------------------------------------
// ActivityPanner Class
//
// Convenience class to handle Activity attributes bug.
// Use this class instead of windowSoftInputMode="adjustPan".
//
// To implement, call enable() and pass a reference
// to an Activity which already has its content view set.
// Example:
//      setContentView( R.layout.someview );
//      ActivityPanner.enable( this );
//-------------------------------------------------------
//
// Notes:
//
// The standard method for handling screen panning
// when the virtual keyboard appears is to set an activity
// attribute in the manifest.
// Example:
// <activity
//      ...
//      Android:windowSoftInputMode="adjustPan"
//      ... >
// Unfortunately, this is ignored when using the fullscreen attribute:
//      Android:theme="@Android:style/Theme.NoTitleBar.Fullscreen"
//
//-------------------------------------------------------
public class ActivityPanner {

    private View contentView_;
    private int priorVisibleHeight_;

    public static void enable( Activity activity ) {
        new ActivityPanner( activity );
    }

    private ActivityPanner( Activity activity ) {
        FrameLayout content = (FrameLayout)
            activity.findViewById( Android.R.id.content );
        contentView_ = content.getChildAt( 0 );
        contentView_.getViewTreeObserver().addOnGlobalLayoutListener(
            new ViewTreeObserver.OnGlobalLayoutListener() {
                public void onGlobalLayout() { panAsNeeded(); }
        });
    }

    private void panAsNeeded() {

        // Get current visible height
        int currentVisibleHeight = visibleHeight();

        // Determine if visible height changed
        if( currentVisibleHeight != priorVisibleHeight_ ) {

            // Determine if keyboard visiblity changed
            int screenHeight =
                contentView_.getRootView().getHeight();
            int coveredHeight =
                screenHeight - currentVisibleHeight;
            if( coveredHeight > (screenHeight/4) ) {
                // Keyboard probably just became visible

                // Get the current focus elements top & bottom
                // using a ratio to convert the values
                // to the native scale.
                float ratio = (float) screenHeight / viewPortHeight();
                int elTop = focusElementTop( ratio );
                int elBottom = focusElementBottom( ratio );

                // Determine the amount of the focus element covered
                // by the keyboard
                int elPixelsCovered = elBottom - currentVisibleHeight;

                // If any amount is covered
                if( elPixelsCovered > 0 ) {

                    // Pan by the amount of coverage
                    int panUpPixels = elPixelsCovered;

                    // Prevent panning so much the top of the element
                    // becomes hidden
                    panUpPixels = ( panUpPixels > elTop ?
                                    elTop : panUpPixels );

                    // Prevent panning more than the keyboard height
                    // (which produces an empty gap in the screen)
                    panUpPixels = ( panUpPixels > coveredHeight ?
                                    coveredHeight : panUpPixels );

                    // Pan up
                    contentView_.setY( -panUpPixels );
                }
            }
            else {
                // Keyboard probably just became hidden

                // Reset pan
                contentView_.setY( 0 );
            }

            // Save usabale height for the next comparison
            priorVisibleHeight_ = currentVisibleHeight;
        }
    }

    private int visibleHeight() {
        Rect r = new Rect();
        contentView_.getWindowVisibleDisplayFrame( r );
        return r.bottom - r.top;
    }

    // Customize this as needed...
    private int viewPortHeight() { return JavaScriptObject.viewPortHeight(); }
    private int focusElementTop( final float ratio ) {
        return (int) (ratio * JavaScriptObject.focusElementTop());
    }
    private int focusElementBottom( final float ratio ) {
        return (int) (ratio * JavaScriptObject.focusElementBottom());
    }

}
3
BuvinJ

En effet, l'apparence du clavier virtuel ne semble pas affecter le Activity de quelque façon que ce soit, peu importe ce que windowSoftInputMode je sélectionne dans le mode FullScreen.

Bien que je ne puisse pas trouver beaucoup de documentation sur cette propriété, je pense que le mode FullScreen a été conçu pour des applications de jeu qui ne nécessitent pas beaucoup d'utilisation du clavier logiciel. Si votre activité est une activité nécessitant une interaction de l'utilisateur via un clavier virtuel, veuillez reconsidérer votre décision en utilisant un thème autre que FullScreen. Vous pouvez désactiver la barre de titre en utilisant un thème NoTitleBar. Pourquoi voudriez-vous cacher la barre de notification?

2
Arnab Chakraborty

Il suffit de garder comme Android:windowSoftInputMode="adjustResize". Parce qu'il est donné de n'en garder qu'un seul parmi "adjustResize" et "adjustPan" (le mode d'ajustement de la fenêtre est spécifié avec adjustResize ou adjustPan. Il est vivement recommandé de toujours spécifier l'un ou l'autre). Vous pouvez le trouver ici: http://developer.Android.com/resources/articles/on-screen-inputs.html

Cela fonctionne parfaitement pour moi.

2
Balaji Khadake

J'ai utilisé Joseph Johnson pour créer la classe AndroidBug5497Workaround mais pour obtenir un espace noir entre le clavier virtuel et la vue. J'ai référé ce lien Greg Ennis . Après avoir apporté quelques modifications à ce qui précède, c’est mon code de travail final.

 public class SignUpActivity extends Activity {

 private RelativeLayout rlRootView; // this is my root layout
 private View rootView;
 private ViewGroup contentContainer;
 private ViewTreeObserver viewTreeObserver;
 private ViewTreeObserver.OnGlobalLayoutListener listener;
 private Rect contentAreaOfWindowBounds = new Rect();
 private FrameLayout.LayoutParams rootViewLayout;
 private int usableHeightPrevious = 0;

 private View mDecorView;

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_sign_up);
  mDecorView = getWindow().getDecorView();
  contentContainer =
   (ViewGroup) this.findViewById(Android.R.id.content);

  listener = new OnGlobalLayoutListener() {
   @Override
   public void onGlobalLayout() {
    possiblyResizeChildOfContent();
   }
  };

  rootView = contentContainer.getChildAt(0);
  rootViewLayout = (FrameLayout.LayoutParams)
  rootView.getLayoutParams();

  rlRootView = (RelativeLayout) findViewById(R.id.rlRootView);


  rlRootView.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
   @Override
   public void onGlobalLayout() {
    int heightDiff = rlRootView.getRootView().getHeight() - rlRootView.getHeight();
    if (heightDiff > Util.dpToPx(SignUpActivity.this, 200)) {
     // if more than 200 dp, it's probably a keyboard...
     //  Logger.info("Soft Key Board ", "Key board is open");

    } else {
     Logger.info("Soft Key Board ", "Key board is CLOSED");

     hideSystemUI();
    }
   }
  });
 }

 // This snippet hides the system bars.
 protected void hideSystemUI() {
  // Set the IMMERSIVE flag.
  // Set the content to appear under the system bars so that the 
  content
  // doesn't resize when the system bars hide and show.
  mDecorView.setSystemUiVisibility(
   View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
 }
 @Override
 protected void onPause() {
  super.onPause();
  if (viewTreeObserver.isAlive()) {
   viewTreeObserver.removeOnGlobalLayoutListener(listener);
  }
 }

 @Override
 protected void onResume() {
  super.onResume();
  if (viewTreeObserver == null || !viewTreeObserver.isAlive()) {
   viewTreeObserver = rootView.getViewTreeObserver();
  }
  viewTreeObserver.addOnGlobalLayoutListener(listener);
 }

 @Override
 protected void onDestroy() {
  super.onDestroy();
  rootView = null;
  contentContainer = null;
  viewTreeObserver = null;
 }
 private void possiblyResizeChildOfContent() {
  contentContainer.getWindowVisibleDisplayFrame(contentAreaOfWindowBounds);

  int usableHeightNow = contentAreaOfWindowBounds.height();

  if (usableHeightNow != usableHeightPrevious) {
   rootViewLayout.height = usableHeightNow;
   rootView.layout(contentAreaOfWindowBounds.left,
    contentAreaOfWindowBounds.top, contentAreaOfWindowBounds.right, contentAreaOfWindowBounds.bottom);
   rootView.requestLayout();

   usableHeightPrevious = usableHeightNow;
  } else {

   this.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
  }
 }
}
1
Venkat

basé sur https://stackoverflow.com/a/19494006/1815624 et désir de le réaliser ...

idée mise à jour


combiner les réponses de

Code pertinent:

        if (heightDifference > (usableHeightSansKeyboard / 4)) {

            // keyboard probably just became visible
            frameLayoutParams.height = usableHeightSansKeyboard - heightDifference;
            activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
            activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
        } else {

            // keyboard probably just became hidden
            if(usableHeightPrevious != 0) {
                frameLayoutParams.height = usableHeightSansKeyboard;
                activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
                activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);

            }

Source complète sur https://github.com/CrandellWS/AndroidBug5497Workaround/blob/master/AndroidBug5497Workaround.Java

vieille idée

Créez une valeur statique de la hauteur des conteneurs avant d'ouvrir le clavier. Définissez la hauteur du conteneur en fonction de usableHeightSansKeyboard - heightDifference à l'ouverture du clavier et réglez-la sur la valeur enregistrée à sa fermeture.

if (heightDifference > (usableHeightSansKeyboard / 4)) {
                // keyboard probably just became visible
                frameLayoutParams.height = usableHeightSansKeyboard - heightDifference;
                int mStatusHeight = getStatusBarHeight();
                frameLayoutParams.topMargin = mStatusHeight;
                ((MainActivity)activity).setMyMainHeight(usableHeightSansKeyboard - heightDifference);

                if(BuildConfig.DEBUG){
                    Log.v("aBug5497", "keyboard probably just became visible");
                }
            } else {
                // keyboard probably just became hidden
                if(usableHeightPrevious != 0) {
                    frameLayoutParams.height = usableHeightSansKeyboard;
                    ((MainActivity)activity).setMyMainHeight();    
                }
                frameLayoutParams.topMargin = 0;

                if(BuildConfig.DEBUG){
                    Log.v("aBug5497", "keyboard probably just became hidden");
                }
            }

Méthodes dans MainActivity

public void setMyMainHeight(final int myMainHeight) {

    runOnUiThread(new Runnable() {
        @Override
        public void run() {
            ConstraintLayout.LayoutParams rLparams =  (ConstraintLayout.LayoutParams) myContainer.getLayoutParams();
            rLparams.height = myMainHeight;

            myContainer.setLayoutParams(rLparams);
        }

    });

}

int mainHeight = 0;
public void setMyMainHeight() {

    runOnUiThread(new Runnable() {
        @Override
        public void run() {
            ConstraintLayout.LayoutParams rLparams =  (ConstraintLayout.LayoutParams) myContainer.getLayoutParams();
            rLparams.height = mainHeight;

            myContainer.setLayoutParams(rLparams);
        }

    });

}

Exemple de conteneur XML

<Android.support.constraint.ConstraintLayout
    xmlns:Android="http://schemas.Android.com/apk/res/Android"
    xmlns:app="http://schemas.Android.com/apk/res-auto"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    >
        <Android.support.constraint.ConstraintLayout
            Android:id="@+id/my_container"
            Android:layout_width="match_parent"
            Android:layout_height="0dp"
            app:layout_constraintHeight_percent=".8">

de même, des marges peuvent être ajoutées si nécessaire ...

Une autre considération est l'utilisation du rembourrage. Un exemple de ceci peut être trouvé à l'adresse:

https://github.com/mikepenz/MaterialDrawer/issues/95#issuecomment-80519589

1
CrandellWS

J'utilise actuellement cette approche et cela fonctionne comme un charme. Le truc, c'est que nous obtenons hauteur du clavier de différentes méthodes sur 21 ci-dessus et ci-dessous, puis nous l'utilisons comme remplissage inférieur de notre vue racine dans notre activité. J'ai supposé que votre mise en page n'avait pas besoin d'un remplissage supérieur (passe en dessous de la barre d'état), mais si vous le faites, informez-moi de mettre à jour ma réponse.

MainActivity.Java

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(final Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        RelativeLayout mainLayout = findViewById(R.id.main_layout);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Lollipop) {
            ViewCompat.setOnApplyWindowInsetsListener(mainLayout , new OnApplyWindowInsetsListener() {
                @Override
                public WindowInsetsCompat onApplyWindowInsets(View v, WindowInsetsCompat insets) {
                    v.setPadding(0, 0, 0, insets.getSystemWindowInsetBottom());
                    return insets;
                }
            });
        } else {
            View decorView = getWindow().getDecorView();
            final View contentView = mainLayout;
            decorView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
                @Override
                public void onGlobalLayout() {
                    Rect r = new Rect();
                    //r will be populated with the coordinates of your view that area still visible.
                    decorView.getWindowVisibleDisplayFrame(r);

                    //get screen height and calculate the difference with the useable area from the r
                    int height = decorView.getContext().getResources().getDisplayMetrics().heightPixels;
                    int diff = height - r.bottom;

                    //if it could be a keyboard add the padding to the view
                    if (diff != 0) {
                        // if the use-able screen height differs from the total screen height we assume that it shows a keyboard now
                        //check if the padding is 0 (if yes set the padding for the keyboard)
                        if (contentView.getPaddingBottom() != diff) {
                            //set the padding of the contentView for the keyboard
                            contentView.setPadding(0, 0, 0, diff);
                        }
                    } else {
                        //check if the padding is != 0 (if yes reset the padding)
                        if (contentView.getPaddingBottom() != 0) {
                            //reset the padding of the contentView
                            contentView.setPadding(0, 0, 0, 0);
                        }
                    }
                }
            });
        }
    }
...
}

N'oubliez pas d'adresser votre vue racine avec un identifiant:

activity_main.xml

<RelativeLayout
    xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:id="@+id/main_layout"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent">

J'espère que ça aide quelqu'un.

1
Sdghasemi

n'utilisez que Android:windowSoftInputMode="adjustResize|stateHidden comme vous utilisez AdjustPan, puis désactivez la propriété de redimensionnement

1
Azhar Shaikh

Aujourd'hui, ne fonctionne pas, les problèmes de réglage de la taille et de l'affichage en plein écran sont effectifs pour Android sdk.

De réponses j'ai trouvé:
la solution - mais la solution présente les problèmes d'image suivants:

Que je trouve la solution et supprime l'action inutile:

this.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);

Donc, voyez mon code de solution fixe sur Kotlin:

class AndroidBug5497Workaround constructor(val activity: Activity) {

    private val content = activity.findViewById<View>(Android.R.id.content) as FrameLayout

    private val mChildOfContent = content.getChildAt(0)
    private var usableHeightPrevious: Int = 0
    private val contentContainer = activity.findViewById(Android.R.id.content) as ViewGroup
    private val rootView = contentContainer.getChildAt(0)
    private val rootViewLayout = rootView.layoutParams as FrameLayout.LayoutParams

    private val listener = {
        possiblyResizeChildOfContent()
    }

    fun addListener() {
        mChildOfContent.apply {
            viewTreeObserver.addOnGlobalLayoutListener(listener)

        }
    }

    fun removeListener() {
        mChildOfContent.apply {
            viewTreeObserver.removeOnGlobalLayoutListener(listener)
        }
    }

    private fun possiblyResizeChildOfContent() {
        val contentAreaOfWindowBounds = Rect()
        mChildOfContent.getWindowVisibleDisplayFrame(contentAreaOfWindowBounds)
        val usableHeightNow = contentAreaOfWindowBounds.height()

        if (usableHeightNow != usableHeightPrevious) {
            rootViewLayout.height = usableHeightNow
            rootView.layout(contentAreaOfWindowBounds.left,
                    contentAreaOfWindowBounds.top, contentAreaOfWindowBounds.right, contentAreaOfWindowBounds.bottom);
            mChildOfContent.requestLayout()
            usableHeightPrevious = usableHeightNow
        }
    }
}

Ma correction de bogue implémente le code:

 class LeaveDetailActivity : BaseActivity(){

    private val keyBoardBugWorkaround by lazy {
        AndroidBug5497Workaround(this)
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

    }

    override fun onResume() {
        keyBoardBugWorkaround.addListener()
        super.onResume()
    }

    override fun onPause() {
        keyBoardBugWorkaround.removeListener()
        super.onPause()
    }
}
0
Serg Burlaka

J'ai essayé de nombreuses solutions, dont celles de Joseph Johnson et de Johan Stuyts. Mais en conséquence, dans tous les cas, il y a toujours un espace entre le contenu et le clavier de certains appareils (comme Lenovo s820). J'ai donc apporté quelques modifications à leurs codes et j'ai finalement trouvé une solution efficace.

Mon idée est d’ajouter une marge en haut du contenu lorsque le clavier est affiché.

contentContainer.getWindowVisibleDisplayFrame(contentAreaOfWindowBounds);
    int usableHeightNow = contentAreaOfWindowBounds.height();

    if (usableHeightNow != usableHeightPrevious) {

        int difference = usableHeightNow - usableHeightPrevious;

        if (difference < 0 && difference < -150) {
            keyboardShowed = true;
            rootViewLayout.topMargin -= difference + 30;
            rootViewLayout.bottomMargin += 30;
        }
        else if (difference < 0 && difference > -150){
            rootViewLayout.topMargin -= difference + 30;
        }
        else if (difference > 0 && difference > 150) {
            keyboardShowed = false;
            rootViewLayout.topMargin = 0;
            rootViewLayout.bottomMargin = 0;
        }

        rootView.requestLayout();

        Log.e("Bug Workaround", "Difference: " + difference);

        usableHeightPrevious = usableHeightNow;
}

Comme vous pouvez le constater, j'ajoute une différence de 30 px à la différence car il existe un petit espace blanc entre le haut de l'écran et la zone de contenu avec marge. Et comme je ne sais pas d'où ça vient, j'ai décidé de réduire les marges et maintenant, cela fonctionne exactement comme je le souhaitais.

0
IDmikael

J'utilisais uniquement le mode plein écran pour masquer la barre d'état. Cependant, je veux que l'application se redimensionne lorsque le clavier est affiché. Toutes les autres solutions (probablement en raison de l'âge du message) étaient compliquées ou impossibles à utiliser (je souhaite éviter les modifications Java code du sac de PhoneGap Build).

Au lieu d'utiliser Plein écran, j'ai modifié ma configuration pour que Android ne soit pas en plein écran:

            <preference name="fullscreen" value="false" />

Et ajouté le cordova-plugin-statusbar, via la ligne de commande:

cordova plugin add cordova-plugin-statusbar

Quand l'application est chargée, j'appelle simplement une méthode du plugin pour se cacher, comme:

    if (window.cordova && window.cordova.platformId == 'Android' && window.StatusBar)
        window.StatusBar.hide();

Cela fonctionne comme un charme. Seul inconvénient, c'est que la barre d'état est rapidement visible pendant le chargement de l'application. Pour mes besoins, ce n'était pas un problème.

0
raider33

Merci Joseph pour votre réponse. Cependant, dans la méthode éventuellementResizeChildOfContent (), la partie

else {
            // keyboard probably just became hidden
            frameLayoutParams.height = usableHeightSansKeyboard;
        }

ne fonctionnait pas pour moi, la partie inférieure de la vue devenant cachée. J'ai donc dû prendre une variable globale restoreHeight, et dans le constructeur, j'ai inséré la dernière ligne

restoreHeight = frameLayoutParams.height;

puis j'ai remplacé la première partie mentionnée avec

else {
            // keyboard probably just became hidden
            frameLayoutParams.height = restoreHeight;
        }

Mais je ne sais pas pourquoi votre code n'a pas fonctionné pour moi. Ce serait très utile si quelqu'un pouvait faire la lumière à ce sujet.

0
Debanjan

1) Créer KeyboardHeightHelper:

public class KeyboardHeightHelper {

    private final View decorView;
    private int lastKeyboardHeight = -1;

    public KeyboardHeightHelper(Activity activity, View activityRootView, OnKeyboardHeightChangeListener listener) {
        this.decorView = activity.getWindow().getDecorView();
        activityRootView.getViewTreeObserver().addOnGlobalLayoutListener(() -> {
            int keyboardHeight = getKeyboardHeight();
            if (lastKeyboardHeight != keyboardHeight) {
                lastKeyboardHeight = keyboardHeight;
                listener.onKeyboardHeightChange(keyboardHeight);
            }
        });
    }

    private int getKeyboardHeight() {
        Rect rect = new Rect();
        decorView.getWindowVisibleDisplayFrame(rect);
        return decorView.getHeight() - rect.bottom;
    }

    public interface OnKeyboardHeightChangeListener {
        void onKeyboardHeightChange(int keyboardHeight);
    }
}

2) Laissez votre activité être en plein écran:

activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);

3) Écoutez les changements de hauteur du clavier et ajoutez un remplissage inférieur pour votre vue:

View rootView = activity.findViewById(R.id.root); // your root view or any other you want to resize
KeyboardHeightHelper effectiveHeightHelper = new KeyboardHeightHelper(
        activity, 
        rootView,
        keyboardHeight -> rootView.setPadding(0, 0, 0, keyboardHeight));

So, chaque fois que le clavier apparaîtra à l'écran - le remplissage inférieur de votre vue changera et le contenu sera réorganisé.

0
repitch

J'ai essayé toutes les réponses possibles de stackOverflow, enfin j'ai résolu après une longue recherche. J'ai utilisé la disposition des coordonnées et j'ai changé cela avec linearLayout et mon problème est résolu. Je ne sais pas si la mise en page des coordonnées a des bugs ou quoi que ce soit de mon erreur.

0
yubaraj poudel

Vous voulez que la barre inférieure reste en bas de la vue, mais lorsque le clavier est affiché, ils doivent monter pour être placés au-dessus du clavier, n'est-ce pas?

Vous pouvez essayer cet extrait de code:

<RelativeLayout
    xmlns:Android="http://schemas.Android.com/apk/res/Android"
    ...>

    <RelativeLayout
        Android:id="@+id/RelativeLayoutTopBar"
    ...>
    </RelativeLayout>

    <LinearLayout
        Android:id="@+id/LinearLayoutBottomBar"
        Android:layout_alignParentBottom = true
        ...>
    </LinearLayout>

    <LinearLayout
    Android:layout_width="fill_parent"
    Android:layout_height="390dp"
    Android:orientation="vertical" 
    Android:layout_above="@+id/LinearLayoutBottomBar"
    Android:layout_below="@+id/RelativeLayoutTopBar"> 

    <ScrollView 
        Android:layout_width="fill_parent" 
        Android:layout_height="wrap_content"
        Android:layout_marginTop="10dp"
        Android:layout_marginBottom="10dp"
        Android:id="@+id/ScrollViewBackground">

            ...

        </ScrollView>
     </LinearLayout>
  </RelativeLayout>

La barre inférieure reste collée au bas de la vue et le LinearLayout contenant la vue ScrollView prend ce qu'il reste de la vue après l'affichage de la barre supérieure/inférieure et du clavier. Faites-moi savoir si cela fonctionne pour vous aussi.

0
banzai86

Ne pas utiliser:

getWindow().addFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);

parce que ça marche mal. Au lieu de cela, utilisez:

fun setFullScreen(fullScreen: Boolean) {
        val decorView = getWindow().getDecorView()
        val uiOptions : Int
        if(fullScreen){
            uiOptions = View.SYSTEM_UI_FLAG_FULLSCREEN // this hide statusBar
            toolbar.visibility = View.GONE // if you use toolbar
            tabs.visibility = View.GONE // if you use tabLayout
        } else {
            uiOptions = View.SYSTEM_UI_FLAG_VISIBLE // this show statusBar
            toolbar.visibility = View.VISIBLE
            tabs.visibility = View.VISIBLE
        }
        decorView.setSystemUiVisibility(uiOptions)
    }
0
Alberto