windowSoftInputMode = "AdjustResize" ne fonctionne pas avec l'action translucide / la barre de navigation

130

J'ai des problèmes avec la barre d'action / barre de navigation translucide dans le nouvel Android KitKat (4.4) et le windowSoftInputMode="adjustResize".

Normalement, en changeant InputMode pour AdjustResize, l'application devrait se redimensionner lorsque le clavier est affiché ... mais ici, ce ne sera pas le cas! Si je supprime les lignes pour l'effet transparent, le redimensionnement fonctionne.

Donc, si le clavier est visible, ma ListView est en dessous et je ne peux pas accéder aux derniers éléments. (Uniquement en masquant le clavier manuellement)

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="XYZ"
android:versionCode="23"
android:versionName="0.1" >

<uses-sdk
    android:minSdkVersion="9"
    android:targetSdkVersion="19" />

<application
    android:allowBackup="true"
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/Theme.XYZStyle" >
    <activity
        android:name="XYZ"
        android:label="@string/app_name"
        android:windowSoftInputMode="adjustResize" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
</application>

</manifest>

valeurs-v19 / styles.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>

<style name="Theme.XYZStyle" parent="@style/Theme.AppCompat.Light">
    <item name="android:windowTranslucentStatus">true</item>
    <item name="android:windowTranslucentNavigation">true</item>
</style>

</resources>

fragment.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >

<ListView
    android:id="@+id/listView_contacts"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:clipToPadding="false"
    android:divider="@null"
    android:dividerHeight="0dp"
    android:drawSelectorOnTop="true"
    android:fastScrollAlwaysVisible="true"
    android:fastScrollEnabled="true"
    android:paddingBottom="@dimen/navigationbar__height" >
</ListView>

</RelativeLayout>

Des idées pour résoudre ce problème?

Fabianbru
la source

Réponses:

184

Il vous manque la propriété suivante:

android:fitsSystemWindows="true"

à la racine RelativeLayoutde la mise en page du fragment .xml.

Mettre à jour:

L'année dernière, il y avait une conférence intéressante de Chris Bane qui explique en détail comment cela fonctionne:

https://www.youtube.com/watch?v=_mGDMVRO3iE

pablisco
la source
5
Je suppose que c'est quelque chose avec la politique du plein écran
Felix.D
1
Tu es l'homme! Je ce problème ne m'est arrivé que sur la version Lollipop, et il le corrige.
David
6
@David Ce n'est pas encore corrigé, toujours en train de casser dans le dispositif de guimauve, si vous ouvrez une boîte de dialogue et essayez de faire défiler, le clavier logiciel bloquera le défilement
Bytecode
5
Cela fonctionne, mais entre en conflit avec ma barre d'outils et la personnalisation de la barre d'état
Ninja
2
fonctionne mais la barre d'état n'est plus translucide. Je veux que la mise en page couvre tout l'écran.
htafoya
34

Il y a un rapport de bogue connexe ici . J'ai trouvé une solution de contournement qui, à partir de tests limités, semble faire l'affaire sans répercussions. Ajoutez une implémentation personnalisée de votre racine ViewGroup(j'utilise presque toujours FrameLayout, c'est donc ce que j'ai testé) avec la logique ci-dessous. Ensuite, utilisez cette disposition personnalisée à la place de votre disposition racine et assurez-vous de la définir android:fitsSystemWindows="true". Vous pouvez alors simplement appeler à getInsets()tout moment après la mise en page (par exemple, ajouter un OnPreDrawListener) pour ajuster le reste de votre mise en page pour tenir compte des inserts système, si vous le souhaitez.

import android.content.Context;
import android.graphics.Rect;
import android.os.Build;
import android.util.AttributeSet;
import android.widget.FrameLayout;
import org.jetbrains.annotations.NotNull;

/**
 * @author Kevin
 *         Date Created: 3/7/14
 *
 * https://code.google.com/p/android/issues/detail?id=63777
 * 
 * When using a translucent status bar on API 19+, the window will not
 * resize to make room for input methods (i.e.
 * {@link android.view.WindowManager.LayoutParams#SOFT_INPUT_ADJUST_RESIZE} and
 * {@link android.view.WindowManager.LayoutParams#SOFT_INPUT_ADJUST_PAN} are
 * ignored).
 * 
 * To work around this; override {@link #fitSystemWindows(android.graphics.Rect)},
 * capture and override the system insets, and then call through to FrameLayout's
 * implementation.
 * 
 * For reasons yet unknown, modifying the bottom inset causes this workaround to
 * fail. Modifying the top, left, and right insets works as expected.
 */
public final class CustomInsetsFrameLayout extends FrameLayout {
    private int[] mInsets = new int[4];

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

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

    public CustomInsetsFrameLayout(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    public final int[] getInsets() {
        return mInsets;
    }

    @Override
    protected final boolean fitSystemWindows(@NotNull Rect insets) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            // Intentionally do not modify the bottom inset. For some reason, 
            // if the bottom inset is modified, window resizing stops working.
            // TODO: Figure out why.

            mInsets[0] = insets.left;
            mInsets[1] = insets.top;
            mInsets[2] = insets.right;

            insets.left = 0;
            insets.top = 0;
            insets.right = 0;
        }

        return super.fitSystemWindows(insets);
    }
}

Étant donné que fitSystemWindows est obsolète, veuillez vous reporter à la réponse ci-dessous pour terminer la solution de contournement.

Kevin Coppock
la source
1
En fait, SOFT_INPUT_ADJUST_PAN ne semble PAS être ignoré selon mon expérience - il déplacera tout l'écran vers le haut, y compris la barre système et le clavier décalé sous une vue focalisée.
sealskej
Merci - vous avez raison sur le SOFT_INPUT_ADJUST_PAN. J'ai utilisé ceci dans mon fragment: getActivity (). GetWindow (). SetSoftInputMode (WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
Simon
C'était le seul moyen que je pouvais obtenir avec AdjustResize pour l'activité (nécessaire pour le défilement de la vue lors de l'affichage du clavier), fitSystemWindows défini sur true afin que le défilement se produise réellement sur> = Lollipop et ayant un statusBar translucide. Merci beaucoup.
Lucas le
c'est la solution réelle
martyglaubitz
Il faut du temps pour afficher et masquer le clavier, même s'il faut du temps pour pousser la mise en page vers le haut. Toute solution ?
Vanjara Sweta le
28

La réponse @kcoppock est vraiment utile, mais fitSystemWindows était obsolète au niveau de l'API 20

Donc, depuis l'API 20 (KITKAT_WATCH), vous devez remplacer onApplyWindowInsets

@Override
public final WindowInsets onApplyWindowInsets(WindowInsets insets) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT_WATCH) {
        return super.onApplyWindowInsets(insets.replaceSystemWindowInsets(0, 0, 0,
                insets.getSystemWindowInsetBottom()));
    } else {
        return insets;
    }
}
Victor91
la source
Dans quelle classe devrions-nous remplacer cela?
Ben-J
@ Ben-J dans une classe qui étend la classe d'origine
Victor91
Je n'ai aucune idée de la raison pour laquelle vous définissez des éléments de tableau mInsets alors qu'ils ne sont pas utilisés, mais cela fonctionne
Buckstabue
1
Au lieu de votre vérification de version, vous pouvez utiliserViewCompat.setOnApplyWindowInsetsListener
repitch
Je ne pouvais pas faire fonctionner cela, mais la dispatchApplyWindowInsetssubstitution à la place (même code) a fonctionné pour moi
petter
11

Cela a fonctionné pour moi d'avoir une barre d'état translucide et d'ajusterResize en fragment:

  1. Créez un RelativeLayout personnalisé comme l'ont dit @ Victor91 et @kcoppock.

  2. Utilisez CustomRelativeLayout comme mise en page parent pour votre fragment.

  3. Déclarez le thème avec Android: windowTranslucentStatus = true

  4. L'activité du conteneur doit être déclarée dans le manifeste avec android: windowSoftInputMode = "AdjustResize" et utiliser le thème déclaré

  5. Veuillez utiliser correspondancesSystemWindows sur la disposition de racine de fragment!

    public class CustomRelativeLayout extends RelativeLayout {
    
        private int[] mInsets = new int[4];
    
        public CustomRelativeLayout(Context context) {
            super(context);
        }
    
        public CustomRelativeLayout(Context context, AttributeSet attrs) {
            super(context, attrs);
        }
    
        public CustomRelativeLayout(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
        }
    
        public CustomRelativeLayout(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
            super(context, attrs, defStyleAttr, defStyleRes);
        }
    
        @Override
        public final WindowInsets onApplyWindowInsets(WindowInsets insets) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT_WATCH) {
                mInsets[0] = insets.getSystemWindowInsetLeft();
                mInsets[1] = insets.getSystemWindowInsetTop();
                mInsets[2] = insets.getSystemWindowInsetRight();
                return super.onApplyWindowInsets(insets.replaceSystemWindowInsets(0, 0, 0,
                        insets.getSystemWindowInsetBottom()));
            } else {
                return insets;
            }
        }
    }

Puis en xml,

<com.blah.blah.CustomRelativeLayout 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:fitsSystemWindows="true">
</com.blah.blah.CustomRelativeLayout>
Herman
la source
1
C'est la meilleure réponse à ce jour, et je cherche une solution depuis quelque temps. Cela fonctionne parfaitement, mais vous devez ajouter un rembourrage supplémentaire à votre barre d'outils, sans cela, votre barre d'outils se chevauchera la barre d'état
Paulina
Qu'en est-il de windowTranslucentNavigation? pouvez-vous m'aider?
V-rund Puro-hit le
10

Si vous souhaitez personnaliser les inserts et que vous ciblez un niveau d'API> = 21, vous pouvez le faire sans avoir à créer un groupe de vues personnalisé. En définissant simplement le fitsSystemWindowsremplissage, la vue de votre conteneur sera appliquée par défaut, ce que vous ne voudrez peut-être pas.

Les vérifications de version sont intégrées à cette méthode et seuls les appareils> = 21 exécuteront le code à l'intérieur du lambda. Exemple de Kotlin:

ViewCompat.setOnApplyWindowInsetsListener(container) { view, insets ->
  insets.replaceSystemWindowInsets(0, 0, 0, insets.systemWindowInsetBottom).apply {
    ViewCompat.onApplyWindowInsets(view, this)
  }
}

Assurez-vous que votre mise en page définit toujours l' fitsSystemWindowsindicateur, sinon l'écouteur d'inserts de fenêtre ne sera pas appelé.

<FrameLayout
    android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    />

Ces sources sont utiles:

https://medium.com/google-developers/why-would-i-want-to-fitssystemwindows-4e26d9ce1eec https://medium.com/@azizbekian/windowinsets-24e241d4afb9

Victor Rendina
la source
1
Cela reste la meilleure approche, car vous pouvez appliquer cela à vous BaseFragment, avec view.fitsSystemWindows = trueet cela fonctionne simplement sans aucune modification des mises en page XML réelles ou des sous-classes de vue.
Bogdan Zurac
5

J'ai eu le même problème, Mon activité avait un ScrollView en tant que vue racine et avec la barre d'état translucide activée, elle ne se redimensionnait pas correctement lorsque le clavier montrait ... et par conséquent, l'écran ne défilait pas en cachant les vues d'entrée.

Solution: tout a été déplacé (mise en page et logique d'activité) dans un nouveau fragment. Puis changé l'activité pour n'inclure que ce fragment. Maintenant, tout fonctionne comme prévu!

Voici la disposition de l'activité:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"

    android:id="@+id/contentView"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true" />
araks
la source
Fonctionne comme un charme pour moi
imike
2

Basé sur la solution de contournement de Joseph Johnson dans Android Comment ajuster la mise en page en mode plein écran lorsque le clavier logiciel est visible

appelez cela onCreate()après setContentView()dans votre activité.

AndroidBug5497Workaround.assistActivity(this);

un peu différent de l'original remplacer return (r.bottom - r.top);par return r.bottom;encomputeUsableHeight()

pour une raison quelconque, je dois définir mon fitsSystemWindowsattribut d' activité sur false.

cette solution de contournement m'a sauvé. ça marche bien pour moi. l'espoir peut vous aider.

la classe d'implémentation est:

public class AndroidBug5497Workaround {

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

}
Loyea
la source
2

Cela ne devrait pas fonctionner avec la barre d'état translucide; ce paramètre force la fenêtre en mode plein écran qui ne fonctionne pas avec AdjustResize.

Vous pouvez utiliser AdjustPan ou utiliser les propriétés fitsSystemWindows. Je suggérerais cependant de lire sur la fonctionnalité, elle a des effets secondaires importants:

https://medium.com/google-developers/why-would-i-want-to-fitssystemwindows-4e26d9ce1eec

RESTfulGeoffrey
la source
0

AndroidBug5497Workaround.java prend soin de la fuite de mémoire. besoin de code ci-dessous

getViewTreeObserver().removeOnGlobalLayoutListener(listener);

Mon exemple utilisant RxJava qui appelle automatiquement removeOnGlobalLayoutListener () lorsque onPause () dans le cycle de vie de l'activité

public class MyActivity extends RxAppCompatActivity {
    // ...

protected void onStart(){
    super.onStart();

        TRSoftKeyboardVisibility
            .changes(this) // activity
            .compose(this.<TRSoftKeyboardVisibility.ChangeEvent>bindUntilEvent(ActivityEvent.PAUSE))
            .subscribe(keyboardEvent -> {
                FrameLayout content = (FrameLayout) findViewById(android.R.id.content);
                View firstChildView = content.getChildAt(0);
                firstChildView.getLayoutParams().height = keyboardEvent.viewHeight();
                firstChildView.requestLayout();

                // keyboardEvent.isVisible      = keyboard visible or not
                // keyboardEvent.keyboardHeight = keyboard height
                // keyboardEvent.viewHeight     = fullWindowHeight - keyboardHeight
            });
   //...
}





package commonlib.rxjava.keyboard;

import android.app.Activity;
import android.view.View;
import android.widget.FrameLayout;
import kr.ohlab.android.util.Assert;
import rx.Observable;

public class TRSoftKeyboardVisibility {

    public static Observable<ChangeEvent> changes(Activity activity) {
        Assert.notNull(activity, "activity == null");
        FrameLayout content = (FrameLayout) activity.findViewById(android.R.id.content);
        View childOfContent = content.getChildAt(0);
        return Observable.create(
            new TRSoftKeyboardVisibilityEventOnSubscribe(childOfContent));
    }

    public static final class ChangeEvent {
        private final int keyboardHeight;
        private final boolean visible;
        private final int viewHeight;

        public static ChangeEvent create(boolean visible, int keyboardHeight,
            int windowDisplayHeight) {
            return new ChangeEvent(visible, keyboardHeight, windowDisplayHeight);
        }

        private ChangeEvent(boolean visible, int keyboardHeight, int viewHeight) {
            this.keyboardHeight = keyboardHeight;
            this.visible = visible;
            this.viewHeight = viewHeight;
        }

        public int keyboardHeight() {
            return keyboardHeight;
        }

        public boolean isVisible() {
            return this.visible;
        }

        public int viewHeight() {
            return viewHeight;
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (!(o instanceof ChangeEvent)) return false;

            ChangeEvent that = (ChangeEvent) o;

            if (keyboardHeight != that.keyboardHeight) return false;
            if (visible != that.visible) return false;
            return viewHeight == that.viewHeight;
        }

        @Override
        public int hashCode() {
            int result = keyboardHeight;
            result = 31 * result + (visible ? 1 : 0);
            result = 31 * result + viewHeight;
            return result;
        }

        @Override
        public String toString() {
            return "ChangeEvent{" +
                "keyboardHeight=" + keyboardHeight +
                ", visible=" + visible +
                ", viewHeight=" + viewHeight +
                '}';
        }
    }
}


package commonlib.rxjava.keyboard;

import android.graphics.Rect;
import android.view.View;
import android.view.ViewTreeObserver;
import kr.ohlab.android.util.Assert;
import rx.Observable;
import rx.Subscriber;
import rx.android.MainThreadSubscription;
import timber.log.Timber;

public class TRSoftKeyboardVisibilityEventOnSubscribe
    implements Observable.OnSubscribe<TRSoftKeyboardVisibility.ChangeEvent> {
    private final View mTopView;
    private int mLastVisibleDecorViewHeight;
    private final Rect mWindowVisibleDisplayFrame = new Rect();

    public TRSoftKeyboardVisibilityEventOnSubscribe(View topView) {
        mTopView = topView;
    }

    private int computeWindowFrameHeight() {
        mTopView.getWindowVisibleDisplayFrame(mWindowVisibleDisplayFrame);
        return (mWindowVisibleDisplayFrame.bottom - mWindowVisibleDisplayFrame.top);
    }

    private TRSoftKeyboardVisibility.ChangeEvent checkKeyboardVisibility() {
        int windowFrameHeightNow = computeWindowFrameHeight();
        TRSoftKeyboardVisibility.ChangeEvent event = null;
        if (windowFrameHeightNow != mLastVisibleDecorViewHeight) {
            int mTopViewHeight = mTopView.getHeight();
            int heightDiff = mTopViewHeight - windowFrameHeightNow;
            Timber.e("XXX heightDiff=" + heightDiff);
            if (heightDiff > (mTopViewHeight / 4)) {
                event = TRSoftKeyboardVisibility.ChangeEvent.create(true, heightDiff, windowFrameHeightNow);
            } else {
                event = TRSoftKeyboardVisibility.ChangeEvent.create(false, 0, windowFrameHeightNow);
            }
            mLastVisibleDecorViewHeight = windowFrameHeightNow;
            return event;
        }

        return null;
    }

    public void call(final Subscriber<? super TRSoftKeyboardVisibility.ChangeEvent> subscriber) {
        Assert.checkUiThread();

        final ViewTreeObserver.OnGlobalLayoutListener listener =
            new ViewTreeObserver.OnGlobalLayoutListener() {
                @Override
                public void onGlobalLayout() {
                    TRSoftKeyboardVisibility.ChangeEvent event = checkKeyboardVisibility();
                    if( event == null)
                        return;
                    if (!subscriber.isUnsubscribed()) {
                        subscriber.onNext(event);
                    }
                }
            };

        mTopView.getViewTreeObserver().addOnGlobalLayoutListener(listener);

        subscriber.add(new MainThreadSubscription() {
            @Override
            protected void onUnsubscribe() {
                mTopView.getViewTreeObserver().removeOnGlobalLayoutListener(listener);
            }
        });
    }
}
ohlab
la source
0

J'ai eu comme un problème.

J'ai défini windowDrawsSystemBarBackgrounds sur «true» et mon application devrait s'afficher sous la barre d'état.

C'est mon thème d'activité.

<item name="android:windowTranslucentStatus" tools:targetApi="KITKAT">false</item>
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
<item name="android:windowTranslucentNavigation">true</item>
<item name="android:statusBarColor">@android:color/transparent</item>

et j'ai obtenu de l'aide du blog de jianshu . vous pouvez lire du code mais du texte comme moi. J'ajoute encore quelques codes.

public final class ZeroInsetsFrameLayout extends FrameLayout {
    private int[] mInsets = new int[4];

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

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

    public ZeroInsetsFrameLayout(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    public final int[] getInsets() {
        return mInsets;
    }

    @Override
    public WindowInsets computeSystemWindowInsets(WindowInsets in, Rect outLocalInsets) {
        outLocalInsets.left = 0;
        outLocalInsets.top = 0;
        outLocalInsets.right = 0;

        return super.computeSystemWindowInsets(in, outLocalInsets);
    }

    @Override
    protected final boolean fitSystemWindows(@NonNull Rect insets) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            // Intentionally do not modify the bottom inset. For some reason,
            // if the bottom inset is modified, window resizing stops working.
            // TODO: Figure out why.

            mInsets[0] = insets.left;
            mInsets[1] = insets.top;
            mInsets[2] = insets.right;

            insets.left = 0;
            insets.top = 0;
            insets.right = 0;
        }

        return super.fitSystemWindows(insets);
    }
}

Ceci est ma mise en page de fragment.

<com.dhna.widget.ZeroInsetsFrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    android:background="@color/white">

    <!-- your xml code -->

</ZeroInsetsFrameLayout>

Je veux que cela vous soit utile. bonne chance!

Hogun
la source
Il faut du temps pour masquer et afficher le clavier et il faut aussi du temps pour pousser la mise en page vers le haut. Toute solution ? Comment gérer ?
Vanjara Sweta le
0
  • Après avoir fait des recherches sur tous les forums. ces moyens ne peuvent pas aider à trouver le point. Chanceux quand j'ai essayé de faire de cette façon. Cela m'aide à résoudre le problème

XML

<RelativeLayout 
      xmlns:android="http://schemas.android.com/apk/res/android"
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      android:fitsSystemWindows="true">
       <!-- Your xml -->
    </RelativeLayout>

Activité

@Override
protected void onCreate(Bundle savedInstanceState) {
   super.onCreate(savedInstanceState);
   setContentView("Your Activity");
   setAdjustScreen();

}

Créé Func

protected void setAdjustScreen(){
        getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
        getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
        /*android:windowSoftInputMode="adjustPan|adjustResize"*/
}

Enfin ajouter quelques lignes à votre mainifest

 <activity
     android:name="Your Activity"
     android:windowSoftInputMode="adjustPan|adjustResize"
     android:screenOrientation="portrait"></activity>
Trần Thanh Phong
la source
0

J'ai eu le même problème. J'ai résolu en utilisant coordinatorlayout

activity.main.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
    android:layout_height="match_parent" android:layout_width="match_parent"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:android="http://schemas.android.com/apk/res/android">


    <android.support.design.widget.AppBarLayout
    android:layout_height="wrap_content"
    android:layout_width="match_parent"
    android:theme="@style/AppTheme.AppBarOverlay">

    <android.support.v7.widget.Toolbar
        android:layout_height="?attr/actionBarSize"
        android:layout_width="match_parent"
        app:popupTheme="@style/AppTheme.PopupOverlay"
        android:background="?attr/colorPrimary"
        android:id="@+id/toolbar"/>

</android.support.design.widget.AppBarLayout>

    <include layout="@layout/content_main2"/>

</android.support.design.widget.CoordinatorLayout>

content_main2.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto">


    <android.support.v7.widget.RecyclerView
        android:layout_height="match_parent"
        android:layout_width="match_parent"
        android:layout_marginTop="30dp"
        android:layout_marginBottom="30dp"
        app:layout_scrollFlags="scroll|exitUntilCollapsed"
        android:id="@+id/post_msg_recyclerview">
    </android.support.v7.widget.RecyclerView>

    <EditText
        android:layout_width="match_parent"
        android:layout_height="50dp"
        app:layout_constraintBottom_toBottomOf="parent"
        android:background="@color/colorPrimary"


        />

</android.support.constraint.ConstraintLayout>

MainActivity.java

ajoutez maintenant cette ligne linearLayoutManager.setStackFromEnd (true);

 LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
        linearLayoutManager.setStackFromEnd(true);
        recyclerView.setLayoutManager(linearLayoutManager);
        Adapter adapter1=new Adapter(arrayList);
        recyclerView.setAdapter(adapter1);
gaurav gupta
la source
0
<androidx.constraintlayout.widget.ConstraintLayout
  android:fitsSystemWindows="true">

  <androidx.coordinatorlayout.widget.CoordinatorLayout>
    <com.google.android.material.appbar.AppBarLayout>

      <com.google.android.material.appbar.CollapsingToolbarLayout/>

    </com.google.android.material.appbar.AppBarLayout>

    <androidx.core.widget.NestedScrollView>
    <Editext/>
    <androidx.core.widget.NestedScrollView/>

  </androidx.coordinatorlayout.widget.CoordinatorLayout>

</androidx.constraintlayout.widget.ConstraintLayout>
Shehan Gamage
la source
0

Ajoutez-le d'abord à votre disposition racine.

android:fitsSystemWindows="true"

Lorsque vous utilisez cette approche, il devient de votre responsabilité de vous assurer que les parties critiques de l'interface utilisateur de votre application (par exemple, les contrôles intégrés dans une application Maps) ne finissent pas par être couvertes par des barres système. Cela pourrait rendre votre application inutilisable. Dans la plupart des cas, vous pouvez gérer cela en ajoutant l'attribut android: fitsSystemWindows à votre fichier de mise en page XML, défini sur true. Cela ajuste le remplissage du ViewGroup parent pour laisser de l'espace pour les fenêtres système. Cela suffit pour la plupart des applications.

Dans certains cas, cependant, vous devrez peut-être modifier le remplissage par défaut pour obtenir la mise en page souhaitée pour votre application. Pour manipuler directement la disposition de votre contenu par rapport aux barres système (qui occupent un espace appelé «encarts de contenu» de la fenêtre), remplacez fitSystemWindows (encarts Rect). La méthode fitSystemWindows () est appelée par la hiérarchie des vues lorsque les encarts de contenu d'une fenêtre ont changé, pour permettre à la fenêtre d'ajuster son contenu en conséquence. En remplaçant cette méthode, vous pouvez gérer les inserts (et donc la mise en page de votre application) comme vous le souhaitez.

https://developer.android.com/training/system-ui/status#behind

Si vous souhaitez devenir un maître monteur de fenêtres, veuillez regarder la vidéo du développeur Android. https://www.youtube.com/watch?v=_mGDMVRO3iE

xiaoyuan hu
la source
-1

La meilleure pratique permet à l'utilisateur de faire défiler le contenu lorsque le clavier est affiché. Donc, pour ajouter cette fonctionnalité, vous devez placer votre disposition racine dans la méthode d'activité ScrollViewet utiliser windowSoftInputMode="adjustResize".

Mais si vous souhaitez utiliser cette fonctionnalité avec un <item name="android:windowTranslucentStatus">true</item> indicateur sur le contenu d'Android 5, le contenu ne pourra pas faire défiler et chevauchera le clavier.

Pour résoudre ce problème, cochez cette réponse

Mandrin
la source