Отрегулируйте компоновку, когда включена мягкая клавиатура

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

Ответ 1

Здесь решение, которое работает как экран входа 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)

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

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

Ответ 2

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

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

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

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

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

Ответ 4

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

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

Ответ 6

используйте прокрутку в макете внутри родителя и удалите настройку настройки или настройки в файле манифеста. 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>