Question Pourquoi dois-je envelopper un ImageView dans un FrameLayout?


Voici une mise en page simple:

      <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

            <ImageView
                android:id="@+id/companyIcon"
                android:layout_width="wrap_content"
                android:layout_height="40dp" <!-- notice I've limited a height -->
                android:scaleType="fitStart"
                android:adjustViewBounds="true"
                android:layout_alignParentLeft="true" />

            <TextView
                android:id="@+id/companyName"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_toRightOf="@id/companyIcon"
                android:layout_marginLeft="3dp"
                android:layout_centerVertical="true"
                android:textStyle="bold"
                android:textColor="#20526d" />
        </RelativeLayout>

La hauteur d'une image que je définirai par setImageBitmap() est plus que 40dp. En utilisant cette disposition, j'ai un espace supplémentaire entre ImageView et TextView, d'où vient-il? enter image description here

Mais après avoir enveloppé le ImageView avec FrameLayout Je n'ai pas cet espace supplémentaire inutile:

<RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

            <FrameLayout
                android:id="@+id/image_container"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content">

                <ImageView
                    android:id="@+id/companyIcon"
                    android:layout_width="wrap_content"
                    android:layout_height="40dp"
                    android:scaleType="fitStart"
                    android:adjustViewBounds="true"
                    android:layout_alignParentLeft="true" />
            </FrameLayout>

            <TextView
                android:id="@+id/companyName"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_toRightOf="@id/image_container"
                android:layout_marginLeft="3dp"
                android:layout_centerVertical="true"
                android:textStyle="bold"
                android:textColor="#20526d" />
        </RelativeLayout>

Et le résultat:

enter image description here

Pouvez-vous les gars expliquer pourquoi devrais-je mettre ImageView dans FrameLayout avoir les choses comme prévu? Merci beaucoup.


29
2018-01-30 16:40


origine


Réponses:


La hauteur d'une image que je vais définir avec setImageBitmap () est supérieure à 40dp. En utilisant cette disposition, j'ai un espace supplémentaire entre ImageView et TextView, d'où vient-il?

Depuis le android:layout_height="40dp" avec un android:scaleType="fitStart", l'image est réduite (et à gauche / commencer) pour s'adapter à la hauteur, donc cet "espace supplémentaire" est en fait la largeur d'origine de l'image, puisque votre android:layout_width="wrap_content". J'ai recréé votre mise en page avec ma propre image plus grande que 40dp. Lorsque vous sélectionnez le ImageView, vous pouvez voir que ses limites s'étendent à la largeur d'origine de l'image.

Original Layout

Pour le prouver davantage, si je mets android:scaleType="center", aucun ajustement n'est appliqué et vous pouvez voir le ImageViewLargeur d'origine.

Original Layout not scaled to fit 

Pouvez-vous expliquer pourquoi je devrais mettre ImageView dans FrameLayout pour avoir les choses comme prévu?

Il semble que depuis votre FrameLayout les usages android:layout_width="wrap_content", il obtient la largeur correcte réduite de votre ImageView après avoir été mis à l'échelle en raison de android:adjustViewBounds="true". Il est étrange que le ImageView lui-même utilise android:layout_width="wrap_content", mais affiche la largeur de l'image d'origine et non la largeur mise à l'échelle. ma pressentiment est que la hauteur et la largeur de ImageViews se préparer avant la mise à l'échelle est appliquée, de sorte que le ImageView obtient la largeur de l'image d'origine, mais le parent FrameLayout obtient la largeur mise à l'échelle ImageView enfant après la mise à l'échelle est appliquée. Cela peut ne pas être vrai, mais cela me semble être le cas.

Cependant, vous pouvez résoudre le problème de la largeur non calibrée (sans utiliser de FrameLayout) en utilisant android:maxHeight="40dp" sur le ImageView. Vous pouvez ensuite définir android:layout_height="wrap_content" de sorte que vos images peuvent être plus petites que 40dp si l'image est plus petite.

<ImageView
    android:id="@+id/companyIcon"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentLeft="true"
    android:adjustViewBounds="true"
    android:maxHeight="40dp"
    android:scaleType="fitStart" />

Original Layout using maxHeight


30
2018-02-14 01:08



Cela s'applique à presque toute la vue mais la réponse est écrite en tenant compte spécifiquement ImageView 

Ligne directrice pour définir la hauteur et la largeur

Choisissez l'une de ces trois options uniquement.

  1. Ensemble tous les deux hauteur et largeur à "WRAP_CONTENT"
  2. Ensemble tous les deux hauteur et largeur à "FILL_PARENT"
  3. Ensemble tous les deux hauteur et largeur à "FIXED SIZE"

    *Éviter en utilisant un mélange d'entre eux dire Width=WRAP_CONTENT and Height=FILL_PARENT 

Directive pour définir SCALETYPE pour ImageView

Que fait ScaleType?

Il redimensionne l'image que vous définissez sur ImageView, il ne redimensionne pas   ImageView, donc lorsque vous le définissez sur fitStart, vous pourrez redimensionner votre image et   montrer à droite mais votre imageView restera la même en termes de   hauteur et largeur comme vous l'avez spécifié.

Comme si vous utilisiez WRAP_CONTENT pour la hauteur et la largeur vous n'a pas besoin de spécifier ScaleType parce que votre ImageView sera automatiquement aussi grand que votre image.

Comme si vous utilisiez FILL_PARENTpour la hauteur et la largeur, vous aurez la possibilité d'afficher l'image au centre, au début, à la fin ou en plein écran. sur cette base, vous pouvez choisir votre ScaleType.

Comme si vous utilisiez FIXED_SIZE fpr hauteur et largeur vous devrait opter pour scaletype=FITXY.


Directive pour définir l'image dans ImageView 

Comme si vous définissez l'image statiquement en XML alors vous avez une image sur votre main afin que vous puissiez créer une image de la taille que vous souhaitez selon votre conception et juste aller de l'avant avec WRAP_CONTENT.

Comme si vous définissiez l'image à temps d'exécution après l'avoir téléchargé de quelque part, cette fois télécharger l'image et créer un bitmap de la taille vous préférez, puis réglez-le sur ImageView


Spécifique à votre cas

Vous pouvez voir que votre image est assez étendue et que le texte n'est pas lisible car vous avez téléchargé et défini l'image telle qu'elle est, mais en hauteur et en largeur plus petites.

Définissez la hauteur et la largeur de ImageView sur WRAP_CONTENT en fichier XML

                    <ImageView
                    android:id="@+id/companyIcon"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_alignParentLeft="true" />

Télécharger l'image dans la taille requise, par exemple 50X100, par exemple voir ce code

class LoadPics extends AsyncTask<Void, Bitmap, Bitmap> {
    String urlStr;
    ImageView iv;
    int width, height;

    public LoadPics(ImageView iv, String url, int width, int height) {
        this.iv = iv;
        this.urlStr = url;
        this.width = width;
        this.height = height;
    }

    @Override
    protected Bitmap doInBackground(Void... params) {
        try {
                InputStream in = null;
                try {
                    URL url = new URL(urlStr);
                    URLConnection urlConn = url.openConnection();
                    HttpURLConnection httpConn = (HttpURLConnection) urlConn;
                    httpConn.connect();
                    in = httpConn.getInputStream();
                } catch (MalformedURLException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }

                BitmapFactory.Options o = new BitmapFactory.Options();
                o.inJustDecodeBounds = true;

                int scale = 2;
                if (o.outHeight > width || o.outWidth > height) {
                    scale = 2 ^ (int) Math.ceil(Math.log(width
                            / (double) Math.max(o.outHeight, o.outWidth))
                            / Math.log(0.5));
                }

                if (scale <= 1 && o.outHeight > 150) {
                    scale = 5;
                }

                BitmapFactory.Options o2 = new BitmapFactory.Options();
                o2.inSampleSize = scale;
                Bitmap b1 = BitmapFactory.decodeStream(in, null, o2);
                b1 = Bitmap.createScaledBitmap(b1, width, height, true);
                loader.addToCache(urlStr, b1);
                publishProgress(b1);

        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    protected void onProgressUpdate(Bitmap... values) {
        super.onProgressUpdate(values);
        iv.setImageBitmap(values[0]);
    }
}

Et appelez cette méthode avec vos arguments,

new LoadPics(ivUser,imgURL,100,50).execute();

4
2018-02-14 06:55



essayer de remplacer android:scaleType="fitStart" avec ça android:scaleType="fitXY" 


modifier

dans votre vue d'image, vous devez définir la largeur de imagView à wrap-content Cela prendra la taille de l'image. Si vous codez en dur le imageView's largeur (comme vous l'avez fait en donnant la largeur à 40dp) alors cela ne sera pas si bien dans d'autres appareils mobiles Android.

Encore si vous voulez le faire alors Essayez de charger l'image de moindre résolution. si cette image est 200X100 en résolution, puis essayez de charger l'image de 100X50 dans ton ImageView


1
2018-01-30 17:31



Si tu fais android:scaleType="FIT_END", sans le FrameLayout, est-ce que cela met l'image du métro près du texte "Subway"? Je me demande, parce que vous avez android:layout_alignParentLeft="true" là-bas. Je pense que le ImageViewla taille originale avant la mise à l'échelle est ce qui jette la mise en page sans FrameLayout.

Cela n’a probablement pas d’importance, mais il faut un certain traitement pour redimensionner et redimensionner l’image en fonction de vos besoins. S'il est viable pour ce que vous voulez faire, je redimensionnerais simplement l'image moi-même au lieu d'utiliser XML. Si je voulais répondre à plusieurs tailles, j'aurais deux ou trois mises en page différentes. Cela peut être exagéré pour votre objectif, je ne sais pas.


0
2018-01-30 22:16



Un espace supplémentaire est venu en première image car vous définissez le parent correspondant dans la disposition du conteneur d'image. mais en second lieu, vous avez utilisé un contenu wrap dans FrameLayout, qui est un conteneur d’image.

Ma suggestion de faire ces choses Créer une disposition relative d'initié de mise en page linéaire et appliquer la disposition layout_weight de sorte que le rapport sera le même dans les deux vues.


0
2018-02-12 06:03



essayez de définir le type d'échelle sur center_inside.


0
2018-02-14 02:46