it-swarm.it

Android Come regolare il layout in modalità schermo intero quando è visibile la tastiera virtuale

Ho fatto molte ricerche per adattare il layout quando il softkeyboard è attivo e l'ho implementato con successo, ma il problema si presenta quando uso Android:theme="@Android:style/Theme.NoTitleBar.Fullscreen" questo nel mio tag attività nel file manifest.

Per questo ho usato Android:windowSoftInputMode="adjustPan|adjustResize|stateHidden" con diverse opzioni ma senza fortuna.

Dopo di che ho implementato FullScreen a livello di codice e ho provato vari layout per lavorare con FullScreen ma tutto invano.

Ho fatto riferimento a questi collegamenti e ho cercato molti post qui relativi a questo problema:

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/

Ecco il codice 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

Voglio che i 2 pulsanti in basso vadano verso l'alto quando la tastiera viene visualizzata in figura.

enter image description here

161
Vineet Shukla
69
nmr

Sulla base della soluzione di yghm, ho codificato una classe di convenienza che mi consente di risolvere il problema con una riga (ovviamente dopo aver aggiunto la nuova classe al mio codice sorgente). Il one-liner è:

     AndroidBug5497Workaround.assistActivity(this);

E la classe di implementazione è:


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);
    }
}

Spero che questo aiuti qualcuno.

243
Joseph Johnson

Poiché la risposta è già stata scelta e il problema è noto per essere un bug, ho pensato di aggiungere un "Possibile soluzione".

È possibile attivare o disattivare la modalità schermo intero quando viene visualizzata la tastiera virtuale. Ciò consente a "adjustPan" di funzionare correttamente.

In altre parole, uso ancora @ Android: style/Theme.Black.NoTitleBar.Fullscreen come parte del tema dell'applicazione e stateVisible | AdjustResize come parte della modalità di input soft della finestra attività ma per per farli lavorare insieme devo attivare la modalità a schermo intero prima che la tastiera venga visualizzata.

Usa il seguente codice:

Disattiva la modalità a schermo intero

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

Attiva la modalità a schermo intero

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

Nota: l'ispirazione proviene da: Nascondere il titolo in una modalità a schermo intero

34
LEO

Ho provato soluzione di Joseph Johnson , ma come altri ho riscontrato il problema del gap tra contenuto e tastiera. Il problema si verifica perché la modalità di input soft è sempre panoramica quando si utilizza la modalità a schermo intero. Questa panoramica interferisce con la soluzione di Joseph quando si attiva un campo di input che sarebbe nascosto dall'input soft.

Quando viene visualizzato l'input software, il contenuto viene prima spostato in base alla sua altezza originale, quindi ridimensionato dal layout richiesto dalla soluzione di Joseph. Il ridimensionamento e il layout successivo non annullano il pan, il che si traduce in uno spazio vuoto. L'ordine completo degli eventi è:

  1. Listener di layout globale
  2. Panoramica
  3. Layout del contenuto (= ridimensionamento effettivo del contenuto)

Non è possibile disabilitare la panoramica, ma è possibile forzare l'offset della panoramica su 0 modificando l'altezza del contenuto. Questo può essere fatto nel listener, perché viene eseguito prima che avvenga il panning. L'impostazione dell'altezza del contenuto all'altezza disponibile si traduce in un'esperienza utente fluida, ovvero senza sfarfallio.

Ho anche apportato queste modifiche. Se qualcuno di questi problemi presenta, fammi sapere:

  • Determinazione modificata dell'altezza disponibile per utilizzare getWindowVisibleDisplayFrame. Rect viene memorizzato nella cache per impedire un po 'di immondizia non necessaria.
  • Consenti anche al listener di essere rimosso. Ciò è utile quando si riutilizza un'attività per frammenti diversi con requisiti a schermo intero diversi.
  • Non distinguere tra tastiera mostrata o nascosta, ma imposta sempre l'altezza del contenuto all'altezza del riquadro di visualizzazione visibile.

È stato testato su un Nexus 5 ed emulatori con livelli API 16-24 con dimensioni dello schermo che vanno da minuscole a grandi.

Il codice è stato portato su Kotlin, ma riportare le mie modifiche su Java è semplice. Fammi sapere se hai bisogno di aiuto:

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

Ho appena trovato una soluzione semplice e affidabile se stai utilizzando l'approccio UI di sistema ( https://developer.Android.com/training/system-ui/immersive.html ).

Funziona nel caso in cui stai usando View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN, ad es. se stai usando CoordinatorLayout.

Non funzionerà per WindowManager.LayoutParams.FLAG_FULLSCREEN (quello che puoi anche impostare in tema con Android:windowFullscreen), ma puoi ottenere un effetto simile con SYSTEM_UI_FLAG_LAYOUT_STABLE (che "ha lo stesso effetto visivo" secondo i documenti ) e questa soluzione dovrebbe funzionare di nuovo.

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)

L'ho provato sul mio dispositivo con Marshmallow.

La chiave è che le tastiere software sono anche una delle finestre di sistema (come la barra di stato e la barra di navigazione), quindi il WindowInsets inviato dal sistema contiene informazioni accurate e affidabili al riguardo.

Per il caso d'uso come in DrawerLayout in cui stiamo cercando di disegnare dietro la barra di stato, possiamo creare un layout che ignori solo l'inserto superiore e applichi l'inserto inferiore che rappresenta la tastiera virtuale.

Ecco il mio FrameLayout personalizzato:

/**
 * 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);
        }
    }
}

E per usarlo:

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

Questo dovrebbe teoricamente funzionare per qualsiasi dispositivo senza modifiche folli, molto meglio di qualsiasi hack che tenta di prendere come riferimento un 1/3 o 1/4 casuale di dimensioni dello schermo.

(Richiede API 16+, ma sto usando lo schermo intero solo su Lollipop + per disegnare dietro la barra di stato, quindi è la soluzione migliore in questo caso.)

10
Dreaming in Code

Ho dovuto affrontare anche questo problema e ho avuto un lavoro intorno al quale ho controllato su HTC one, galaxy s1, s2, s3, note e sensazione HTC.

mettere un listener di layout globale nella vista principale del layout

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

e lì ho controllato la differenza di altezza e se la differenza di altezza dello schermo è maggiore di un terzo dell'altezza dello schermo, possiamo supporre che la tastiera sia aperta. preso da questa risposta .

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;
    }
}

questo probabilmente non è a prova di proiettile e forse su alcuni dispositivi non funzionerà ma ha funzionato per me e spero che possa aiutare anche te.

9
yghm

Si noti che Android:windowSoftInputMode="adjustResize" non funziona quando WindowManager.LayoutParams.FLAG_FULLSCREEN è impostato per un'attività. Hai due opzioni.

  1. Disattiva la modalità a schermo intero per la tua attività. L'attività non viene ridimensionata in modalità schermo intero. Puoi farlo in xml (modificando il tema dell'attività) o nel codice Java. Aggiungi le seguenti righe nel tuo metodo onCreate ().

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

O

  1. Utilizzare un modo alternativo per ottenere la modalità a schermo intero. Aggiungi il seguente codice nel tuo metodo 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);`
    

Si noti che il metodo 2 funziona solo in Android 4.1 e versioni successive.

7
Abhinav Chauhan

Ho implementato la soluzione Joseph Johnson e ha funzionato bene, ho notato che dopo aver usato questa soluzione a volte il cassetto sull'applicazione non si chiudeva correttamente. Ho aggiunto una funzionalità per rimuovere il listener removeOnGlobalLayoutListener quando l'utente chiude il frammento in cui si trovano gli 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);
    } 
}

usa la classe in cui si trova il mio edittexts

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

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

Per farlo funzionare con FullScreen:

Utilizzare il plug-in tastiera ionic. Ciò ti consente di ascoltare quando appare e scompare la tastiera.

OnDeviceReady aggiungi questi listener di eventi:

// 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 logica:

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');
}

Fondamentalmente se la loro differenza è meno, allora è la quantità di pixel che copre la tastiera del tuo input. Quindi, se modifichi il div del tuo genitore con questo, dovresti contrastarlo.

L'aggiunta di timeout alla logica indica che 300 ms dovrebbero anche ottimizzare le prestazioni (poiché ciò consentirà di visualizzare il tempo della tastiera.

5
tyler_mitchell

Aggiungi Android:fitsSystemWindows="true" al layout e questo layout verrà ridimensionato.

5
zayn

Ho provato la lezione di Joseph Johnson, e ha funzionato, ma non ha soddisfatto le mie esigenze. Invece di emulare Android: windowSoftInputMode = "AdjustResize", dovevo emulare Android: windowSoftInputMode = "AdjustPan".

Lo sto usando per una visualizzazione web a schermo intero. Per spostare la visualizzazione del contenuto nella posizione corretta, ho bisogno di utilizzare un'interfaccia javascript che fornisca dettagli sulla posizione dell'elemento della pagina che ha lo stato attivo e quindi riceve l'input da tastiera. Ho omesso quei dettagli, ma ho fornito la mia riscrittura della lezione di Joseph Johnson. Fornirà una base molto solida per implementare una panoramica personalizzata rispetto al suo ridimensionamento.

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

In effetti l'aspetto della tastiera non sembra influenzare Activity in alcun modo, indipendentemente da windowSoftInputMode che seleziono nella modalità FullScreen.

Sebbene non sia stato possibile trovare molta documentazione su questa proprietà, penso che la modalità FullScreen sia stata progettata per applicazioni di gioco che non richiedono un uso eccessivo della tastiera software. Se la tua è un'attività che richiede l'interazione dell'utente tramite la tastiera software, ti preghiamo di riconsiderare utilizzando un tema non FullScreen. È possibile disattivare la barra del titolo utilizzando un tema NoTitleBar. Perché dovresti nascondere la barra delle notifiche?

2

Continua come Android:windowSoftInputMode="adjustResize". Perché viene dato per mantenere solo uno tra "adjustResize" e "adjustPan" (La modalità di regolazione della finestra è specificata con AdjustResize o AdjustPan. Si consiglia vivamente di specificare sempre l'uno o l'altro). Puoi trovarlo qui: http://developer.Android.com/resources/articles/on-screen-inputs.html

Funziona perfettamente per me.

2
Balaji Khadake

Ho usato Joseph Johnson creato AndroidBug5497Workaround class ma ottenendo uno spazio nero tra la tastiera e la vista. Ho indicato questo link Greg Ennis . Dopo aver apportato alcune modifiche a quanto sopra, questo è il mio codice di lavoro finale.

 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

basato su https://stackoverflow.com/a/19494006/1815624 e desiderio di farlo accadere ...

idea aggiornata


combinando le risposte di

Codice pertinente:

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

            }

Fonte completa su https://github.com/CrandellWS/AndroidBug5497Workaround/blob/master/AndroidBug5497Workaround.Java

vecchia idea

Creare un valore statico dell'altezza dei contenitori prima di aprire la tastiera Impostare l'altezza del contenitore in base a usableHeightSansKeyboard - heightDifference quando la tastiera si apre e reimpostare il valore salvato alla chiusura

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");
                }
            }

Metodi in 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);
        }

    });

}

Esempio di contenitore 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">

allo stesso modo è possibile aggiungere margini se necessario ...

Un'altra considerazione è l'uso dell'imbottitura, un esempio di questo può essere trovato su:

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

1
CrandellWS

Attualmente sto usando questo approccio e funziona come un fascino. Il trucco è che otteniamo altezza della tastiera da diversi metodi su 21 sopra e sotto e quindi usiamolo come riempimento inferiore della nostra vista radice nella nostra attività. Presumo che il tuo layout non abbia bisogno di un'imbottitura superiore (va sotto la barra di stato) ma, nel caso, informami per aggiornare la mia risposta.

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

Non dimenticare di indirizzare la vista radice con un ID:

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

Spero che aiuti qualcuno.

1
Sdghasemi

usa Android:windowSoftInputMode="adjustResize|stateHidden solo mentre usi AdjustPan, quindi disabilita la proprietà di ridimensionamento

1
Azhar Shaikh

Oggi non funziona AdjustResize sul problema dello schermo intero è reale per Android sdk.

Dalle risposte che ho trovato:
la soluzione - ma la soluzione presenta questo problema con l'immagine:

Di quanto ho trovato la soluzione e rimuovere l'unica azione non necessaria:

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

Quindi, vedi il mio codice di soluzione fissa su 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
        }
    }
}

Il mio codice dell'attrezzo per la correzione di bug:

 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

Ho provato molte soluzioni tra cui Joseph Johnson e Johan Stuyts. Ma di conseguenza ho ottenuto uno spazio bianco tra contenuto e tastiera su alcuni dispositivi (come Lenovo s820) in tutti i casi. Quindi ho apportato alcune modifiche ai loro codici e finalmente ho ottenuto una soluzione funzionante.

La mia idea si basa sull'aggiunta di margine all'inizio del contenuto quando viene visualizzata la tastiera.

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;
}

Come puoi vedere, aggiungo 30 px alla differenza perché c'è un piccolo spazio bianco tra la parte superiore dello schermo e l'area di contenuto con margine. E non so da dove appaia, quindi ho deciso di ridurre i margini e ora funziona esattamente come mi serviva.

0
IDmikael

Stavo solo usando la modalità a schermo intero per nascondere la barra di stato. Tuttavia, desidero ridimensionare l'app quando viene visualizzata la tastiera. Tutte le altre soluzioni (probabilmente a causa dell'età dei post) erano complicate o non possibili per il mio uso (voglio evitare di cambiare il codice Java per il sacco di PhoneGap Build).

Invece di utilizzare lo schermo intero, ho modificato la mia configurazione per Android in modo che non fosse a schermo intero:

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

E aggiunto cordova-plugin-statusbar, tramite riga di comando:

cordova plugin add cordova-plugin-statusbar

Quando l'app è stata caricata, chiamo semplicemente un metodo sul plug-in per nascondersi, come:

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

Funziona come un fascino. L'unico aspetto negativo è che la barra di stato è facilmente visibile mentre l'app viene caricata. Per le mie esigenze, non è stato un problema.

0
raider33

Grazie Giuseppe per la tua risposta. Tuttavia, nel metodo eventualmenteResizeChildOfContent (), la porzione

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

non funzionava per me, poiché la parte inferiore della vista veniva nascosta. Quindi ho dovuto eseguire un ripristino della variabile globaleHeight e nel costruttore ho inserito l'ultima riga

restoreHeight = frameLayoutParams.height;

e poi ho sostituito la parte precedentemente menzionata con

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

Ma non ho idea del perché il tuo codice non abbia funzionato per me. Sarebbe di grande aiuto se qualcuno potesse far luce su questo.

0
Debanjan

1) Crea 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) Lascia che la tua attività sia a schermo intero:

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

3) Ascolta le modifiche dell'altezza della tastiera e aggiungi un'imbottitura inferiore per la visualizzazione:

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, ogni volta che la tastiera apparirà sullo schermo - il padding inferiore per la tua vista cambierà e il contenuto verrà riorganizzato.

0
repitch

Ho provato tutte le possibili risposte da stackOverflow, finalmente ho risolto dopo una settimana di ricerca lunga. Ho usato il layout delle coordinate e l'ho modificato con linearLayout e il mio problema è stato risolto. Non so che probabilmente il layout delle coordinate abbia dei bug o qualunque cosa sia il mio errore.

0
yubaraj poudel

Vuoi che la barra in basso si attacchi alla parte inferiore della vista, ma quando viene visualizzata la tastiera, dovrebbero spostarsi verso l'alto per essere posizionati sopra la tastiera, giusto?

Puoi provare questo frammento di codice:

<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 barra inferiore si attaccherà nella parte inferiore della vista e il LinearLayout contenente ScrollView prenderà ciò che resta della vista dopo la visualizzazione della barra superiore/inferiore e della tastiera. Fammi sapere se funziona anche per te.

0
banzai86

Non usare:

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

perché funziona male. Invece, usa:

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