Почему мне нужно обернуть 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
, чтобы иметь что-то по своему усмотрению? Большое вам спасибо.
Ответы
Ответ 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.