Подтвердить что ты не робот

Почему мне нужно обернуть ImageView в FrameLayout?

Вот простой макет:

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

Высота изображения, установленного параметром setImageBitmap(), больше 40dp. Используя этот макет, у меня есть дополнительное пространство между ImageView и TextView, откуда оно взялось? enter image description here

Но после того, как я обернул ImageView с помощью FrameLayout, у меня нет лишнего лишнего места:

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

И результат:

enter image description here

Можете ли вы, ребята, объяснить, зачем мне помещать ImageView в FrameLayout, чтобы иметь что-то по своему усмотрению? Большое вам спасибо.

4b9b3361

Ответ 1

Высота изображения, заданного setImageBitmap(), больше 40dp. Используя этот макет, у меня есть дополнительное пространство между ImageView и TextView, откуда оно взялось?

Поскольку android:layout_height="40dp" с android:scaleType="fitStart", изображение становится уменьшенным (и влево/в начале), чтобы соответствовать высоте, поэтому это "дополнительное пространство" на самом деле является исходной шириной изображения, поскольку ваш android:layout_width="wrap_content". Я воссоздал ваш макет с моим собственным изображением, которое больше, чем 40dp. Когда вы выберете ImageView, вы увидите, что его границы простираются до ширины оригинала изображения.

Original Layout

Чтобы еще раз доказать это, если я устанавливаю android:scaleType="center", пригонка не применяется, и вы можете видеть исходную ширину ImageView.

Original Layout not scaled to fit

Можете ли вы, ребята, объяснить, почему я должен поместить ImageView в FrameLayout, чтобы иметь все, что нужно?

Похоже, что поскольку ваш FrameLayout использует android:layout_width="wrap_content", он получает правильную уменьшенную ширину с вашего ImageView после того, как он будет масштабироваться из-за android:adjustViewBounds="true". Странно, что ImageView сам использует android:layout_width="wrap_content", но показывает исходную ширину изображения, а не масштабированную ширину. Моя догадка заключается в том, что высота и ширина ImageView устанавливаются до, применяется масштабирование, поэтому ImageView получает исходную ширину изображения, но родительский FrameLayout получает масштабированную ширину ImageView дочернего после, применяется масштабирование. Это может быть неверно, но мне кажется, что это так.

Однако вы можете решить проблему без масштабирования (без использования FrameLayout), используя android:maxHeight="40dp" в ImageView. Затем вы можете установить android:layout_height="wrap_content", чтобы ваши изображения могли быть меньше 40dp, если изображение меньше.

<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

Ответ 2

Это относится практически ко всем представлениям, но ответ написан специально с учетом ImageView

Руководство по установке высоты и ширины

Выберите только один из этих трех вариантов.

  • Установите как высоту и ширину на "WRAP_CONTENT"
  • Установите как высоту, так и ширина до "FILL_PARENT"
  • Установите как высоту и ширину на "FIXED SIZE"

    * Избегайте, используя смесь из них: Width=WRAP_CONTENT and Height=FILL_PARENT

Руководство по установке SCALETYPE для ImageView

Что делает ScaleType?

Он масштабирует изображение, установленное в ImageView, оно не масштабируется ImageView, поэтому, когда вы установите его для fitStart, он масштабирует ваше изображение и показать справа, но ваше изображениеView останется таким же с точки зрения высота и ширина, как вы указали.

Как будто вы используете WRAP_CONTENT для высоты и ширины, вам не нужно указывать ScaleType, потому что ваш ImageView будет автоматически больше вашего изображения.

Как будто вы используете FILL_PARENT для высоты и ширины, у вас будет возможность отображать изображение в Центре, Старт, Конец или Полном просмотре.. поэтому на основе этого вы можете выбрать свой ScaleType.

Как будто вы используете высоту и ширину FIXED_SIZE fpr, вы должны выбрать scaletype=FITXY.


Руководство по установке изображения в ImageView

Как будто вы устанавливаете образ статически в XML, тогда у вас есть одно изображение на руке, чтобы вы могли создать изображение размера, которое вы хотите, в соответствии с вашим дизайном макета, и просто перейти с помощью WRAP_CONTENT.

Как будто вы устанавливаете изображение в время выполнения после его загрузки откуда-то, тогда загрузите изображение и создайте растровое изображение размера, которое вы предпочитаете, а затем установите его в ImageView


Конкретно для вашего случая

Вы можете видеть, что ваше изображение довольно растянуто, и текст не читается, потому что вы загрузили и установили изображение как есть, но с меньшей высотой и шириной.. скорее вы должны были сделать, например,

Установить высоту и ширину ImageView в WRAP_CONTENT в файле XML

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

Загрузите изображение в требуемом размере, скажем, 50X100, например, посмотрите этот код

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]);
    }
}

И вызовите этот метод с вашими аргументами,

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

Ответ 3

попробуйте заменить android:scaleType="fitStart" на это android:scaleType="fitXY"


Edit

в представлении изображения вы должны установить ширину imagView в wrap-content, это займет размер изображения. Если вы жестко кодируете ширину imageView's (как вы это сделали, указав ширину 40dp), это не будет выглядеть так хорошо в других мобильных устройствах Android.

Тем не менее, если вы хотите сделать это, попробуйте загрузить изображение с меньшим разрешением. если это изображение 200X100 в разрешении, попробуйте загрузить изображение 100X50 в ImageView

Ответ 4

Если вы выполняете android:scaleType="FIT_END", без FrameLayout, то ли это изображение Subway находится рядом с текстом "Subway"? Интересно, потому что у вас там android:layout_alignParentLeft="true". Я думаю, что исходный размер ImageView до масштабирования - это то, что выбрасывает макет без FrameLayout.

Вероятно, это не имеет большого значения, но для масштабирования и изменения размера изображения требуется какая-то обработка для того, что вы хотите. Если это жизнеспособно для того, что вы хотите сделать, я бы просто изменил размер изображения самостоятельно, вместо того, чтобы полагаться на XML. Если бы я хотел удовлетворить несколько размеров, у меня было бы несколько разных макетов. Это, конечно, может быть излишним для вашей цели, я не знаю.

Ответ 5

Дополнительное пространство появилось на первом изображении, потому что u задал соответствие родительскому в макете контейнера изображения. но второй u использует содержимое обертки в FrameLayout, которое является контейнером изображений.

Мое предложение сделать это. Создайте линейный макет с относительной компоновкой макета и примените layout_weight propert, поэтому отношение будет одинаковым в обоих представлениях.

Ответ 6

попробуйте установить тип шкалы в center_inside.