Программная клавиатура изменяет размер фонового изображения на Android

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

Как вы можете видеть, фон сжимается. Кто-нибудь может пролить свет на то, почему меняется размер фона?

Мой макет выглядит следующим образом:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/page_bg" android:isScrollContainer="false" > <LinearLayout android:layout_height="wrap_content" android:orientation="horizontal" android:layout_width="fill_parent" > <EditText android:id="@+id/CatName" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_weight="1" android:inputType="textCapSentences" android:lines="1" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/save" android:onClick="saveCat" /> </LinearLayout> <ImageButton android:id="@+id/add_totalk" android:layout_height="wrap_content" android:layout_width="wrap_content" android:background="@null" android:src="@drawable/add_small" android:scaleType="center" android:onClick="createToTalk" android:layout_marginTop="5dp" /> </LinearLayout> 

Хорошо, я исправил это, используя

 android:windowSoftInputMode="stateVisible|adjustPan" 

Запись внутри <Activity > в файле manifest . Я думаю, это было вызвано наличием ScrollView внутри Activity.

Я столкнулся с такой же проблемой при разработке приложения чата, экрана чата с фоновым изображением. android:windowSoftInputMode="adjustResize" сжал мое фоновое изображение, чтобы оно соответствовало доступному пространству после того, как была отображена мягкая клавиатура, и "adjustPan" сдвинул весь макет, чтобы настроить мягкую клавиатуру. Решение этой проблемы заключалось в установке фона фона вместо фона макета внутри XML-операции. Используйте getWindow().setBackgroundDrawable() в вашей деятельности.

Через android: windowSoftInputMode = "adjustPan" дает плохой пользовательский опыт, потому что через весь экран идет сверху (сдвиг в начало) Итак, следующий – один из лучших ответов.

У меня есть одна и та же проблема, но после этого я нашел Awesome ответы от @Gem

В манифесте

 android:windowSoftInputMode="adjustResize|stateAlwaysHidden" 

В xml

Не устанавливайте здесь какой-либо фон и сохраняйте свое представление под ScrollView

В Java

Вам нужно установить фон в окно:

  getWindow().setBackgroundDrawableResource(R.drawable.bg_wood) ; 

Благодаря @Gem.

Вот лучшее решение, чтобы избежать такой проблемы. Шаг 1. Создание стиля

 <style name="ChatBackground" parent="AppBaseTheme"> <item name="android:windowBackground">@drawable/bg_chat</item> </style> 

Шаг 2. Установите стиль своей деятельности в файле AndroidManifest.

 <activity android:name=".Chat" android:screenOrientation="portrait" android:theme="@style/ChatBackground" > 

Просто для добавления …

Если у вас есть список в вашей деятельности, вам нужно добавить этот android:isScrollContainer="false" в свойствах listview …

И не забудьте добавить android:windowSoftInputMode="adjustPan" в ваш манифест xml при вашей активности …

Если вы, ребята, используете android:windowSoftInputMode="adjustUnspecified" с прокручиваемым видом на вашем макете, тогда ваш фон будет по-прежнему изменяться с помощью мягкой клавиатуры …

Было бы лучше, если бы вы использовали значение «adjustPan», чтобы предотвратить изменение размера фона …

В случае, если кому-то нужно поведение adjustResize и не хотите, чтобы его ImageView был изменен, это еще один способ:

Просто поместите ImageView внутри ScrollView => RelativeLayout с помощью ScrollView.fillViewport = true.

 <ScrollView android:layout_width="match_parent" android:layout_height="match_parent" android:fillViewport="true"> <RelativeLayout android:layout_width="match_parent" android:layout_height="wrap_content"> <FrameLayout android:layout_width="100dp" android:layout_height="100dp"> <ImageView android:layout_width="match_parent" android:layout_height="match_parent" android:scaleType="fitXY" android:src="@drawable/gift_checked" /> </FrameLayout> </RelativeLayout> </ScrollView> 

Я столкнулся с основной проблемой при работе с моим приложением. Сначала я использую метод, предоставляемый @parulb для решения проблемы. Большое спасибо ему. Но позже я заметил, что фоновое изображение частично скрыто с помощью панели действий (и в строке состояния я уверен). Этот небольшой вопрос уже предложен @ zgc7009, который прокомментировал ниже ответ @parulb полтора года назад, но никто не ответил.

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

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

 <!-- my_background.xml --> <?xml version="1.0" encoding="utf-8"?> <layer-list xmlns:android="http://schemas.android.com/apk/res/android"> <item android:top="75dp"> <bitmap android:src="@drawable/bg" /> </item> </layer-list> 

Во-вторых, мы устанавливаем этот файл как ресурс для фона, как указано выше:

 getWindow().setBackgroundDrawableResource(R.drawable.my_background); 

Я использую Nexus 5. Я нашел способ получить высоту панели действий в xml, но не в строке состояния, поэтому я должен использовать фиксированную высоту 75dp для верхнего заполнения. Надеюсь, кто-нибудь найдет последнюю часть этой головоломки.

Добавьте эту строку в файл AndroidManifest.xml :

 android:windowSoftInputMode=adjustUnspecified 

Обратитесь к этой ссылке для получения дополнительной информации.

У меня были аналогичные проблемы, но, похоже, с помощью adjustPan с android:isScrollContainer="false" все еще не android:isScrollContainer="false" мой макет (который был RecyclerView под LinearLayout). RecyclerView был в порядке, но каждый раз, когда появлялась виртуальная клавиатура, LinearLayout снова настраивался.

Чтобы предотвратить это поведение (я просто хотел, чтобы клавиатура переместила мой макет), я пошел со следующим кодом:

  <activity android:name=".librarycartridge.MyLibraryActivity" android:windowSoftInputMode="adjustNothing" /> 

Это говорит Android в основном оставить свой макет в одиночку при вызове виртуальной клавиатуры.

Более adjustNothing возможных вариантов можно найти здесь (хотя, как ни странно, не похоже, что есть запись для adjustNothing ).

Я столкнулся с тем же проблемом, и ни одно решение не удовлетворило меня, потому что я использовал фрагмент как слой над другим фрагментом, поэтому getActivity().getWindow().setBackgroundDrawable() не работал для меня. Мое решение состояло в том, чтобы переопределить FrameLayout с логикой для обработки клавиатуры и изменения растрового изображения на ходу. Это мой FrameLayout (kotlin):

`Class FlexibleFrameLayout: FrameLayout {

 var backgroundImage: Drawable? = null set(bitmap) { field = bitmap invalidate() } private var keyboardHeight: Int = 0 private var isKbOpen = false private var actualHeight = 0 constructor(context: Context) : super(context) { init() } constructor(context: Context, attributeSet: AttributeSet) : super(context, attributeSet) { init() } fun init() { setWillNotDraw(false) } override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) { super.onMeasure(widthMeasureSpec, heightMeasureSpec) val height = MeasureSpec.getSize(heightMeasureSpec) if (actualHeight == 0) { actualHeight = height return } //kb detected if (actualHeight - height > 100 && keyboardHeight == 0) { keyboardHeight = actualHeight - height isKbOpen = true } if (actualHeight - height < 50 && keyboardHeight != 0) { isKbOpen = false } if (height != actualHeight) { invalidate() } } override fun onDraw(canvas: Canvas) { if (backgroundImage != null) { if (backgroundImage is ColorDrawable) { backgroundImage!!.setBounds(0, 0, measuredWidth, measuredHeight) backgroundImage!!.draw(canvas) } else if (backgroundImage is BitmapDrawable) { val scale = measuredWidth.toFloat() / backgroundImage!!.intrinsicWidth.toFloat() val width = Math.ceil((backgroundImage!!.intrinsicWidth * scale).toDouble()).toInt() val height = Math.ceil((backgroundImage!!.intrinsicHeight * scale).toDouble()).toInt() val kb = if (isKbOpen) keyboardHeight else 0 backgroundImage!!.setBounds(0, 0, width, height) backgroundImage!!.draw(canvas) } } else { super.onDraw(canvas) } } 

} `

Затем я использовал его как обычный FrameLayout и в моем фрагменте, называемом frameLayout.backgroundImage = Drawable.createFromPath(path)

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