So passen Sie das Layout an, wenn eine weiche Tastatur angezeigt wird

173

Ich möchte das Layout bei aktivierter Softtastatur wie folgt anpassen / neu dimensionieren:

Vorher und nachher:

Geben Sie hier die Bildbeschreibung einGeben Sie hier die Bildbeschreibung ein


Einige Ressourcen in SO gefunden:

  1. So halten Sie alle Felder und Texte sichtbar, während die Softtastatur angezeigt wird
  2. Android Soft Keyboard verdirbt Layout, wenn erscheint
  3. Passen Sie das Layout an, wenn die Softtastatur aktiviert ist

Aber die Fragen und Antworten sind ziemlich zweideutig, hier ist die Frage mit einem klareren Bild von dem, was ich will.

Bedarf:

  • Es sollte auf Telefonen mit beliebigen Bildschirmgrößen funktionieren.
  • Es wurde festgestellt, dass sich der Rand- / Auffüllbereich bei "FACEBOOK" und "Für Facebook anmelden" vorher und nachher geändert hat.
  • Es ist keine Bildlaufansicht beteiligt.
Roy Lee
quelle
3
Beachten Sie auch, dass die Größenänderung im Vollbildmodus ( Theme.AppCompat.Light.NoActionBar.FullScreen) gemäß dieser Antwort nicht funktioniert -> stackoverflow.com/a/7509285/1307690
Roman Nazarevych

Antworten:

214

Einfach hinzufügen

android:windowSoftInputMode="adjustResize"

In Ihrer AndroidManifest.xml, in der Sie diese bestimmte Aktivität deklarieren, wird die Option zum Ändern der Layoutgröße angepasst.

Geben Sie hier die Bildbeschreibung ein

Einige Quellcodes unten für das Layout-Design

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

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="20dp"
        android:text="FaceBook"
        android:textAppearance="?android:attr/textAppearanceLarge" />

    <EditText
        android:id="@+id/editText1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/textView1"
        android:layout_marginTop="30dp"
        android:ems="10"
        android:hint="username" >

        <requestFocus />
    </EditText>

    <EditText
        android:id="@+id/editText2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/editText1"
        android:layout_marginTop="20dp"
        android:ems="10"
        android:hint="password" />

    <Button
        android:id="@+id/button1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/editText2"
        android:layout_centerHorizontal="true"
        android:layout_marginLeft="18dp"
        android:layout_marginTop="20dp"
        android:text="Log In" />

    <TextView
        android:id="@+id/textView2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_marginTop="17dp"
        android:gravity="center"
        android:text="Sign up for facebook"
        android:textAppearance="?android:attr/textAppearanceLarge" />

</RelativeLayout>
Venkatesh S.
quelle
2
+1 So einfach? Irgendwelche zusätzlichen Bedingungen? Was war das Bild, über das du gepostet hast?
Roy Lee
2
Freunde nur um alignparentbottom = "true" zu zeigen, wenn der Bildschirm nicht richtig eingestellt wurde. Dann platzierte ich diesen Bildfreund
Venkatesh S
Sehr gute Antwort. Danke für die Hilfe, Kumpel. Ich bin froh, dass du gekommen bist.
Roy Lee
9
Freund es scheint, dass sich nur die Textansicht mit "Für Facebook anmelden" selbst anpasste, wenn das Softkeyboard aktiviert wurde, andere bleiben unverändert. Ich hoffe, dass sich auch andere anpassen können. Irgendeine Problemumgehung? Und das gesamte Layout sollte in der Mitte sein, bevor die Tastatur aktiviert wurde
Roy Lee
1
Gibt es eine Möglichkeit, zusätzliche Polsterung zu geben, wenn die Größe angepasst wird? Derzeit wird die Größe so geändert, dass der untere Rand des Textcursors genau am unteren Bildschirmrand ausgerichtet ist. Ich möchte eine zusätzliche Lücke von 5 dp unter dem Textcursor sichtbar haben.
Noitidart
42

Diese Frage wurde vor einigen Jahren gestellt und "Secret Andro Geni" hat eine gute Basiserklärung und "tir38" hat auch einen guten Versuch unternommen, die vollständige Lösung zu finden, aber leider gibt es hier keine vollständige Lösung. Ich habe ein paar Stunden damit verbracht, Dinge herauszufinden, und hier ist meine vollständige Lösung mit einer detaillierten Erklärung unten:

<?xml version="1.0" encoding="utf-8"?>
<ScrollView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fillViewport="true">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="10dp">

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_above="@+id/mainLayout"
            android:layout_alignParentTop="true"
            android:id="@+id/headerLayout">

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_centerVertical="true"
                android:gravity="center_horizontal">

                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:id="@+id/textView1"
                    android:text="facebook"
                    android:textStyle="bold"
                    android:ellipsize="marquee"
                    android:singleLine="true"
                    android:textAppearance="?android:attr/textAppearanceLarge" />

            </LinearLayout>

        </RelativeLayout>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_centerVertical="true"
            android:id="@+id/mainLayout"
            android:orientation="vertical">

            <EditText
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:id="@+id/editText1"
                android:ems="10"
                android:hint="Email or Phone"
                android:inputType="textVisiblePassword">

                <requestFocus />
            </EditText>

            <EditText
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginTop="10dp"
                android:id="@+id/editText2"
                android:ems="10"
                android:hint="Password"
                android:inputType="textPassword" />

            <Button
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginTop="10dp"
                android:id="@+id/button1"
                android:text="Log In"
                android:onClick="login" />

        </LinearLayout>

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:layout_below="@+id/mainLayout"
            android:id="@+id/footerLayout">

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_alignParentBottom="true">

                <RelativeLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content">

                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:id="@+id/textView2"
                        android:text="Sign Up for Facebook"
                        android:layout_centerHorizontal="true"
                        android:layout_alignBottom="@+id/helpButton"
                        android:ellipsize="marquee"
                        android:singleLine="true"
                        android:textAppearance="?android:attr/textAppearanceSmall" />

                    <Button
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_alignParentRight="true"
                        android:id="@+id/helpButton"
                        android:text="\?"
                        android:onClick="help" />

                </RelativeLayout>

            </LinearLayout>

        </RelativeLayout>

    </RelativeLayout>

</ScrollView>

Vergessen Sie in AndroidManifest.xml nicht, Folgendes festzulegen :

android:windowSoftInputMode="adjustResize"

auf dem <activity>Tag, dass Sie ein solches Layout möchten.

Gedanken:

Ich habe festgestellt, dass dies RelativeLayoutdie Layouts sind, die sich über den gesamten verfügbaren Speicherplatz erstrecken und deren Größe dann geändert wird, wenn die Tastatur angezeigt wird.

Und LinearLayoutsind Layouts, deren Größe beim Größenänderungsprozess nicht geändert wird.

Aus diesem Grund benötigen Sie RelativeLayoutunmittelbar danach 1 ScrollView, um den gesamten verfügbaren Bildschirmbereich zu durchlaufen. Und Sie müssen ein LinearLayoutInneres haben, RelativeLayoutsonst würde Ihr Inneres zerquetscht, wenn die Größenänderung erfolgt. Gutes Beispiel ist "headerLayout". Wenn es kein LinearLayoutInneres gäbe, würde dieser RelativeLayout"Facebook" -Text zerquetscht und nicht angezeigt werden.

In den in der Frage geposteten "Facebook" -Login-Bildern ist mir auch aufgefallen, dass der gesamte Login-Teil (mainLayout) in Bezug auf den gesamten Bildschirm vertikal zentriert ist, daher das Attribut:

android:layout_centerVertical="true"

auf dem LinearLayoutLayout. Und da sich mainLayout in a befindet, LinearLayoutbedeutet dies, dass die Größe dieses Teils nicht geändert wird (siehe Bild in Frage).

Yani2000
quelle
1
Klappt wunderbar!! Die Fußzeile bleibt jedoch am unteren Rand des Layouts hängen, was nicht gut aussieht. Wie kann ich vermeiden, dass die Fußzeile unten bleibt? stattdessen, wenn ich der Fußzeile einen gewissen Spielraum geben möchte, damit das Layout gut aussieht. Ich habe einige Änderungen vorgenommen, indem ich dem relativen Layout der Fußzeile das Attribut layout_margin gegeben habe, aber damit wird die letzte Hälfte des Textes bearbeiten abgedeckt. Bitte helfen Sie mir.
Tara
In RelativeLayout mit @ + id / footerLayout haben Sie ein LinearLayout mit dem folgenden Attribut : android:layout_alignParentBottom="true". Dadurch bleibt es am Boden haften.
Yani2000
ya, unter Berücksichtigung dessen, fragte ich Sie, wie Anordnungen der Fußzeilen-Komponenten, die unteren Rand mindestens 10dp oder 15dp haben sollten
Tara
Ich habe keine Ahnung, wovon du sprichst. Getestet habe ich mich gerade dies , indem sie android:layout_marginBottom="15dp"auf footerLayout und dann RelativeLayout , die hält textView2 und Helpbutton . In beiden Fällen wird helpButton zerstört (auch ohne das marginBottom-Attribut). In keiner Weise wird editText1 oder editText2 jemals zerstört, da sie sich in einem LinearLayout befinden . Haben Sie vielleicht einen Rand für ein anderes Layout festgelegt (nicht nur für footerLayout )? Versuchen Sie es von Grund auf neu, wenn Sie nicht weiterkommen! Sie können auch mit android:windowSoftInputModeAttributen in AndroidManifest spielen.
Yani2000
1
"Und LinearLayout sind Layouts, deren Größe beim Größenänderungsprozess nicht geändert wird." - Dies ist eine wirklich hilfreiche Information.
Zylon
28

Fügen Sie diese Zeile in Ihr Manifest ein, in der Ihre Aktivität aufgerufen wird

android:windowSoftInputMode="adjustPan|adjustResize"

oder

Sie können diese Zeile in Ihre hinzufügen onCreate

getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE|WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
Ashish Jaiswal
quelle
7
Sie sollten niemals beide adjustPanund verwenden adjustResize. Dies sind verschiedene Modi. Lesen Sie hier mehr darüber: stackoverflow.com/a/17410528/1738090 Und hier: developer.android.com/guide/topics/manifest/activity-element
w3bshark
19

Es kann für alle Arten von Layouts verwendet werden.

  1. Fügen Sie dies Ihrem Aktivitäts-Tag in AndroidManifest.xml hinzu

android: windowSoftInputMode = "adjustResize"

zum Beispiel:

<activity android:name=".ActivityLogin"
    android:screenOrientation="portrait"
    android:theme="@style/AppThemeTransparent"
    android:windowSoftInputMode="adjustResize"/>
  1. Fügen Sie dies zu Ihrem Layout-Tag in activitypage.xml hinzu , das seine Position ändert.

android: fitSystemWindows = "true"

und

android: layout_alignParentBottom = "true"

zum Beispiel:

<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:fitsSystemWindows="true">
user3725137
quelle
Diese Antwort bietet bessere Informationen darüber, wie ein Layout funktioniert.
Tim
14

Android Developer hat die richtige Antwort, aber der bereitgestellte Quellcode ist ziemlich ausführlich und implementiert das im Diagramm beschriebene Muster nicht.

Hier ist eine bessere Vorlage:

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:fillViewport="true">

    <RelativeLayout android:layout_width="match_parent"
                    android:layout_height="match_parent">

        <LinearLayout android:layout_width="match_parent"
                      android:layout_height="wrap_content"
                      android:orientation="vertical">

                <!-- stuff to scroll -->

        </LinearLayout>

        <FrameLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true">

            <!-- footer -->

        </FrameLayout>

    </RelativeLayout>

</ScrollView>

Es liegt an Ihnen, zu entscheiden, welche Ansichten Sie für die Teile "Scrollen" und "Fußzeile" verwenden. Beachten Sie auch, dass Sie wahrscheinlich den ScrollViews fillViewPort festlegen müssen .

tir38
quelle
Es wurde versucht, Ihrer Lösung zu folgen, aber zwei LinearLayouts anstelle von Frame und Relative zu verwenden, aber alle Ansichten liegen immer noch übereinander.
Henrique de Sousa
9

Auf diese Weise können Sie jedes gewünschte Layout anzeigen, das zuvor von der Tastatur ausgeblendet wurde.

Fügen Sie dies dem Aktivitäts-Tag in AndroidManifest.xml hinzu

android: windowSoftInputMode = "adjustResize"


Umgeben Sie Ihre Stammansicht mit einer ScrollView, vorzugsweise mit Bildlaufleisten = keine. Die ScrollView ändert nichts an Ihrem Layout, außer um dieses Problem zu lösen.

Setzen Sie dann fitSystemWindows = "true" für die Ansicht, die Sie vollständig über der Tastatur anzeigen möchten. Dadurch wird Ihr EditText über der Tastatur sichtbar und Sie können zu den Teilen unter dem EditText scrollen, jedoch in der Ansicht mit fitSystemWindows = "true".

android: fitSystemWindows = "true"

Zum Beispiel:

<ScrollView
    android:id="@+id/scrollView"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:scrollbars="none">

    <android.support.constraint.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:fitsSystemWindows="true">

        ...

    </android.support.constraint.ConstraintLayout>
</ScrollView>   

Wenn Sie den gesamten Teil der Ansicht "fitsSystemWindows =" true "über der Tastatur anzeigen möchten, sobald die Tastatur angezeigt wird, benötigen Sie Code, um die Ansicht nach unten zu scrollen:

// Code is in Kotlin

setupKeyboardListener(scrollView) // call in OnCreate or similar


private fun setupKeyboardListener(view: View) {
    view.viewTreeObserver.addOnGlobalLayoutListener {
        val r = Rect()
        view.getWindowVisibleDisplayFrame(r)
        if (Math.abs(view.rootView.height - (r.bottom - r.top)) > 100) { // if more than 100 pixels, its probably a keyboard...
            onKeyboardShow()
        }
    }
}

private fun onKeyboardShow() {
    scrollView.scrollToBottomWithoutFocusChange()
}

fun ScrollView.scrollToBottomWithoutFocusChange() { // Kotlin extension to scrollView
    val lastChild = getChildAt(childCount - 1)
    val bottom = lastChild.bottom + paddingBottom
    val delta = bottom - (scrollY + height)
    smoothScrollBy(0, delta)
}

Vollständiges Layoutbeispiel:

<android.support.constraint.ConstraintLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:fitsSystemWindows="true">

    <RelativeLayout
        android:id="@+id/statisticsLayout"
        android:layout_width="match_parent"
        android:layout_height="340dp"
        android:background="@drawable/some"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <ImageView
            android:id="@+id/logoImageView"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="64dp"
            android:src="@drawable/some"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

    </RelativeLayout>

    <RelativeLayout
        android:id="@+id/authenticationLayout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginEnd="32dp"
        android:layout_marginStart="32dp"
        android:layout_marginTop="20dp"
        android:focusableInTouchMode="true"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@id/statisticsLayout">

        <android.support.design.widget.TextInputLayout
            android:id="@+id/usernameEditTextInputLayout"
            android:layout_width="match_parent"
            android:layout_height="68dp">

            <EditText
                android:id="@+id/usernameEditText"
                android:layout_width="match_parent"
                android:layout_height="wrap_content" />

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

        <android.support.design.widget.TextInputLayout
            android:id="@+id/passwordEditTextInputLayout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_below="@id/usernameEditTextInputLayout">

            <EditText
                android:id="@+id/passwordEditText"
                android:layout_width="match_parent"
                android:layout_height="wrap_content" />

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

        <Button
            android:id="@+id/loginButton"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@id/passwordEditTextInputLayout"
            android:layout_centerHorizontal="true"
            android:layout_marginBottom="10dp"
            android:layout_marginTop="20dp" />

        <Button
            android:id="@+id/forgotPasswordButton"
            android:layout_width="wrap_content"
            android:layout_height="40dp"
            android:layout_below="@id/loginButton"
            android:layout_centerHorizontal="true" />

    </RelativeLayout>

</android.support.constraint.ConstraintLayout>

Morten Holmgaard
quelle
Verwenden android:fitsSystemWindows="true"ist, was mir die gewünschten Ergebnisse gab, die ich wollte ... danke
CrandellWS
8

Für diejenigen, die ConstraintLayout verwenden , android:windowSoftInputMode="adjustPan|adjustResize"funktioniert dies nicht.

Sie können einen Soft-Tastatur-Listener verwenden , Einschränkungen für die Ansichten von unten nach unten in den oberen Ansichten festlegen und dann für jede Ansicht eine vertikale Abweichung (als Positionsprozentsatz zwischen Einschränkungen) für eine horizontale Richtlinie festlegen (ebenfalls prozentual positioniert) , aber an die Eltern).

Für jede Ansicht müssen wir nur programmgesteuert ändern app:layout_constraintBottom_toBottomOf, @+id/guidelinewann die Tastatur angezeigt wird.

        <ImageView
        android:id="@+id/loginLogo"
        ...
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.15" />


        <RelativeLayout
        android:id="@+id/loginFields"
        ...
        app:layout_constraintVertical_bias=".15"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/loginLogo">

        <Button
        android:id="@+id/login_btn"
        ...
        app:layout_constraintVertical_bias=".25"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/loginFields"/>

Im Allgemeinen nimmt eine Softtastatur nicht mehr als 50% der Bildschirmhöhe ein. Somit können Sie die Richtlinie auf 0,5 setzen.

        <android.support.constraint.Guideline
        android:id="@+id/guideline"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        app:layout_constraintGuide_percent="0.5"/>

Wenn die Tastatur jetzt programmgesteuert nicht angezeigt wird , können wir den gesamten app:layout_constraintBottom_toBottomOfRücken auf übergeordnet setzen, und umgekehrt.

            unregistrar = KeyboardVisibilityEvent.registerEventListener(this, isOpen -> {
            loginLayout.startAnimation(AnimationManager.getFade(200));
            if (isOpen) {
                setSoftKeyViewParams(loginLogo, R.id.guideline, ConstraintLayout.LayoutParams.PARENT_ID, -1, "235:64", 0.15f,
                        63, 0, 63, 0);
                setSoftKeyViewParams(loginFields, R.id.guideline, -1, R.id.loginLogo, null, 0.15f,
                        32, 0, 32, 0);
                setSoftKeyViewParams(loginBtn, R.id.guideline, -1, R.id.useFingerPrintIdText, null, 0.5f,
                        32, 0, 32, 0);
            } else {
                setSoftKeyViewParams(loginLogo, ConstraintLayout.LayoutParams.PARENT_ID, ConstraintLayout.LayoutParams.PARENT_ID, -1, "235:64", 0.15f,
                        63, 0, 63, 0);
                setSoftKeyViewParams(loginFields, ConstraintLayout.LayoutParams.PARENT_ID, -1, R.id.loginLogo,null, 0.15f,
                        32, 0, 32, 0);
                setSoftKeyViewParams(loginBtn, ConstraintLayout.LayoutParams.PARENT_ID, -1, R.id.useFingerPrintIdText,null, 0.25f,
                        32, 0, 32, 0);
            }
        });

Nennen Sie diese Methode:

    private void setSoftKeyViewParams(View view, int bottomToBottom, int topToTop, int topToBottom, String ratio, float verticalBias,
                                  int left, int top, int right, int bottom) {
    ConstraintLayout.LayoutParams viewParams = new ConstraintLayout.LayoutParams(view.getLayoutParams().width, view.getLayoutParams().height);
    viewParams.dimensionRatio = ratio;
    viewParams.bottomToBottom = bottomToBottom;
    viewParams.topToTop = topToTop;
    viewParams.topToBottom = topToBottom;
    viewParams.endToEnd = ConstraintLayout.LayoutParams.PARENT_ID;
    viewParams.startToStart = ConstraintLayout.LayoutParams.PARENT_ID;
    viewParams.verticalBias = verticalBias;
    viewParams.setMargins(Dimensions.dpToPx(left), Dimensions.dpToPx(top), Dimensions.dpToPx(right), Dimensions.dpToPx(bottom));
    view.setLayoutParams(viewParams);
}

Wichtig ist, dass Sie die vertikale Vorspannung so einstellen, dass sie korrekt skaliert wird, wenn die Tastatur angezeigt und nicht angezeigt wird.

6rchid
quelle
2
Eine einfachere Methode besteht darin, das ConstraintLayout in eine ScrollView oder eine NestedScrollView zu verpacken. Die Berechnungen sind zu viel Arbeit. Aber Ihre Antwort ist großartig, wenn eine ScrollView andere Probleme verursachen würde
Devenom
5

Viele Antworten sind richtig. In AndroidManifestschrieb ich:

<activity
    android:name=".SomeActivity"
    android:configChanges="orientation|keyboardHidden|screenSize" // Optional, doesn't affect.
    android:theme="@style/AppTheme.NoActionBar"
    android:windowSoftInputMode="adjustResize" />

In meinem Fall habe ich ein Thema hinzugefügt styles.xml, aber Sie können Ihr eigenes verwenden:

<style name="AppTheme.NoActionBar" parent="AppTheme">
    <!--  Hide ActionBar -->
    <item name="windowNoTitle">true</item>
    <item name="windowActionBar">false</item>
</style>

Ich habe festgestellt, dass bei Verwendung eines Vollbild-Themas keine Größenänderung auftritt:

<style name="AppTheme.FullScreenTheme" parent="AppTheme">
    <!--  Hide ActionBar -->
    <item name="windowNoTitle">true</item>
    <item name="windowActionBar">false</item>
    <!--  Hide StatusBar -->
    <item name="android:windowFullscreen">true</item>
</style>

Funktioniert auch in meinem Fall, adjustResizefunktioniert aber adjustPannicht.

Für Vollbild-Layouts finden Sie eine Problemumgehung in Android. So passen Sie das Layout im Vollbildmodus an, wenn das Softkeyboard sichtbar ist, oder in https://gist.github.com/grennis/2e3cd5f7a9238c59861015ce0a7c5584 .

Auch https://medium.com/@sandeeptengale/problem-solved-3-android-full-screen-view-translucent-scrollview-adjustresize-keyboard-b0547c7ced32 funktioniert, aber die Statusleiste ist transparent, also Batterie, Uhr, Wi- Fi-Symbole sind sichtbar.

Wenn Sie eine Aktivität mit Datei> Neu> Aktivität> Vollbildaktivität erstellen, wobei im Code Folgendes verwendet wird:

fullscreen_content.systemUiVisibility =
    View.SYSTEM_UI_FLAG_LOW_PROFILE or
    View.SYSTEM_UI_FLAG_FULLSCREEN or
    View.SYSTEM_UI_FLAG_LAYOUT_STABLE or
    View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY or
    View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION or
    View.SYSTEM_UI_FLAG_HIDE_NAVIGATION

Sie werden auch kein Ergebnis erzielen. Sie können android:fitsSystemWindows="true"in einem Root-Container verwenden, aber StatusBar wird angezeigt. Verwenden Sie daher Problemumgehungen ab dem ersten Link.

CoolMind
quelle
@ Harshilkakadiya, danke! Beachten Sie, dass diese Problemumgehung entfernt werden sollte, wenn Sie dann zum normalen Modus (nicht Vollbild) zurückkehren möchten. Ich habe viele Stunden damit verschwendet. In meinem Fall unter Layout habe ich einen Leerraum bekommen. Viel Glück!
CoolMind
3

Sie können diese Optionen einfach in der Datei AndroidManifest.xml festlegen.

<activity
    android:name=".YourACtivityName"
    android:windowSoftInputMode="stateVisible|adjustResize">

Die Verwendung von adjustPanwird von Google nicht empfohlen, da der Nutzer möglicherweise die Tastatur schließen muss, um alle Eingabefelder anzuzeigen.

Weitere Informationen: Android App Manifest

vovahost
quelle
3

Bei mir hat es mit dieser Codezeile funktioniert:

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

Fügen Sie es einfach in die onCreate-Methode ein. Beste!

Peter94
quelle
1
Während dies theoretisch die Frage beantworten kann, wäre es vorzuziehen, auch zu erklären, warum dies funktioniert.
Clinomaniac
2

In meinem Fall hat es geholfen.

main_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main2"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:orientation="vertical"
    tools:context="com.livewallpaper.profileview.loginact.Main2Activity">

<TextView
    android:layout_weight="1"
    android:layout_width="match_parent"
    android:text="Title"
    android:gravity="center"
    android:layout_height="0dp" />
<LinearLayout
    android:layout_weight="1"
    android:layout_width="match_parent"
    android:layout_height="0dp">
    <EditText
        android:hint="enter here"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
</LinearLayout>
<TextView
    android:layout_weight="1"
    android:text="signup for App"
    android:gravity="bottom|center_horizontal"
    android:layout_width="match_parent"
    android:layout_height="0dp" />
</LinearLayout>

Verwenden Sie dies in der manifestDatei

<activity android:name=".MainActivity"
        android:screenOrientation="portrait"
        android:windowSoftInputMode="adjustResize"/>

Nun der wichtigste Teil! Verwenden Sie ein solches Thema entweder in Activityoder im ApplicationTag.

android:theme="@style/AppTheme"

Und das Thema dauert so

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    <!-- Customize your theme here. -->
    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
    <item name="colorAccent">@color/colorAccent</item>
    <item name="windowActionBar">false</item>
    <item name="windowNoTitle">true</item>
    <item name="windowActionModeOverlay">true</item>
</style>

Also hat mir das Thema gefehlt. Was mich den ganzen Tag frustriert hat.

Pradeep Kumar Kushwaha
quelle
1

Ich verwende diesen erweiterten Klassenrahmen. Wenn ich die Höhengröße onLayout neu berechnen muss, überschreibe ich onmeasure und subtrahiere keyboardHeight mit getKeyboardHeight ()

Mein Erstellungsrahmen, der die Größe mit Softkeyboard ändern muss

SizeNotifierFrameLayout frameLayout = new SizeNotifierFrameLayout(context) {
            private boolean first = true;

            @Override
            protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
                super.onLayout(changed, left, top, right, bottom);

                if (changed) {
                    fixLayoutInternal(first);
                    first = false;
                }
            }

            @Override
            protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
                super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(heightMeasureSpec) - getKeyboardHeight(), MeasureSpec.EXACTLY));
            }

            @Override
            protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
                boolean result = super.drawChild(canvas, child, drawingTime);
                if (child == actionBar) {
                    parentLayout.drawHeaderShadow(canvas, actionBar.getMeasuredHeight());
                }
                return result;
            }


        };

SizeNotifierFrameLayout

public class SizeNotifierFrameLayout extends FrameLayout {

    public interface SizeNotifierFrameLayoutDelegate {
        void onSizeChanged(int keyboardHeight, boolean isWidthGreater);
    }

    private Rect                            rect            = new Rect();
    private Drawable                        backgroundDrawable;
    private int                             keyboardHeight;
    private int                             bottomClip;
    private SizeNotifierFrameLayoutDelegate delegate;
    private boolean                         occupyStatusBar = true;

    public SizeNotifierFrameLayout(Context context) {
        super(context);
        setWillNotDraw(false);
    }

    public Drawable getBackgroundImage() {
        return backgroundDrawable;
    }

    public void setBackgroundImage(Drawable bitmap) {
        backgroundDrawable = bitmap;
        invalidate();
    }

    public int getKeyboardHeight() {
        View rootView = getRootView();
        getWindowVisibleDisplayFrame(rect);
        int usableViewHeight = rootView.getHeight() - (rect.top != 0 ? AndroidUtilities.statusBarHeight : 0) - AndroidUtilities.getViewInset(rootView);
        return usableViewHeight - (rect.bottom - rect.top);
    }

    public void notifyHeightChanged() {
        if (delegate != null) {
            keyboardHeight = getKeyboardHeight();
            final boolean isWidthGreater = AndroidUtilities.displaySize.x > AndroidUtilities.displaySize.y;
            post(new Runnable() {
                @Override
                public void run() {
                    if (delegate != null) {
                        delegate.onSizeChanged(keyboardHeight, isWidthGreater);
                    }
                }
            });
        }
    }

    public void setBottomClip(int value) {
        bottomClip = value;
    }

    public void setDelegate(SizeNotifierFrameLayoutDelegate delegate) {
        this.delegate = delegate;
    }

    public void setOccupyStatusBar(boolean value) {
        occupyStatusBar = value;
    }

    protected boolean isActionBarVisible() {
        return true;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        if (backgroundDrawable != null) {
            if (backgroundDrawable instanceof ColorDrawable) {
                if (bottomClip != 0) {
                    canvas.save();
                    canvas.clipRect(0, 0, getMeasuredWidth(), getMeasuredHeight() - bottomClip);
                }
                backgroundDrawable.setBounds(0, 0, getMeasuredWidth(), getMeasuredHeight());
                backgroundDrawable.draw(canvas);
                if (bottomClip != 0) {
                    canvas.restore();
                }
            } else if (backgroundDrawable instanceof BitmapDrawable) {
                BitmapDrawable bitmapDrawable = (BitmapDrawable) backgroundDrawable;
                if (bitmapDrawable.getTileModeX() == Shader.TileMode.REPEAT) {
                    canvas.save();
                    float scale = 2.0f / AndroidUtilities.density;
                    canvas.scale(scale, scale);
                    backgroundDrawable.setBounds(0, 0, (int) Math.ceil(getMeasuredWidth() / scale), (int) Math.ceil(getMeasuredHeight() / scale));
                    backgroundDrawable.draw(canvas);
                    canvas.restore();
                } else {
                    int actionBarHeight =
                            (isActionBarVisible() ? ActionBar.getCurrentActionBarHeight() : 0) + (Build.VERSION.SDK_INT >= 21 && occupyStatusBar ? AndroidUtilities.statusBarHeight : 0);
                    int   viewHeight = getMeasuredHeight() - actionBarHeight;
                    float scaleX     = (float) getMeasuredWidth() / (float) backgroundDrawable.getIntrinsicWidth();
                    float scaleY     = (float) (viewHeight + keyboardHeight) / (float) backgroundDrawable.getIntrinsicHeight();
                    float scale      = scaleX < scaleY ? scaleY : scaleX;
                    int   width      = (int) Math.ceil(backgroundDrawable.getIntrinsicWidth() * scale);
                    int   height     = (int) Math.ceil(backgroundDrawable.getIntrinsicHeight() * scale);
                    int   x          = (getMeasuredWidth() - width) / 2;
                    int   y          = (viewHeight - height + keyboardHeight) / 2 + actionBarHeight;
                    canvas.save();
                    canvas.clipRect(0, actionBarHeight, width, getMeasuredHeight() - bottomClip);
                    backgroundDrawable.setBounds(x, y, x + width, y + height);
                    backgroundDrawable.draw(canvas);
                    canvas.restore();
                }
            }
        } else {
            super.onDraw(canvas);
        }
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        super.onLayout(changed, l, t, r, b);
        notifyHeightChanged();
    }
}
Arthur Melo
quelle
1

Fügen Sie diese Zeile in die Manifiest-Datei ein:

android:windowSoftInputMode="adjustResize"
Nullzeiger-Ausnahme
quelle
1

In Kotlin oder in ConstraintLayout fügen Sie einfach hinzu:

android:windowSoftInputMode="stateHidden|adjustResize"

ODER

android:windowSoftInputMode="stateVisible|adjustResize"

Welchen Status Sie nach dem Start der Aktivität benötigen, können Sie über das Manifest festlegen.

in deinem AndroidManifest.xmlso:

      <activity
        android:name=".ActivityName"
        android:windowSoftInputMode="stateHidden|adjustResize"
        />
Jamil Hasnine Tamim
quelle
0

Dieser Code funktioniert für mich. Wenn die Tastatur angezeigt wird, können Sie den Bildschirm scrollen

In AndroidManifest.xml

<activity android:name=".signup.screen_2.SignUpNameAndPasswordActivity"
                  android:screenOrientation="portrait"
                  android:windowSoftInputMode="adjustResize">
</activity>

activity_sign_up.xml

<?xml version="1.0" encoding="utf-8"?>
<ScrollView
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fillViewport="true"
        tools:context=".signup.screen_2.SignUpNameAndPasswordActivity">
    <LinearLayout
            android:fitsSystemWindows="true"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">

        <LinearLayout
                android:layout_marginTop="@dimen/dp_24"
                android:layout_marginStart="@dimen/dp_24"
                android:layout_marginEnd="@dimen/dp_24"
                android:id="@+id/lin_name_password"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical">

            <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center_horizontal"
                    android:fontFamily="sans-serif-medium"
                    android:text="@string/name_and_password"
                    android:textColor="@color/colorBlack"
                    android:layout_marginTop="@dimen/dp_5"
                    android:textSize="@dimen/ts_16"/>

            <EditText
                    android:id="@+id/edit_full_name"
                    android:layout_width="match_parent"
                    android:layout_height="@dimen/dp_44"
                    app:layout_constraintTop_toTopOf="parent"
                    android:hint="@string/email_address_hint"
                    android:inputType="textPersonName"
                    android:imeOptions="flagNoFullscreen"
                    android:textSize="@dimen/ts_15"
                    android:background="@drawable/rounded_border_edittext"
                    android:layout_marginTop="@dimen/dp_15"
                    android:paddingStart="@dimen/dp_8"
                    android:paddingEnd="@dimen/dp_8"
                    android:maxLength="100"
                    android:maxLines="1"/>

            <EditText
                    android:id="@+id/edit_password"
                    android:layout_width="match_parent"
                    android:layout_height="@dimen/dp_44"
                    app:layout_constraintTop_toTopOf="parent"
                    android:hint="@string/password"
                    android:inputType="textPassword"
                    android:imeOptions="flagNoFullscreen"
                    android:textSize="@dimen/ts_15"
                    android:background="@drawable/rounded_border_edittext"
                    android:layout_marginTop="@dimen/dp_15"
                    android:paddingStart="@dimen/dp_8"
                    android:paddingEnd="@dimen/dp_8"
                    android:maxLength="100"
                    android:maxLines="1"/>

            <TextView
                    android:id="@+id/btn_continue_and_sync_contacts"
                    android:layout_width="match_parent"
                    android:layout_height="@dimen/dp_44"
                    android:gravity="center"
                    android:clickable="true"
                    android:focusable="true"
                    android:layout_marginTop="@dimen/dp_15"
                    android:background="@drawable/btn_blue_selector"
                    android:enabled="false"
                    android:text="@string/continue_and_sync_contacts"
                    android:textColor="@color/colorWhite"
                    android:textSize="@dimen/ts_15"
                    android:textStyle="bold"/>

            <TextView
                    android:id="@+id/btn_continue_without_syncing_contacts"
                    android:layout_width="match_parent"
                    android:layout_height="@dimen/dp_44"
                    android:gravity="center"
                    android:clickable="true"
                    android:focusable="true"
                    android:layout_marginTop="@dimen/dp_10"
                    android:enabled="false"
                    android:text="@string/continue_without_syncing_contacts"
                    android:textColor="@color/colorBlue"
                    android:textSize="@dimen/ts_15"
                    android:textStyle="bold"/>

        </LinearLayout>
        <!--RelativeLayout is scaled when keyboard appears-->
        <RelativeLayout
                android:layout_marginStart="@dimen/dp_24"
                android:layout_marginEnd="@dimen/dp_24"
                android:layout_marginBottom="@dimen/dp_20"
                android:layout_width="match_parent"
                android:layout_height="match_parent">

            <LinearLayout
                    android:layout_alignParentBottom="true"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:orientation="vertical">
                <TextView
                        android:id="@+id/tv_learn_more_1"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:clickable="true"
                        android:focusable="true"
                        android:layout_gravity="center_horizontal"
                        android:text="@string/learn_more_syncing_contacts"
                        android:textColor="@color/black_alpha_70"
                        android:gravity="center"
                        android:layout_marginBottom="1dp"
                        android:textSize="@dimen/ts_13"/>

                <TextView
                        android:id="@+id/tv_learn_more_2"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:clickable="true"
                        android:focusable="true"
                        android:layout_gravity="center_horizontal"
                        android:text="@string/learn_more"
                        android:fontFamily="sans-serif-medium"
                        android:textColor="@color/black_alpha_70"
                        android:textSize="@dimen/ts_13"/>
            </LinearLayout>
        </RelativeLayout>
    </LinearLayout>
</ScrollView>

round_border_edittext.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_activated="true">
        <shape android:shape="rectangle">
            <solid android:color="#F6F6F6"/>
            <corners android:radius="3dp"/>
            <stroke
                    android:width="1dp"
                    android:color="@color/red"/>
        </shape>
    </item>
    <item android:state_activated="false">
        <shape android:shape="rectangle">
            <solid android:color="#F6F6F6"/>
            <corners android:radius="3dp"/>
            <stroke
                    android:width="1dp"
                    android:color="@color/colorGray"/>
        </shape>
    </item>
</selector>

btn_blue_selector.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_enabled="true" android:state_pressed="true">
        <shape android:shape="rectangle">
            <corners android:radius="3dp"/>
            <solid android:color="@color/colorBlueLight"/>
            <stroke android:width="1dp" android:color="@color/colorBlueLight"/>
        </shape>
    </item>
    <item android:state_enabled="true">
        <shape android:shape="rectangle">
            <corners android:radius="3dp"/>
            <solid android:color="@color/colorBlue"/>
            <stroke android:width="1dp" android:color="@color/colorBlue"/>
        </shape>
    </item>
    <item android:state_enabled="false">
        <shape android:shape="rectangle">
            <corners android:radius="3dp"/>
            <solid android:color="@color/colorBlueAlpha"/>
            <stroke android:width="0dp" android:color="@color/colorBlueAlpha"/>
        </shape>
    </item>
</selector>
Anh Duy
quelle
0

In Xamarin registrieren Sie sich unter dem Code in Ihrer Aktivität

 WindowSoftInputMode = Android.Views.SoftInput.AdjustResize | Android.Views.SoftInput.AdjustPan

Ich habe ein relatives Layout verwendet, wenn Sie das Einschränkungslayout verwenden. Der obige Code funktioniert wie folgt

logeshpalani98
quelle
0

Einfacher Weg in Kotlin

In deinem Fragment

requireActivity().window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE or WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN)

In Ihrem Layout:

android:fitsSystemWindows="true"
Phạm Thành Nam
quelle