web-dev-qa-db-fra.com

android: windowSoftInputMode = "adjustResize" ne fait aucune différence?

J'ai un faux dialogue qui utilise cette disposition:

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

Je place un fragment à l'intérieur du <FrameLayout> en fonction du dialogue qui s'ouvre. L'activité contrôlant le dialogue se présente comme suit:

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

Malheureusement, lorsque vous cliquez sur un texte d'édition dans la boîte de dialogue, aucun redimensionnement n'a lieu. La windowSoftInputMode ne fait littéralement aucune différence, car la fonctionnalité est la même que celle du mode panoramique.

Documentation dit "Ceci ne fonctionne bien sûr que pour les applications dont la zone redimensionnable peut être réduite pour laisser suffisamment d'espace" comment j’ai non ai une zone redimensionnable?

Si quelqu'un sait ce qui se passe, peuvent-ils m'aider?

MODIFIER

Entourer le dialogue comme si ne changeait rien:

<?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 en tant que parent n'aide pas non plus:

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

J'ai créé un nouveau projet afin d'essayer de faire fonctionner les fonctionnalités de base pour le redimensionnement de la fenêtre et je l'ai lentement déplacé vers la partie cible de mon projet. En faisant cela, j'ai tracé le problème jusqu'à ceci:

Dans ma hiérarchie de thèmes, j'avais cette propriété:

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

qui a été enterré au niveau de Theme.Black.NoTitleBar.FullScreen - Un ancêtre de mon thème personnalisé.

La documentation suggère qu'il s'agit d'un "indicateur indiquant si cette fenêtre doit remplir tout l'écran". Cela semble être une bonne chose si vous avez une application qui occupe tout l'écran ... Sauf qu'elle occupe tout l'écran sans le drapeau.

En fait, une fois que vous avez éliminé cela, il n'y a absolument aucun changement dans l'application ... à part adjustResize fonctionne maintenant parfaitement.

46
Graeme

Il y a quelque temps, j'ai également eu le même problème dans une bibliothèque que j'ai créée. ( MaterialDrawer )

Autant que je sache, toutes les réponses fournies ne résolvent pas le problème principal, elles indiquent simplement de supprimer l'indicateur plein écran (Android:windowFullscreen), ce qui n'est pas une solution pour beaucoup.

Le "problème" mentionné ci-dessus n'apparaît que dans les versions d'Android commençant par l'API Niveau 19 (KitKat), car elles ont modifié le comportement. Pour être correct, ce n'est pas un problème, cela fonctionne comme prévu. Voir le commentaire d'un employé Android ( Android-Issue ).


J'ai donc commencé à explorer les sources Android et je suis arrivé à la solution suivante en utilisant le ViewTreeObserver.OnGlobalLayoutListener et en réagissant si le clavier était affiché/ou masqué. Si le clavier est affiché, j'ajoute le remplissage au bas de la vue du conteneur, qui émulera de la même façon que le ferait adjustResize.


Solution

Pour simplifier l'utilisation, j'ai intégré le tout dans une simple classe d'assistance 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);
        }
    }
}

Vous pouvez ensuite l'utiliser dans votre activité ou votre fragment en procédant comme suit:

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

//enable it
keyboardUtil.enable();

//disable it
keyboardUtil.disable();

La classe util entière est utilisée dans la bibliothèque mentionnée ci-dessus MaterialDrawer et peut être trouvée ici KeyboardUtil . Cela contiendra toujours la dernière version. (s'il y a des améliorations)

44
mikepenz

Il semble que le problème soit lié à FrameLayout, car il se comporte de la sorte, chaque enfant occupant l’espace visible de cette image, il n’a donc pas besoin de le redimensionner pour l’adapter aux enfants. Essayez d'utiliser RelativeLayout. Ça devrait marcher.

2
ACM64

Vous pouvez ajuster Redimensionner par programme. Ajoutez ceci dans onCreate () de votre activité.

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

Je ne sais pas pourquoi, mais si vous avez <item name="Android:windowTranslucentNavigation">true</item> dans votre thème, changez-le en false. Et ça va commencer à fonctionner. Vraiment étrange.

0
Nastromo

Sans utiliser un ScrollView comme parent, je viens d'ajouter Android:fitsSystemWindows="true" à ma vue parent (qui était un RelativeLayout et un adjustResize au manifeste pour l'activité et cela a fonctionné.

0
Josh Laird

Essayez de mettre votre LinearLayout sur un ScrollView qui a déjà fonctionné pour moi une fois.

0
Cata

J'ai dû mettre 

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

Malgré cela, je ne l'ai jamais définie sur true et l'application n'était pas en plein écran.

0
F0G