web-dev-qa-db-fra.com

L'activité avec des fragments ne redimensionne pas à l'ouverture du clavier

Dans mon activité principale, il y a une RelativeLayout qui a 2 enfants:

  • Un ImageView qui sert de fond
  • Un LinearLayout qui a 2 conteneurs de fragments

activity_main.xml

<RelativeLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
    xmlns:tools="http://schemas.Android.com/tools"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    Android:layout_gravity="bottom"
    tools:context="${packageName}.${activityClass}">

    <ImageView
        Android:layout_width="match_parent"
        Android:layout_height="match_parent"
        Android:adjustViewBounds="true"
        Android:baselineAlignBottom="false"
        Android:scaleType="fitStart"
        Android:src="@drawable/bg_image" />

    <LinearLayout
        Android:layout_width="match_parent"
        Android:layout_height="match_parent"
        Android:orientation="vertical"
        Android:paddingTop="?android:attr/actionBarSize"
        Android:layout_alignParentBottom="true">

        <LinearLayout
            Android:id="@+id/ContainerA"
            Android:layout_width="match_parent"
            Android:layout_height="wrap_content"
            Android:layout_gravity="center"
            Android:orientation="vertical" />

        <LinearLayout
            Android:id="@+id/ContainerB"
            Android:layout_width="match_parent"
            Android:layout_height="match_parent"
            Android:background="@color/background_gray"
            Android:orientation="vertical" />

    </LinearLayout>
</RelativeLayout>

Le conteneur A montre simplement un fragment qui ne change pas.
Cependant, le conteneur B contient un fragment qui change en fonction des clics de l'utilisateur. 

Le conteneur B change de 2 manières:

  • Il peut s'étendre (d'une hauteur d'environ 70% à la hauteur totale).
  • Ça change des fragments.

L'un des fragments que le conteneur B peut contenir est un formulaire, qui contient EditTexts et d'autres vues. 

Mon problème est que je ne parviens pas à redimensionner l'activité lorsque le clavier est ouvert.
J'ai placé adjustResize dans le fichier manifeste et mon thème n’est pas un thème plein écran (c’est apparemment une cause de ce problème). J'ai aussi essayé de modifier les vues, d'ajouter ScrollViews mais rien ne fonctionnait. 

Le thème que j'utilise pour cette activité est le thème clair avec la barre d’action sombre de la bibliothèque AppCompat. J'ai uniquement modifié le thème pour autoriser une barre d'action superposée. C'est pas le problème car j'ai déjà essayé de supprimer ces modifications en vain.

Voici un lien vers la disposition du formulaire

TL; DRadjustResizeadjustPan ne fonctionnent pas pour moi. Recherché, essayé diverses solutions, rien n'a fonctionné. Ma question est; quelle est la cause de cela dans mon cas?

Mise à jour: AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:Android="http://schemas.Android.com/apk/res/Android" ...>

    <uses-sdk Android:minSdkVersion="11" Android:targetSdkVersion="19" />

    <application ... Android:theme="@style/AppTheme">
        <activity Android:name=".SplashScreenActivity"
            Android:label="@string/app_name"
            Android:screenOrientation="portrait"
            Android:theme="@Android:style/Theme.Black.NoTitleBar">
            <intent-filter>
                <action Android:name="Android.intent.action.MAIN" />

                <category Android:name="Android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity Android:name=".MainActivity"
            Android:configChanges="keyboardHidden|screenSize" Android:label="@string/app_name"
            Android:screenOrientation="portrait" Android:theme="@style/OverlayActionBarTheme"
            Android:windowSoftInputMode="adjustResize"  />
        <activity Android:name=".SettingsActivity"
            Android:label="@string/title_activity_settings"
            Android:parentActivityName=".MainActivity"
            Android:windowSoftInputMode="adjustResize">
            <meta-data Android:name="Android.support.PARENT_ACTIVITY"
                Android:value=".MainActivity" />
        </activity>
    </application>

</manifest>

_/Mise à jour 2:
J'ai créé une toute nouvelle application, ajouté la mise en page en tant que mise en page principale et testé si le problème venait de la mise en page elle-même. Il s'avère que c'est, car même sur cette application nouvellement créée, elle ne semble pas redimensionner.

Comme indiqué ci-dessus, le lien vers la mise en page peut être trouvé ici

Mise à jour 3: J'ai réussi à le faire fonctionner sur la nouvelle application en entourant toute la mise en page avec une ScrollView. Je ne pouvais pas reproduire le même effet dans l'application d'origine pour une raison quelconque ... essayant toujours de comprendre pourquoi.

15
Asaf

Lorsque le clavier virtuel apparaît à l'écran, la quantité d'espace disponible pour l'interface utilisateur de l'application diminue. Le système décide comment organiser l'espace disponible entre l'interface utilisateur de l'application et le clavier logiciel. 

  • Si le contenu de la fenêtre contient ListView, ScrollView, la fenêtre de l'application est redimensionnée à condition que tout le contenu soit visible.
  • Si le redimensionnement n'est pas réalisable, l'approche pan and scan est utilisée. Elle consiste simplement à faire défiler la fenêtre de l'application afin que la vue actuellement activée soit visible. 

Etant donné que votre mise en page ne contient aucune ListView, ScrollView, le redimensionnement est exclu.

La vue racine de la fenêtre est une FrameLayout à laquelle vous aviez initialement ajouté LinearLayout. Puisque LinearLayout ne prend pas en charge le défilement, l’approche pan and scan est également exclue. Envelopper la présentation dans ScrollView résout donc le problème du défilement.

Vous pouvez consulter Blog des développeurs Android pour plus de détails.

Mise à jour 1:

OP a pu résoudre le problème, comme indiqué dans cette réponse . Le problème se posait car un fragment recouvrait un autre fragment après animation et que le parent de ces Fragment était un LinearLayout. Pour pouvoir superposer, vous devez utiliser RelativeLayout ou FrameLayout uniquement.

19
Manish Mulimani

Pour changer le mode en «redimensionner» à l'instruction suivante de votre activité dans «AndroidManifest.xml».

 <activity Android:name=".ActivityName"
        Android:windowSoftInputMode="adjustResize">

et veuillez supprimer la complexité de LinearLayout (cela signifie que vous utilisez plusieurs niveaux de LinearLayout) au lieu de pouvoir utiliser RelativeLayout également .. en utilisant cela, vous pouvez facilement configurer la disposition comme vous le souhaitez .. essayez-le en espérant que votre problème disparaisse 

J'espère que ça aide. 

11
Vaishali Sutariya

Vous pouvez aussi utiliser ce code dans votre fragment

Ce code fournit une aide pour redimensionner la vue

public static class MyDialog extends DialogFragment {

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

    // Dialog layout inflater code
    // getDialog() need to be called only after onCreateDialog(), which is invoked between onCreate() and onCreateView(). 
      getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN |     WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
   // return view code
  }
}
9
Ramkailash

utilisez cette ligne dans votre fichier de manifeste contre votre activité dans laquelle vous voulez que votre résultat espérons que cela vous aidera

   Android:windowSoftInputMode="adjustPan|stateAlwaysHidden" 

comme

  <activity
            Android:name="com.Android.youractivity"
            Android:windowSoftInputMode="adjustPan|stateAlwaysHidden" />

Il s'avère que mon problème a été causé par une source complètement inattendue. 

Ce qui s’est passé, c’est que j’ai utilisé une LinearLayout comme parent de mes deux conteneurs de fragments.
Ensuite, dans mon animation en expansion, j'ai soulevé le conteneur du bas pour recouvrir le second.

Je ne sais pas vraiment pourquoi mais puisque LinearLayout n'est pas censé retenir les enfants qui se chevauchent, passer à RelativeLayout ou à FrameLayout a immédiatement résolu le problème.

Étant donné que cette cause pourrait ne pas apparaître clairement dans le code que j'ai publié, je tiens à m'excuser pour le manque d'informations et à créditer la réponse la plus détaillée comme la meilleure.

4
Asaf