Zmiana układu, gdy wyświetlana jest klawiatura

Osobiście nie lubię budować wyglądów strony czy aplikacji, ponieważ nie czuję tych wszystkich kolorów, układów itd. Niestety czasem trzeba wykonywać te czynności. Dlatego staram się stawiać na prostotę i minimalizm. Dziś porozmawiamy sobie o wyglądzie, a dokładniej zmianie układu, gdy wyświetlana jest klawiatura w aplikacji na system Android.

Problem

Jeżeli mamy pole do wpisywania tekstu, a pod nim jakiś kolejny widok. Jeżeli wyświetlimy klawiaturę, aby wpisać tekst, to ten drugi widok zostanie zasłonięty przez klawiaturę. W poniższym przykładzie mamy dwa EditTexty, jeden pod drugim. Jeżeli chcemy coś wpisać w pierwszym, to nie będziemy widzieć drugiego pola.

windowSoftInputMode adjustUnspecifiedwindowSoftInputMode adjustUnspecified

Kolejny problem to taki, że Toolbar się chowa. Zobaczmy, w jaki sposób to możemy rozwiązać.

Uzupełnij wiedzę o: Tworzymy przewijany Toolbar

Atrybut windowSoftInputModeandroid

android: windowSoftInputMode — to specjalny atrybut dzięki, któremu możemy kontrolować zachowanie klawiatury w aktywności. Domyślną wartością jest adjustUnspecified i efekt tego jest taki jak widzisz na powyższych zdjęciu. Uważam, że tryb domyślny jest nie taki jaki użytkownik oczekuje, gdzie górna część aktywności (Toolbar oraz TextView) jest wypychana poza ekran, aby zrobić miejsce dla widoku EditText.
Jeśli ustawisz w pliku AndroidManifest w sekcji dla danej aktywności: android:windowSoftInputMode=”adjustResize”, zostanie zachowana górna część aktywności. Drugi EditText przesunie się nad klawiaturę. Wartość adjustResize powoduje, że główne okno aktywności jest zawsze zmieniane w celu zwolnienia miejsca dla klawiatury na ekranie.

<activity
    android:name=".MainActivity"
    android:windowSoftInputMode="adjustResize"
...
>
<android.support.constraint.ConstraintLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="150dp"
        android:gravity="center"
        android:text="MYENV NET"
        android:textSize="100sp"
        android:textStyle="bold"
        app:layout_constraintBottom_toTopOf="@+id/editText01" />
    <EditText
        android:id="@+id/editText01"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="50dp"
        android:hint="EditText 01"
        app:layout_constraintBottom_toTopOf="@+id/editText02"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent" />
    <EditText
        android:id="@+id/editText02"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="40dp"
        android:hint="EditText 02"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent" />
</android.support.constraint.ConstraintLayout>

windowSoftInputMode adjustUnspecified adjustResizePrzewijanie aktywności

Pojawił się nam kolejny problem. Otóż teraz zniknął nam napis „MYENV NET„. Musimy zatem dodać do naszego layoutu widok, który będzie przesuwał nam aktywność. W tym celu skorzystamy z NestedScrollView. Wygląd może wyglądać tak:

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.NestedScrollView
    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.support.constraint.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <TextView ... />
        <EditText ... />
        <EditText ... />
    </android.support.constraint.ConstraintLayout>
</android.support.v4.widget.NestedScrollView>

Teraz użytkownik może przesuwać.ekran i mieć dostęp do każdego widoku. A nie prościej od razu wstawić przesuwanie i nie ustawiać atrybutu indowSoftInputMode? Można, ale efekt będzie taki sam jak na początku, czyli pole drugie do wpisywania zostanie zasłonięte przez klawiaturę. Oprócz tego nie będzie można przesuwać ekranu. Dziwne, prawda? Tak działa świat Androida 😉
Gdybyśmy zastosowali tutaj ScrollView zamiast NestedScrollView, wtedy nie trzeba dodawać atrybutów w manifeście. NestedScrollView ma kilka zalet w porównaniu do ScrollView. Mamy pewność, że dany widok się przewinie. NestedScrollView jest zgodny z CoordinatorLayout i wiele innych różnic, o których napiszę innym razem.

Konfigurowanie trybu klawiatury

Klawiatura może być skonfigurowana dla każdej aktywności w pliku AndroidManifest.xml przy użyciu atrybutu android: windowSoftInputMode w celu dostosowania domyślnej widoczności, a także wpływu klawiatury na wyświetlany interfejs.
Chociaż Android skupia się na pierwszym polu w layoucie, gdy uruchomi się aktywność, nie pokazuje klawiatury. Jeżeli chcesz aby wyświetlić klawiaturę po uruchomieniu aktywności, dodaj atrybut android:windowSoftInputMode=”stateVisible” w manifeście systemu Android. Oczywiście powyzsze wartości, które zostały wspomniane w tym wpisie można łączyć za pomocą pionowej kreski ( | ).
Więcej informacji można znaleźć w przewodniku — widoczności klawiatury.

Co dalej?

  • Polub stronę MYENV na Facebooku oraz śledź mnie na Twitterze
  • Zachęcam do komentowania i pisania propozycji tematów, o których chcesz przeczytać
  • Poleć ten wpis za pomocą poniższych przycisków. Będę Ci za to bardzo wdzięczny 🙂
  • Życzę Ci miłego dnia i miłego kodowania 🙂