it-swarm.com.ru

android: windowSoftInputMode = "AdjustResize" не имеет никакого значения?

У меня есть искусственный диалог, который использует этот макет:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout    xmlns:Android="http://schemas.Android.com/apk/res/Android"
                Android:layout_height="match_parent"
                Android:layout_width="match_parent"
                Android:id="@+id/containerPageConatiner">

    <FrameLayout    Android:id="@+id/dialogHolder"
                    Android:layout_height="wrap_content"
                    Android:layout_width="wrap_content"
                    Android:padding="15dp"
                    Android:layout_gravity="center"
                    Android:background="@drawable/panel_picture_frame_bg_focus_blue"/>    
</FrameLayout> 

Я помещаю фрагмент внутри <FrameLayout> в зависимости от открывающегося диалога. Деятельность, управляющая диалогом, выглядит следующим образом:

<activity
    Android:label="@string/app_name"
    Android:name=".activity.DialogActivity"
    Android:theme="@style/CustomTheme.Screen.Transparent" 
    Android:windowSoftInputMode="adjustResize">

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

Документация говорит: «Конечно, это работает только для приложений, у которых есть область с изменяемыми размерами, которую можно уменьшить, чтобы освободить достаточно места», но не говорит вам, что означает «область с изменяемыми размерами», и заставляет меня думать, что в некоторых как у меня не есть область с изменяемыми размерами?

Если кто-нибудь знает, что случилось, они могут мне помочь?

ПРАВКА

Окружение диалога таким образом ничего не меняет:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:id="@+id/containerPageConatiner"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    Android:orientation="vertical" >

    <View
        Android:layout_width="0dp"
        Android:layout_height="0dp"
        Android:layout_weight="1" />

    <FrameLayout    
        Android:id="@+id/dialogHolder"
        Android:layout_height="wrap_content"
    Android:layout_width="wrap_content"
        Android:padding="15dp"
        Android:layout_gravity="center"
        Android:background="@drawable/panel_picture_frame_bg_focus_blue"/>

    <View
        Android:layout_width="0dp"
        Android:layout_height="0dp"
        Android:layout_weight="1" />
</LinearLayout>

EDIT2 

Scrollview как родитель тоже не помогает:

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:id="@+id/containerPageConatiner"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent" >

    <FrameLayout
            Android:id="@+id/dialogHolder"
            Android:layout_width="wrap_content"
            Android:layout_height="wrap_content"
            Android:layout_gravity="center"
            Android:padding="15dp" />

</ScrollView>
26
Graeme

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

В моей иерархии тем у меня было это свойство:

<item name="Android:windowFullscreen">true</item> 

который был похоронен на уровне Theme.Black.NoTitleBar.FullScreen - предка моей пользовательской темы.

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

На самом деле, как только вы уберете это, в приложении совершенно не будет никаких изменений ... кроме adjustResize теперь работает отлично.

46
Graeme

Некоторое время назад у меня также была та же проблема в библиотеке, которую я создал. ( MaterialDrawer )

Насколько я вижу, все предоставленные ответы не решают основную проблему, они просто указывают на то, чтобы убрать полноэкранный флаг (Android:windowFullscreen), который для многих не является решением.

Вышеупомянутая «проблема» появляется только в версиях Android, начиная с API Level 19 (KitKat), потому что они изменили поведение. Чтобы быть правильным, это не проблема, это работает как задумано. См. Комментарий сотрудника Android ( Android-Issue ).


Поэтому я начал копаться в источнике Android и пришел к следующему решению, используя ViewTreeObserver.OnGlobalLayoutListener и реагируя, если клавиатура отображается/скрыта. Если клавиатура отображается, я добавляю отступ в конец контейнера, который будет эмулировать то же, что и adjustResize.


Решение

Чтобы упростить использование, я обернул все это в простой вспомогательный класс KeyboardUtil.

/**
 * Created by mikepenz on 14.03.15.
 * This class implements a hack to change the layout padding on bottom if the keyboard is shown
 * to allow long lists with editTextViews
 * Basic idea for this solution found here: http://stackoverflow.com/a/9108219/325479
 */
public class KeyboardUtil {
    private View decorView;
    private View contentView;

    public KeyboardUtil(Activity act, View contentView) {
        this.decorView = act.getWindow().getDecorView();
        this.contentView = contentView;

        //only required on newer Android versions. it was working on API level 19 (Build.VERSION_CODES.KitKat)
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KitKat) {
            decorView.getViewTreeObserver().addOnGlobalLayoutListener(onGlobalLayoutListener);
        }
    }

    public void enable() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KitKat) {
            decorView.getViewTreeObserver().addOnGlobalLayoutListener(onGlobalLayoutListener);
        }
    }

    public void disable() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KitKat) {
            decorView.getViewTreeObserver().removeOnGlobalLayoutListener(onGlobalLayoutListener);
        }
    }


    //a small helper to allow showing the editText focus
    ViewTreeObserver.OnGlobalLayoutListener onGlobalLayoutListener = new ViewTreeObserver.OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {
            Rect r = new Rect();
            //r will be populated with the coordinates of your view that area still visible.
            decorView.getWindowVisibleDisplayFrame(r);

            //get screen height and calculate the difference with the useable area from the r
            int height = decorView.getContext().getResources().getDisplayMetrics().heightPixels;
            int diff = height - r.bottom;

            //if it could be a keyboard add the padding to the view
            if (diff != 0) {
                // if the use-able screen height differs from the total screen height we assume that it shows a keyboard now
                //check if the padding is 0 (if yes set the padding for the keyboard)
                if (contentView.getPaddingBottom() != diff) {
                    //set the padding of the contentView for the keyboard
                    contentView.setPadding(0, 0, 0, diff);
                }
            } else {
                //check if the padding is != 0 (if yes reset the padding)
                if (contentView.getPaddingBottom() != 0) {
                    //reset the padding of the contentView
                    contentView.setPadding(0, 0, 0, 0);
                }
            }
        }
    };


    /**
     * Helper to hide the keyboard
     *
     * @param act
     */
    public static void hideKeyboard(Activity act) {
        if (act != null && act.getCurrentFocus() != null) {
            InputMethodManager inputMethodManager = (InputMethodManager) act.getSystemService(Activity.INPUT_METHOD_SERVICE);
            inputMethodManager.hideSoftInputFromWindow(act.getCurrentFocus().getWindowToken(), 0);
        }
    }
}

Затем вы можете использовать его в своей деятельности или фрагменте, выполнив следующие действия:

//initialize the KeyboardUtil (you can do this global)
KeyboardUtil keyboardUtil = new KeyboardUtil(activity, getContent().getChildAt(0));

//enable it
keyboardUtil.enable();

//disable it
keyboardUtil.disable();

Весь класс util используется в вышеупомянутой библиотеке MaterialDrawer и может быть найден здесь KeyboardUtil . Это всегда будет содержать последнюю версию. (если есть улучшения)

44
mikepenz

Кажется, что проблема с FrameLayout, так как он ведет себя таким образом, что каждый дочерний элемент занимает видимое пространство этого кадра, поэтому нет необходимости изменять размер, чтобы соответствовать дочерним элементам. Попробуйте использовать RelativeLayout. Он должен работать.

2
ACM64

Вы можете настроить изменение размера программно. Добавьте это в onCreate () вашей деятельности.

getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
0
Naimish Vinchhi

Я не знаю почему, но если у вас есть <item name="Android:windowTranslucentNavigation">true</item> в вашей теме, измените его на false. И это начнет работать. Действительно странно.

0
Nastromo

Не используя ScrollView в качестве своего родителя, я просто добавил Android:fitsSystemWindows="true" в свое родительское представление (которое было RelativeLayout и adjustResize в манифест для действия, и это сработало.

0
Josh Laird

Попытайтесь поместить свой LinearLayout в ScrollView, который работал для меня однажды ..

0
Cata

Я должен был установить 

<item name="Android:windowFullscreen">false</item> 

Несмотря на это, я никогда не устанавливал его в значение true, и приложение фактически не было полноэкранным.

0
F0G