android: windowSoftInputMode= "adjustResize" nie robi żadnej różnicy?

Mam faux dialog, który używa tego układu:

<?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> 

Umieszczam fragment wewnątrz <FrameLayout> w zależności od okna dialogowego, które się otwiera - działanie sterujące oknem wygląda następująco:

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

Niestety po kliknięciu na edytowany tekst w oknie dialogowym nie następuje zmiana rozmiaru. windowSoftInputMode dosłownie nie robi różnicy, ponieważ funkcjonalność jest taka sama jak tryb pan.

Dokumentacja mówi: "to oczywiście działa tylko dla aplikacje, które mają obszar, który można zmienić, który można zmniejszyć, aby zrobić wystarczająco dużo miejsca", ale nie mówi, co to znaczy "obszar, który można zmienić" i sprawia, że myślę, że w jakiś sposób ja nie mają obszar, który można zmienić?

Jeśli ktoś wie o co chodzi, może mi pomóc?

EDIT

Otaczanie okna tak nic nie zmienia:

<?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 jako rodzic też nie pomaga:

<?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>
Author: Rahul Tiwari, 2011-12-06

9 answers

Stworzyłem nowy projekt, aby spróbować uzyskać podstawowe funkcje pracy przy zmianie rozmiaru okna i powoli przesuwać go w kierunku docelowego peice mojego projektu. Robiąc to namierzyłem problem aż do tego:

W mojej hierarchii tematu miałem taką właściwość:

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

, który został pochowany na poziomie Theme.Black.NoTitleBar.FullScreen - przodka mojego niestandardowego tematu.

Dokumentacja sugeruje, że jest to "flaga wskazująca, czy to okno powinno wypełnić cały ekran". Że brzmi jak dobra rzecz, jeśli masz aplikację, która zajmuje cały ekran... Tyle, że zajmuje cały ekran bez flagi.

W rzeczywistości, po wyjęciu tego, nie ma absolutnie żadnych zmian w aplikacji w ogóle... poza adjustResize Teraz działa doskonale.
 52
Author: Graeme,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-07-02 08:18:30

Jakiś czas temu miałem ten sam problem w bibliotece, którą stworzyłem. (MaterialDrawer )

O ile widzę, wszystkie odpowiedzi nie rozwiązują głównego problemu, po prostu wskazują, aby usunąć flagę pełnoekranową (android:windowFullscreen), co nie jest rozwiązaniem dla wielu tam.

Wyżej wymieniony "problem" pojawia się tylko w wersjach Androida zaczynających się od poziomu API 19 (KITKAT), ponieważ zmieniły one zachowanie. Aby być poprawnym, nie ma problemu, działa zgodnie z przeznaczeniem. Zobacz komentarz przez pracownika z Androidem (Android-Issue ).


Więc zacząłem kopać wokół źródła Androida i doszedłem do następującego rozwiązania, używając ViewTreeObserver.OnGlobalLayoutListener i reagując, czy klawiatura zostanie pokazana / lub ukryta. Jeśli klawiatura zostanie pokazana, dodaję padding na dole widoku kontenera, który będzie emulował to samo, co zrobiłby adjustResize.


Rozwiązanie

Aby uprościć korzystanie, zawijałem całość w prostą klawiaturę klasy.

/**
 * 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);
        }
    }
}

Możesz następnie użyć go w swojej aktywności lub fragmencie, wykonując następujące czynności:

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

//enable it
keyboardUtil.enable();

//disable it
keyboardUtil.disable();

Cała klasa util jest używana we wspomnianej biblioteceMaterialDrawer i można ją znaleźć tutajKeyboardUtil . To zawsze będzie zawierać najnowszą wersję. (jeśli są ulepszenia)

 48
Author: mikepenz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-05-16 15:18:45

Wydaje się, że problem jest z FrameLayout, ponieważ zachowuje się w ten sposób, że każde dziecko zajmuje widoczną przestrzeń tej klatki, dlatego nie trzeba zmieniać rozmiaru, aby pasowały do dzieci. Spróbuj użyć RelativeLayout. Powinno zadziałać.

 2
Author: ACM64,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-12-06 10:29:22

Bez używania ScrollView jako rodzica dodałem android:fitsSystemWindows="true" do widoku rodzica (który był RelativeLayout) i adjustResize do manifestu dla aktywności i zadziałało.

 1
Author: Josh Laird,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-11-18 12:17:39

Spróbuj umieścić swoje LinearLayout na ScrollView, które kiedyś zadziałało dla mnie..

 0
Author: Cata,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-12-06 10:36:34

I ' ve had to set

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

Pomimo, nigdy nie ustawiłem go na true, a aplikacja nie była pełnoekranowa.

 0
Author: F0G,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-13 14:09:02

Nie wiem dlaczego, ale jeśli masz <item name="android:windowTranslucentNavigation">true</item> w swoim temacie, zmień go na false. I zacznie działać. Naprawdę dziwne.

 0
Author: Nastromo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-15 18:18:54

Jako oryginalny plakat wykryty, gdy flaga pełnoekranowa jest przypisana do aktywności, atrybut android: windowFullscreen nie będzie działał, więc twoje okno nie zmieni rozmiaru, gdy widoczna jest miękka klawiatura i nie będzie można go przewijać.

Po prostu usunięcie flagi pełnoekranowej i nie używanie motywu pełnoekranowego pozwoli na przewijanie, gdy widoczna jest miękka klawiatura.

 -1
Author: RichTurner,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-01-16 20:43:38

Upewnij się, że ustawiłeś windowTranslucentStatus Na false w swoich stylach.

 -3
Author: YTerle,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-25 12:43:17