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

В моей основной деятельности есть 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 изменяется двумя способами:

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

Один из фрагментов Container B может содержать форму, содержащую EditText и другие представления.

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

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

Здесь ссылка на макет формы

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. Я не мог воспроизвести тот же эффект в оригинальном приложении по какой-то причине... все еще пытаясь понять, почему.

Ответ 1

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

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

Поскольку ваш макет не содержит ListView, ScrollView, изменение размера исключается.

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

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

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

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

Ответ 2

Чтобы изменить режим на "изменение размера" в следующем выражении на вашу активность в "AndroidManifest.xml".

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

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

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

Ответ 3

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

Этот код предоставляет помощь для изменения размера изображения

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

Ответ 4

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

   android:windowSoftInputMode="adjustPan|stateAlwaysHidden" 

как

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

Ответ 5

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

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

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

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

Ответ 7

Добавьте эту строку кода в DialogFragment Oncreateview ниже R.layout.layout_ui

getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN |     WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);