windowSoftInputMode = "adjustResize" funktioniert nicht mit durchscheinender Aktion / Navigationsleiste

129

Ich habe Probleme mit der durchscheinenden Actionbar / Navbar im neuen Android KitKat (4.4) und dem windowSoftInputMode="adjustResize".

Wenn Sie den InputMode normalerweise auf adjustResize ändern, sollte sich die Größe der App ändern, wenn die Tastatur angezeigt wird ... aber hier nicht! Wenn ich die Linien für den transparenten Effekt lösche, funktioniert die Größenänderung.

Wenn also die Tastatur sichtbar ist, befindet sich meine ListView darunter und ich kann nicht auf die letzten Elemente zugreifen. (Nur durch manuelles Ausblenden der Tastatur)

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>

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

Irgendwelche Ideen, um das zu beheben?

fabianbru
quelle

Antworten:

184

Ihnen fehlt die folgende Eigenschaft:

android:fitsSystemWindows="true"

im Stammverzeichnis RelativeLayoutdes XML-Layouts des Fragments .

Aktualisieren:

Letztes Jahr gab es einen interessanten Vortrag von Chris Bane, der ausführlich erklärt, wie das funktioniert:

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

Pablisco
quelle
5
Ich denke, es ist etwas mit Vollbild-Richtlinien
Felix.D
1
Du bist der Mann! Ich habe dieses Problem nur in der Lollipop-Version erlebt und es hat es behoben.
David
6
@ David Es ist noch nicht behoben, bricht immer noch in Marshmallow-Gerät, wenn Sie einen Dialog öffnen und versuchen zu scrollen, dann blockiert Softkeboard das Scrollen
Bytecode
5
Es funktioniert, aber Konflikt mit meiner Symbolleiste und Statusleiste Anpassung
Ninja
2
funktioniert, aber dann ist die Statusleiste nicht mehr durchscheinend. Ich möchte, dass das Layout den gesamten Bildschirm abdeckt.
Htafoya
34

Es gibt eine ähnliche Fehlerbericht hier . Ich habe eine Problemumgehung gefunden, die nach begrenzten Tests den Trick ohne Auswirkungen zu tun scheint. Fügen Sie mit der folgenden Logik eine benutzerdefinierte Implementierung Ihres Stamms hinzu ViewGroup(die ich fast immer verwende FrameLayout, also habe ich dies getestet). Verwenden Sie dann dieses benutzerdefinierte Layout anstelle Ihres Root-Layouts und stellen Sie sicher, dass Sie es festlegen android:fitsSystemWindows="true". Sie können dann getInsets()jederzeit nach dem Layout aufrufen (z. B. ein hinzufügen OnPreDrawListener), um den Rest Ihres Layouts anzupassen und gegebenenfalls die Systemeinfügungen zu berücksichtigen.

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

Da fitSystemWindows veraltet ist, lesen Sie bitte die Antwort unten, um die Problemumgehung abzuschließen.

Kevin Coppock
quelle
1
Tatsächlich scheint SOFT_INPUT_ADJUST_PAN meiner Erfahrung nach NICHT ignoriert zu werden - es bewegt den gesamten Bildschirm nach oben, einschließlich der Systemleiste und der Umschalttastatur in der fokussierten Ansicht.
Sealskej
Danke - Sie haben Recht mit dem SOFT_INPUT_ADJUST_PAN. Ich habe dies in meinem Fragment verwendet: getActivity (). GetWindow (). SetSoftInputMode (WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
Simon
Nur so konnte ich eine Anpassung von Größe für Aktivität (erforderlich für das Scrollen der Ansicht beim Anzeigen der Tastatur) erreichen. FitSystemWindows wurde auf true gesetzt, sodass der Bildlauf tatsächlich auf> = Lollipop erfolgt und eine durchscheinende Statusleiste hat. Vielen Dank.
Lucas
Dies ist die eigentliche Lösung
Martyglaubitz
Es braucht Zeit, um die Tastatur ein- und auszublenden, auch wenn es Zeit braucht, das Layout nach oben zu verschieben. Irgendeine Lösung ?
Vanjara Sweta
28

Die Antwort von @kcoppock ist wirklich hilfreich, aber fitSystemWindows wurde in API-Level 20 nicht mehr unterstützt

Seit API 20 (KITKAT_WATCH) sollten Sie also onApplyWindowInsets überschreiben

@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
quelle
In welcher Klasse sollten wir das überschreiben?
Ben-J
@ Ben-J in einer Klasse, die die ursprüngliche Klasse erweitert
Victor91
Ich habe keine Ahnung, warum Sie mInsets-Array-Elemente festlegen, während es nicht verwendet wird, aber es funktioniert
Buckstabue
1
Anstelle Ihrer Versionsprüfung können Sie verwendenViewCompat.setOnApplyWindowInsetsListener
repitch
Ich konnte das nicht zum Laufen bringen, aber dispatchApplyWindowInsetsstattdessen hat das Überschreiben (der gleiche Code) für mich funktioniert
petter
11

Dies funktionierte für mich, um eine durchscheinende Statusleiste zu haben und die Größe in Fragment anzupassen:

  1. Erstellen Sie ein benutzerdefiniertes RelativeLayout, wie @ Victor91 und @kcoppock sagten.

  2. Verwenden Sie CustomRelativeLayout als übergeordnetes Layout für Ihr Fragment.

  3. Deklariere Thema mit Android: windowTranslucentStatus = true

  4. Die Containeraktivität muss im Manifest mit android: windowSoftInputMode = "adjustResize" deklariert werden und das deklarierte Thema verwenden

  5. Bitte verwenden Sie fitSystemWindows für das Fragment-Root-Layout!

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

Dann in 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>
Ihr Mann
quelle
1
Dies ist die bisher beste Antwort, und ich suche jetzt nach einer Lösung. Es funktioniert einwandfrei, aber Sie müssen Ihrer Symbolleiste zusätzliche Polster hinzufügen, ohne diese überlappt Ihre Symbolleiste die Statusleiste
Paulina
Was ist mit windowTranslucentNavigation? Kannst du dabei helfen?
V-rund Puro-Hit
10

Wenn Sie die Einfügungen anpassen möchten und auf API-Ebene> = 21 abzielen, können Sie dies erreichen, ohne eine benutzerdefinierte Ansichtsgruppe erstellen zu müssen. Durch fitsSystemWindowseinfaches Einstellen wird das Auffüllen standardmäßig auf Ihre Containeransicht angewendet, was Sie möglicherweise nicht möchten.

Die Versionsprüfungen sind in diese Methode integriert und nur Geräte> = 21 führen den Code im Lambda aus. Kotlin Beispiel:

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

Stellen Sie sicher, dass Ihr Layout weiterhin das fitsSystemWindowsFlag setzt, da sonst der Listener für Fenstereinfügungen nicht aufgerufen wird.

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

Diese Quellen sind hilfreich:

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

Victor Rendina
quelle
1
Dies bleibt immer noch der beste Ansatz, da Sie dies BaseFragmentzusammen mit anwenden können view.fitsSystemWindows = trueund es nur ohne Änderungen an den tatsächlichen XML-Layouts oder View-Unterklassen funktioniert.
Bogdan Zurac
5

Ich hatte das gleiche Problem: Meine Aktivität hatte eine ScrollView als Stammansicht und bei aktivierter durchscheinender Statusleiste wurde die Größe nicht korrekt geändert, wenn die Tastatur angezeigt wurde ... und der Bildschirm wurde nicht gescrollt, um die Eingabeansichten auszublenden.

Lösung: Alles (Layout und Aktivitätslogik) wurde in ein neues Fragment verschoben. Dann wurde die Aktivität so geändert, dass nur dieses Fragment enthalten ist. Jetzt funktioniert alles wie erwartet!

Dies ist das Layout der Aktivität:

<?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
quelle
Funktioniert wie ein Zauber für mich
imike
2

Basierend auf Joseph Johnsons Problemumgehung in Android So passen Sie das Layout im Vollbildmodus an, wenn das Softkeyboard sichtbar ist

Rufen Sie dies onCreate()nachher setContentView()in Ihrer Aktivität an.

AndroidBug5497Workaround.assistActivity(this);

ein litte kann von Original abweichen ersetzen return (r.bottom - r.top);mit return r.bottom;incomputeUsableHeight()

Aus irgendeinem Grund muss ich mein Aktivitätsattribut fitsSystemWindowsauf setzen false.

Diese Problemumgehung hat mich gerettet. es funktioniert gut für mich. Hoffnung kann dir helfen.

Die Implementierungsklasse ist:

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

Es sollte nicht mit der durchscheinenden Statusleiste funktionieren. Diese Einstellung zwingt das Fenster in den Vollbildmodus, der mit adjustResize nicht funktioniert.

Sie können entweder adjustPan oder die Eigenschaften fitsSystemWindows verwenden. Ich würde jedoch empfehlen, über das Feature zu lesen, es hat erhebliche Nebenwirkungen:

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

RESTfulGeoffrey
quelle
0

AndroidBug5497Workaround.java sorgen für Speicherverlust. brauche unten Code

getViewTreeObserver().removeOnGlobalLayoutListener(listener);

Mein Beispiel mit RxJava, das bei onPause () im Lebenszyklus von Activity automatisch removeOnGlobalLayoutListener () aufruft

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

Ich hatte gerne ein Problem.

Ich habe windowDrawsSystemBarBackgrounds auf 'true' gesetzt und meine App sollte in der Statusleiste angezeigt werden.

Es ist mein Aktivitätsthema.

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

und ich bekam Hilfe von Jianshus Blog . Sie können Code lesen, aber Text wie ich. Ich füge ein paar weitere Codes hinzu.

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

Dies ist mein Fragment-Layout.

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

Ich möchte, dass es Ihnen hilfreich ist. Viel Glück!

Hogun
quelle
Es braucht Zeit, um die Tastatur auszublenden und anzuzeigen, und es braucht Zeit, um das Layout nach oben zu verschieben. Irgendeine Lösung ? Wie man verwaltet ?
Vanjara Sweta
0
  • Nachdem ich in allen Foren recherchiert hatte. Diese Wege können nicht helfen, darauf hinzuweisen. Glück, als ich es so versuchte. Es hilft mir, das Problem zu lösen

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>

Aktivität

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

}

Erstellt Func

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

Fügen Sie Ihrem Mainifest schließlich einige Zeilen hinzu

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

Ich hatte das gleiche Problem. Ich habe mit Koordinatorlayout gelöst

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

Fügen Sie nun diese Zeile hinzu. linearLayoutManager.setStackFromEnd (true);

 LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
        linearLayoutManager.setStackFromEnd(true);
        recyclerView.setLayoutManager(linearLayoutManager);
        Adapter adapter1=new Adapter(arrayList);
        recyclerView.setAdapter(adapter1);
Gaurav Gupta
quelle
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
quelle
0

Fügen Sie dies zuerst in Ihrem Root-Layout hinzu.

android:fitsSystemWindows="true"

Wenn Sie diesen Ansatz verwenden, müssen Sie sicherstellen, dass wichtige Teile der Benutzeroberfläche Ihrer App (z. B. die in einer Maps-Anwendung integrierten Steuerelemente) nicht von Systemleisten abgedeckt werden. Dies könnte Ihre App unbrauchbar machen. In den meisten Fällen können Sie dies tun, indem Sie das Attribut android: fitSystemWindows zu Ihrer XML-Layoutdatei hinzufügen, das auf true festgelegt ist. Dadurch wird der Abstand der übergeordneten ViewGroup angepasst, um Platz für die Systemfenster zu lassen. Dies ist für die meisten Anwendungen ausreichend.

In einigen Fällen müssen Sie jedoch möglicherweise die Standardauffüllung ändern, um das gewünschte Layout für Ihre App zu erhalten. Überschreiben Sie fitSystemWindows (Rect-Einfügungen), um direkt zu steuern, wie Ihr Inhalt relativ zu den Systemleisten angeordnet ist (die einen Bereich einnehmen, der als "Inhaltseinfügungen" des Fensters bezeichnet wird). Die Methode fitSystemWindows () wird von der Ansichtshierarchie aufgerufen, wenn sich die Inhaltseinfügungen für ein Fenster geändert haben, damit das Fenster seinen Inhalt entsprechend anpassen kann. Durch Überschreiben dieser Methode können Sie die Einfügungen (und damit das Layout Ihrer App) beliebig behandeln.

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

Wenn Sie ein Master-Fensterbauer werden möchten, schauen Sie sich bitte das Video des Android-Entwicklers an. https://www.youtube.com/watch?v=_mGDMVRO3iE

Xiaoyuan Hu
quelle
-1

Die bewährte Methode ermöglicht dem Benutzer das Scrollen von Inhalten, wenn die Tastatur angezeigt wird. Um diese Funktionalität hinzuzufügen, müssen Sie Ihr Root-Layout in die Aktivitätsmethode einfügen ScrollViewund diese verwenden windowSoftInputMode="adjustResize".

Wenn Sie diese Funktion jedoch mit <item name="android:windowTranslucentStatus">true</item> Flag für Android 5-Inhalte verwenden möchten, können Sie nicht scrollen und überschneiden sich mit der Tastatur.

Überprüfen Sie diese Antwort, um dieses Problem zu beheben

Futter
quelle