Активность с фрагментами не изменяется при открытии клавиатуры

в моей основной деятельности есть RelativeLayout что имеет 2 ребенка:

  • An ImageView который служит фоном
  • A LinearLayout который имеет 2 контейнера фрагментов

activity_main.в XML

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_gravity="bottom"
    tools:context="${packageName}.${activityClass}">

    <ImageView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:adjustViewBounds="true"
        android:baselineAlignBottom="false"
        android:scaleType="fitStart"
        android:src="@drawable/bg_image" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:paddingTop="?android:attr/actionBarSize"
        android:layout_alignParentBottom="true">

        <LinearLayout
            android:id="@+id/ContainerA"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:orientation="vertical" />

        <LinearLayout
            android:id="@+id/ContainerB"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="@color/background_gray"
            android:orientation="vertical" />

    </LinearLayout>
</RelativeLayout>

контейнер A просто показывает фрагмент, который не изменяется.
Однако контейнер B содержит фрагмент, который изменяется в зависимости от кликов пользователя.

контейнер B изменения в 2 пути:

  • оно может расширить (от высоты около 70% к полной высоте).
  • он меняет фрагменты.

один из фрагментов контейнера B может содержать форму, которая содержит EditTextS и другие мнения.

моя проблема в том, что я не могу получить действие для изменения размера, когда клавиатура открыта.
Я установил adjustResize в файле манифеста и моя тема не является полноэкранной темой (это, по-видимому, причина этой проблемы). Я тоже попытался отредактировать представления, добавить ScrollViews но абсолютно ничего не сработало.

тема, которую я использую для этой деятельности, - это светлая тема с темной панелью действий из AppCompat библиотека. Я только отредактировал тему, чтобы разрешить наложение actionbar. Это не проблема, поскольку я уже пытался удалить эти изменения безрезультатно.

вот ссылка на макет

TL; DR adjustResize / adjustPan не работайте на меня. Искали, пробовали различные решения, ничего не получилось. Мой вопрос: какова причина этого в моем случае?

Обновление: AndroidManifest.в XML

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" ...>

    <uses-sdk android:minSdkVersion="11" android:targetSdkVersion="19" />

    <application ... android:theme="@style/AppTheme">
        <activity android:name=".SplashScreenActivity"
            android:label="@string/app_name"
            android:screenOrientation="portrait"
            android:theme="@android:style/Theme.Black.NoTitleBar">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name=".MainActivity"
            android:configChanges="keyboardHidden|screenSize" android:label="@string/app_name"
            android:screenOrientation="portrait" android:theme="@style/OverlayActionBarTheme"
            android:windowSoftInputMode="adjustResize"  />
        <activity android:name=".SettingsActivity"
            android:label="@string/title_activity_settings"
            android:parentActivityName=".MainActivity"
            android:windowSoftInputMode="adjustResize">
            <meta-data android:name="android.support.PARENT_ACTIVITY"
                android:value=".MainActivity" />
        </activity>
    </application>

</manifest>

обновление 2:
Я создал совершенно новое приложение, добавил макет формы в качестве основного макета и проверил, была ли проблема в самом макете. Оказывается, это так, как даже на этом недавно созданном приложении он, похоже, не изменяется.

как указано выше, ссылку на макет можно найти здесь

обновление 3: Мне удалось заставить его работать над новым приложением, окружив весь макет ScrollView. По какой-то причине я не мог воспроизвести тот же эффект в исходном приложении... все еще пытаюсь понять почему.

6 ответов


когда на экране появляется мягкая клавиатура, объем пространства, доступного для пользовательского интерфейса приложения, уменьшается. Система принимает решение о том, как организовать доступное пространство между пользовательским интерфейсом приложения и мягкой клавиатурой.

  • если окно содержит ListView, ScrollView, Окно приложения изменяется при условии, что все содержимое отображается.
  • если повторная калибровка невозможна,pan and scan используется подход, который просто включает прокрутку окно приложения, так что в настоящее время сфокусированное представление отображается.

так как ваш макет не содержит каких-либо ListView, ScrollView, повторная калибровка исключена.

корневой вид окна является FrameLayout, к которому вы изначально добавлять LinearLayout. С LinearLayout не поддерживает скроллинг, pan and scan подход также исключен. Следовательно, обертывание макета внутри ScrollView решает проблему прокрутки.

вы можете обратиться Разработчики Android блог для более подробной информации.

обновление 1:

OP смог решить проблему, как указано в этом ответ. Проблема происходила из-за того, что один фрагмент перекрывал другой фрагмент после анимации и родителя этих Fragmentбыл LinearLayout. Для наложения вам нужно использовать RelativeLayout или FrameLayout только.


чтобы изменить режим на " Изменить размер "в следующей инструкции к вашей деятельности в" AndroidManifest.XML."

 <activity android:name=".ActivityName"
        android:windowSoftInputMode="adjustResize">

и, пожалуйста, удалите сложность LinearLayout (означает, что вы используете несколько уровней LinearLayout ) вместо этого вы также можете использовать RelativeLayout .. с помощью этого вы можете легко установить макет, как вы хотите .. попробуйте, что также надеюсь, что ваша проблема может выпрямитель

надеюсь, это поможет.


вы также можете использовать этот код в своем фрагменте

этот код предоставляет помощь для изменения размера view

public static class MyDialog extends DialogFragment {

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

    // Dialog layout inflater code
    // getDialog() need to be called only after onCreateDialog(), which is invoked between onCreate() and onCreateView(). 
      getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN |     WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
   // return view code
  }
}

используйте эту строку в файле манифеста против действия, в котором вы хотите получить результат надеюсь, это поможет вам

   android:windowSoftInputMode="adjustPan|stateAlwaysHidden" 

как

  <activity
            android:name="com.android.youractivity"
            android:windowSoftInputMode="adjustPan|stateAlwaysHidden" />

оказывается, моя проблема была вызвана совершенно неожиданного источника.

случилось то, что я использовал LinearLayout как родитель моих двух контейнеров фрагментов.
Затем в моей расширяющейся анимации я поднял нижний контейнер, чтобы перекрыть другой.

Я не знаю почему но поскольку LinearLayout не должно содержать перекрывающихся детей, переключаясь на RelativeLayout или FrameLayout немедленно решил проблему.

С этого момента причина может быть не очевидна из кода, который я опубликовал, я хочу извиниться за отсутствие информации и буду считать самый подробный ответ лучшим.


используйте это в onCreateDialog в BottomSheetFragment / Dailogfragment

KeyboardUtil(getActivity(), view);

или

для использования фрагмент

new KeyboardUtil(this, findViewById(R.id.fragment_container));

используя этот класс Util

https://github.com/mikepenz/MaterialDrawer/blob/aa9136fb4f5b3a80460fe5f47213985026d20c88/library/src/main/java/com/mikepenz/materialdrawer/util/KeyboardUtil.java

Кредит:Mikepenz