Как сохранить размер фонового изображения при показе программной клавиатуры

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

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

Однако этот вопрос был закрыт, когда они нашли взломать его. Я не могу использовать этот хак. Весь мой макет находится внутри ScrollView, и мне нужно иметь возможность использовать этот режим прокрутки правильно в любое время. С помощью android: windowSoftInputMode = "stateVisible | adjustPan" пользователь не сможет прокручивать вниз и видеть нижнюю часть экрана, пока отображается клавиатура, поскольку макет будет частично существовать за клавиатурой. Таким образом, решение для меня неприемлемо. Есть ли там лучшие решения?

Приветствия,

Ответ 1

После нескольких дней хардкорного взлома мне наконец удалось создать такое усовершенствованное решение, что, возможно, было бы больно его прочитать. Я размещаю ImageView с фоном позади scrollview и устанавливаю scaleType = "matrix", чтобы он не уменьшался при отображении клавиатуры.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="@color/black"
    >
    <ImageView
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:src="@drawable/mah_kewl_background"
        android:scaleType="matrix"
        />
    <ScrollView
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:fillViewport="true"
        >
        <RelativeLayout
            android:id="@+id/smsLayout"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            >
            <TextView
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:text="PLUNX"
                />
        </RelativeLayout>
    </ScrollView>
</RelativeLayout>

Ответ 2

На самом деле я столкнулся с подобной проблемой не так давно. Однако я наткнулся на правильный ответ с небольшой работой.

В манифесте андроида для этого проекта, привязанного к используемой вами конкретной деятельности, используйте тег android:windowSoftInputMode="adjustPan|stateVisible" в теге активности.

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

источник: Android Dev для тегов активности

Ответ 3

Вы можете использовать свойство windowBackground, которое делает пригодным для переноски весь экран. Для этого вам необходимо:

1- Создать стиль:

<style name="Background" parent="@android:style/Theme.NoTitleBar">
    <item name="android:windowBackground">@drawable/you_bg_drawable</item>
</style>

2- Установите стиль своей деятельности в AndroidManifest.xml

<activity
    android:name=".ui.your_activity"
    android:theme="@style/Background"/>

Ответ 4

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

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

Надеюсь, что это поможет кому-то еще найти решение для этого.

Ответ 5

Я не могу прокомментировать ваш ответ, но я хотел бы добавить что-то.

Я понимаю вашу дилемму и почему решение, с которым вы связались, не является полным решением для вашей ситуации (поскольку вы не можете прокручивать нижнюю часть представления). У меня аналогичная ситуация с большим прокручиваемым полем EditText. Когда появляется мягкая клавиатура, мне не нравится, как мой фон сжимается.

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

  • Если вы позволяете вашему приложению иметь ландшафтный режим, фон не будет изменять размер/растягивать
  • Если вы запустите приложение на устройстве с большим экраном или dpi, ваш фон может не заполнить экран.

Похоже, что когда вы устанавливаете scaleType в matrix, вы говорите Android, чтобы рисовать фон 1:1, а не масштабировать. Итак, что происходит, когда вы открываете мягкую клавиатуру с помощью своего решения, ваши scrollView и imageView все изменяются как обычно, но установленное изображение src остается 1:1, таким образом, продолжает показывать ту же область.

Итак, если, например, ваше фоновое изображение было настроено на определенный размер (например, 480 x 800), и он отлично заполняет ваш Nexus One, как только вы вращаетесь в альбом, у вас будет черная область справа.

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

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

В тщетной попытке решить эту проблему я наткнулся на атрибут View, называемый android:isScrollContainer. Этот атрибут сообщает определенным представлениям, разрешено ли им изменять размер при отображении мягкой клавиатуры. Это также упоминается кем-то в вашем связанном решении. Я попытался установить это (на false) на ViewGroup, содержащем мой фон, но любой дочерний элемент, который прокручивается, кажется, переопределяет его, вызывая снова скрежет.

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

Ответ 7

Возможно, есть другое (действительно простое!) решение: В styles.xml: создайте новый стиль следующим образом:

<style name="Yourstyle" parent="AppBaseTheme">
    <item name="android:windowBackground">@drawable/mybackground</item>
</style>

AppBaseTheme - ваша обычно используемая тема для вашего приложения. Затем вы добавляете в Manifest.xml:

<activity 
    android:name="com.your.app.name.Activity"
    android:theme="@style/Yourstyle">
</activity>

Итак, у вас тот же стиль, но с фоном.

Важно: не устанавливайте фоны в вашем обычном XML файле!

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

Ответ 8

Как насчет решения, где "фон" - это макет. Можем ли мы раздуть макет, сделать его размером всего окна, а затем вставить его в качестве фона окна?

Ответ 9

После долгого поиска...

Поместите android:windowSoftInputMode="adjustPan|stateVisible" в каждую активность