Jak dostosować układ, gdy pojawi się miękka klawiatura

Chciałbym dostosować / zmienić rozmiar układu, gdy aktywowana jest miękka klawiatura, jak poniżej:

Przed i po:

Tutaj wpisz opis obrazkaTutaj wpisz opis obrazka


Znaleziono kilka zasobów w SO:

  1. Jak zachować widoczność wszystkich pól i tekstów podczas wyświetlania miękkiej klawiatury
  2. android miękka klawiatura psuje układ, gdy pojawia się
  3. Dopasuj układ, gdy miękka klawiatura jest włączona

Ale pytania i odpowiedzi są raczej niejednoznaczne, oto pytanie z wyraźniejszym obrazem tego, czego chcę.

Wymagania:

  • powinien działać na telefonie o dowolnej wielkości ekranu.
  • zauważyłem, że przestrzeń margin / padding na "FACEBOOK" i " zapisz się na Facebook " zmienił się przed i po.
  • nie jest wymagany widok przewijania.
Author: Community, 2013-05-07

9 answers

Po prostu dodaj

android:windowSoftInputMode="adjustResize"
W Twoim AndroidManifest.xml, w którym zadeklarujesz tę konkretną aktywność, a to dostosuje opcję zmiany rozmiaru układu.

Tutaj wpisz opis obrazka

Jakiś kod źródłowy poniżej do projektowania układu

<?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>
 155
Author: Venkatesh S,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-02-27 00:30:19

To pytanie zostało zadane kilka lat temu i "Secret Andro Geni" ma dobre podstawowe wyjaśnienie i "tir38" również podjął dobrą próbę kompletnego rozwiązania, ale niestety nie ma tu kompletnego rozwiązania. Spędziłem kilka godzin na wymyślaniu rzeczy i oto moje kompletne rozwiązanie ze szczegółowym wyjaśnieniem na dole: {]}

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

I w AndroidManifest.xml , nie zapomnij ustawić:

android:windowSoftInputMode="adjustResize"

Na znaczniku <activity> że chcesz takie układ.

Myśli:

Zdałem sobie sprawę, że RelativeLayout to układy, które obejmują całą dostępną przestrzeń i są zmieniane po pojawieniu się klawiatury.

I LinearLayout to układy, które nie ulegają zmianie w procesie zmiany rozmiaru.

Dlatego musisz mieć 1 RelativeLayout zaraz po ScrollView, aby objąć całą dostępną przestrzeń ekranu. I musisz mieć LinearLayout wewnątrz RelativeLayout w przeciwnym razie twoje wnętrze zostanie zmiażdżone, gdy nastąpi zmiana rozmiaru. Dobrym przykładem jest "headerLayout". Jeśli nie byłoby LinearLayout wewnątrz RelativeLayout tekst "facebook" zostałby zmiażdżony i nie byłby pokazywany.

W obrazkach logowania "facebook" zamieszczonych w pytaniu zauważyłem również, że cała część logowania (mainLayout) jest wyśrodkowana pionowo w stosunku do całego ekranu, stąd atrybut:

android:layout_centerVertical="true"

Na układzie LinearLayout. A ponieważ mainLayout znajduje się wewnątrz LinearLayout, oznacza to, że ta część nie zostanie zmieniona (patrz rysunek w pytaniu).

 25
Author: Yani2000,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-01 15:12:42

Dodaj ten wiersz w manifeście, gdzie nazywa się Twoja aktywność

android:windowSoftInputMode="adjustPan|adjustResize"

Lub

Możesz dodać ten wiersz w swoim onCreate

getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE|WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
 13
Author: Ashish Jaiswal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-12 12:17:03

Programista Androida ma prawidłową odpowiedź, ale podany kod źródłowy jest dość gadatliwy i nie implementuje wzorca opisanego na diagramie.

Oto lepszy szablon:

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

To Ty decydujesz, jakich widoków używasz do części " przewijania "i " stopki". Wiedz również, że prawdopodobnie musisz ustawić ScrollView s fillViewPort .

 9
Author: tir38,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-06-24 20:09:25

Może pracować dla każdego rodzaju układu.

  1. Dodaj to do tagu aktywności w AndroidManyfest.xml android: windowSoftInputMode= " adjustResize" na przykład:

  2. Dodaj to do tagu układu w activitypage.xml, który zmieni swoją pozycję. android: fitsSystemWindows = "true" i android:layout_alignParentBottom= " true" na przykład:

 3
Author: user3725137,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-11 07:02:41

Dzięki temu możliwe jest wyświetlenie dowolnego pożądanego układu wcześniej ukrytego przez klawiaturę.

Dodaj to do tagu aktywności w AndroidManifest.xml

Android: windowSoftInputMode= "adjustResize"


Otocz swój główny widok przewijaniem, najlepiej za pomocą scrollbars = none. Widok przewijania nie zmieni nic w twoim układzie, z wyjątkiem tego, że zostanie użyty do rozwiązania tego problemu.

A następnie Ustaw fitsSystemWindows = "true" w widoku, który chcesz aby w pełni pokazano nad klawiaturą. Spowoduje to, że Twój EditText będzie widoczny nad klawiaturą i umożliwi przewinięcie w dół do części poniżej EditText, ale w widoku z fitsSystemWindows = "true".

Android: fitsSystemWindows = "true"

Na przykład:

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

Jeśli chcesz pokazać pełną część widoku fitsSystemWindows="true" nad klawiaturą w momencie pojawienia się klawiatury, będziesz potrzebował kodu do przewinięcia widoku do "bottom": {]}

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

Przykład pełnego układu:

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

 2
Author: Morten Holmgaard,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-01 06:40:43

W moim przypadku pomogło.

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>

Użyj tego w manifest pliku

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

Teraz najważniejsza część! Użyj tego motywu w tagu Activity lub Application.

android:theme="@style/AppTheme"

A temat tak wygląda

<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>
Więc przegapiłem temat. Co sprawiało, że cały dzień byłem sfrustrowany.
 1
Author: Pradeep Kumar Kushwaha,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-02 12:52:06

Możesz po prostu ustawić te opcje w AndroidManifest.plik xml.

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

Użycie adjustPan nie jest zalecane przez Google, ponieważ użytkownik może potrzebować zamknąć klawiaturę, aby zobaczyć wszystkie pola wejściowe.

Więcej informacji: Manifest aplikacji na Androida

 1
Author: vovahost,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-13 17:12:05

Dla mnie to działało z tą linijką kodu:

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

Wystarczy umieścić go w metodzie onCreate. Najlepszy!

 0
Author: Ian Žonja,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-18 17:34:40