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:
Znaleziono kilka zasobów w SO:
- Jak zachować widoczność wszystkich pól i tekstów podczas wyświetlania miękkiej klawiatury
- android miękka klawiatura psuje układ, gdy pojawia się
- 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.
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.
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>
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).
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);
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 .
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.
-
Dodaj to do tagu aktywności w AndroidManyfest.xml android: windowSoftInputMode= " adjustResize" na przykład:
-
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:
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>
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.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
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!
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