Программная клавиатура изменяет размер фонового изображения на 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>
11 ответов
Ok я исправил его с помощью
android:windowSoftInputMode="stateVisible|adjustPan"
вход внутри <Activity >
tag in . Я думаю, это было вызвано наличием ScrollView внутри активности.
я столкнулся с той же проблемой при разработке приложения чата, экран чата с фоновым изображением. android:windowSoftInputMode="adjustResize"
сжал мое фоновое изображение, чтобы соответствовать доступному пространству после отображения мягкой клавиатуры и" adjustPan " сдвинул весь макет вверх, чтобы настроить мягкую клавиатуру.
Решением этой проблемы была установка фона окна вместо фона макета внутри XML-кода действия. Использовать getWindow().setBackgroundDrawable()
в вашей деятельности.
вот лучшее решение, чтобы избежать такого рода проблем.
Шаг 1: создать стиль
<style name="ChatBackground" parent="AppBaseTheme">
<item name="android:windowBackground">@drawable/bg_chat</item>
</style>
Шаг 2: установите стиль активности в
<activity
android:name=".Chat"
android:screenOrientation="portrait"
android:theme="@style/ChatBackground" >
через android: windowSoftInputMode= "adjustPan" дает плохой пользовательский опыт, потому что через весь экран идет сверху (shift to top), поэтому, следующее является одним из лучших ответов.
у меня такая же проблема, но после этого я нашел потрясающие ответы от @Gem
В Манифесте
android:windowSoftInputMode="adjustResize|stateAlwaysHidden"
в xml
Не устанавливайте фон здесь и держите свой вид под ScrollView
In Java
вам нужно установить фон в window:
getWindow().setBackgroundDrawableResource(R.drawable.bg_wood) ;
благодаря @Gem.
просто для того...
Если у вас есть listview в вашей деятельности
u нужно добавить это 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 для решения проблемы. Большое ему спасибо. Но позже я заметил, что фоновое изображение частично скрыто actionbar (и statusbar я уверен). Этот небольшой вопрос уже предложен @zgc7009, который прокомментировал ниже Ответ @parulb полтора года назад, но никто не ответил.
Я работал целый день, чтобы найти способ, и, к счастью, я могу по крайней мере решить эту проблему прямо сейчас на моем телефоне.
Сначала нам нужен ресурс списка слоев в папке drawable, чтобы добавить дополнение сверху к фоновому изображению:
<!-- 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. Я нашел способ получить высоту actionbar в xml, но не строку состояния, поэтому я должен использовать фиксированную высоту 75dp для верхнего заполнения. Надеюсь, кто-нибудь сможет найти последний кусочек этой головоломки.
добавьте эту строку в AndroidManifest.в XML:
android:windowSoftInputMode=adjustUnspecified
смотрите этой ссылке для получения дополнительной информации.
Я страдал от подобных проблем, но, похоже, используя adjustPan
С android:isScrollContainer="false"
все еще не исправил мой макет (который был RecyclerView ниже LinearLayout). RecyclerView был в порядке, но каждый раз, когда виртуальная клавиатура появлялась, LinearLayout корректировался.
чтобы предотвратить это поведение (я просто хотел, чтобы клавиатура прошла через мой макет), я пошел со следующим кодом:
<activity
android:name=".librarycartridge.MyLibraryActivity"
android:windowSoftInputMode="adjustNothing" />
Это говорит Android в основном оставить свой макет в покое, когда виртуальный клавиатура называется.
Больше читай о возможных вариантах можно найти здесь (хотя, как ни странно, не похоже, что есть запись для adjustNothing
).
я столкнулся с тем же промлем, и ни одно решение не удовлетворило меня, потому что я использовал фрагмент в качестве слоя над другим фрагментом, поэтому
getActivity().getWindow().setBackgroundDrawable()
не работает для меня. Мое решение состояло в том, чтобы переопределить FrameLayout с логикой для обработки появляющейся клавиатуры и изменения растрового изображения на ходу. Это мой FrameLayout (Котлин):
`класс 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)
надеюсь, что это помогает