Настройка раскладки при включенной программной клавиатуре

В некоторых приложениях я видел, как раскладка меняется, когда отображается программная клавиатура. Это конечно не adjustPan потому что весь макет (вероятно, внутренний макет) смещается, а не только текущий EditText, Это, например, на экране входа в Evernote. Можете ли вы посоветовать, как это сделано?

6 ответов

Решение

Вот решение, которое работает как экран входа в Evernote:

Во-первых, определите класс, который будет вашим специальным LinearLayout следующим образом:

public class MyLayout extends LinearLayout {

public MyLayout(Context context, AttributeSet attrs) {
    super(context, attrs);
}

public MyLayout(Context context) {
    super(context);
}

private OnSoftKeyboardListener onSoftKeyboardListener;

@Override
protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) {
    if (onSoftKeyboardListener != null) {
        final int newSpec = MeasureSpec.getSize(heightMeasureSpec); 
        final int oldSpec = getMeasuredHeight();
        if (oldSpec > newSpec){
            onSoftKeyboardListener.onShown();
        } else {
            onSoftKeyboardListener.onHidden();
        }
    }
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}

public final void setOnSoftKeyboardListener(final OnSoftKeyboardListener listener) {
    this.onSoftKeyboardListener = listener;
}

public interface OnSoftKeyboardListener {
    public void onShown();
    public void onHidden();
}

}

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

Хотя, чтобы это работало, в вашем манифесте нужно установить android:windowSoftInputMode="adjustResize" поэтому содержание будет изменено, а не просто сдвинуто.

И вся система работает следующим образом: у вас есть ваш макет:

<MyLayout id="layout">
  <SomeImage id="image"/>
  <SomeText>
  <SomeInput>
</MyLayout>

Это как экран входа в evernotes. Тогда в вашей деятельности:

((MyLayout)findViewById(R.id.layout)).setOnSoftKeyboardListener(new OnSoftKeyboardListener() {
        @Override
        public void onShown() {
            findViewById(R.id.image).setVisibility(View.GONE);
        }
        @Override
        public void onHidden() {
            findViewById(R.id.image).setVisibility(View.VISIBLE);
        }
    });

Затем перейдите к manifest.xml и установите

android:windowSoftInputMode="adjustResize"

Что произойдет, когда будет показана программная клавиатура, она скроет изображение и изменит размер остального содержимого. (Вы можете увидеть, как текст изменяется в Evernote)

Image hide, конечно, одна из многих вещей, которые вы можете сделать. Но вы должны быть осторожны, так как различные изменения макета также вызовут onMeasure.

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

Используйте "AdjustResize" вместо "AdjustPan" в AndroidManifest.xml

<activity
    ...
    android:windowSoftInputMode="adjustResize" />

Из документации:

"adjustResize"
Главное окно действия всегда изменяется, чтобы освободить место для экранной клавиатуры.

"adjustPan"
Главное окно действия не изменено, чтобы освободить место для виртуальной клавиатуры. Скорее, содержимое окна автоматически панорамируется, так что текущий фокус никогда не скрывается клавиатурой, и пользователи всегда могут видеть, что они печатают. Как правило, это менее желательно, чем изменение размера, поскольку пользователю может потребоваться закрыть экранную клавиатуру, чтобы получить доступ к скрытым частям окна и взаимодействовать с ними.

Это сработало для меня.. Поместите это ваше творение

getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE|WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);

Выбранный ответ не работает в полноэкранном режиме. Следующее решение для одной линии работало на меня

 AndroidBug5497Workaround.assistActivity(this);

скопируйте класс AndroidBug5497 в обход:

Android Как настроить макет в полноэкранном режиме, когда программная клавиша видна

Используйте представление прокрутки в макете внутри родительского элемента и удалите настройку AdjustPan или AdjustSize из файла манифеста. ScrollView на вашем макете даст вам бесплатную функциональность для прокрутки панорамирования или макета с заданным макетом, а также защитит ваш макет для переопределения панели инструментов или панели действий, а также не будет скрывать кнопки или текстовые поля внутри макета. Помните, что вы должны использовать ScrollView внутри базовой компоновки, поэтому эта прокрутка будет работать как базовая компоновка всего экрана. пример

<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >

<ScrollView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:fillViewport="true"
    android:scrollbarStyle="insideInset"
    android:scrollbars="vertical" >

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:orientation="vertical" >

        <!-- Add here which you want -->
    </LinearLayout>
</ScrollView>

Другие вопросы по тегам