Ответ 1
Вы должны установить adjustViewBounds значение true.
imageView.setAdjustViewBounds(true);
Я хочу, чтобы ширина ImageView была задана родителем, а высота должна быть пропорциональна пропорциональности. Причиной этого является то, что в следующем показан TextView, который я хочу разместить прямо под ImageView.
Я могу правильно отобразить изображение, используя
android:layout_width="fill_parent"
android:layout_height="fill_parent"
однако высота ImageView становится родительской высотой, которая намного больше, чем высота показанного растянутого изображения. Одна из идей заключалась в том, чтобы сделать родителя меньшим по вертикали, но.. там я еще не знаю размер растянутого изображения.
Следующее не работает, потому что небольшое изображение не заполняется горизонтально.
android:layout_width="fill_parent"
android:layout_height="wrap_content"
Размещая
android:layout_height="wrap_content"
для RelativeLayout, окружающего все это, не помогает. Также попробовали FrameLayout и LinearLayout и не удалось.
Любые идеи?
Вы должны установить adjustViewBounds значение true.
imageView.setAdjustViewBounds(true);
Существует два случая, если ваш фактический размер изображения равен или больше, чем ширина и ширина изображения ImageView, тогда вы можете использовать свойство adjustViewBounds, и если ваш фактический размер изображения меньше ширины и высоты ImageView, чем использование свойства scaleType для показанного изображения в ImageView на основе вашего требования.
1. Размер соответствующего изображения равен или больше, чем требуемая ширина и высота ImageView.
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:src="@drawable/ic_launcher"/>
2. Размер фактического изображения меньше требуемой ширины и высоты ImageView.
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scaleType="fitXY"
android:src="@drawable/ic_launcher"/>
Таким образом, у меня была одна и та же проблема более одного раза, и при просмотре существующих ответов stackoverflow поняли, что никакой ответ не дает полного объяснения реальной путаницы в решении этой проблемы. Итак, вы идете:
imageView.setAdjustViewBounds(true);
ИЛИ (в XML)
android:adjustViewBounds="true"
решает проблему, она работает независимо от фактического размера ресурса изображения, т.е. масштабирует ваше изображение вверх или вниз до желаемого размера в вашем макете.
Ниже API 17 android:adjustViewBounds="true"
будет работать только для уменьшения изображения, а не для роста, т.е. если фактическая высота источника изображения меньше размеров, которые вы пытаетесь достичь в своем макете, wrap_content
будет использовать это меньшее высота и не масштабировать "вверх" (увеличить) изображение по вашему желанию.
Итак, для API 17 и ниже у вас нет выбора, кроме как использовать пользовательский ImageView для достижения такого поведения. Вы можете написать собственный ImageView самостоятельно или использовать библиотеку, которая уже выполнила эту работу.
Вероятно, существует несколько библиотек, устраняющих эту проблему, одна из которых:
compile 'com.inthecheesefactory.thecheeselibrary:adjustable-imageview:1.0.0'
который используется следующим образом:
<com.inthecheesefactory.thecheeselibrary.widget.AdjustableImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:src="@drawable/your_drawable"/>
альтернативно, используя существующую библиотеку, вы можете написать собственное представление самостоятельно, например:
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.ViewGroup;
import android.view.ViewParent;
import android.widget.ImageView;
public class ScalableImageView extends ImageView {
boolean adjustViewBounds;
public ScalableImageView(Context context) {
super(context);
}
public ScalableImageView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public ScalableImageView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
public void setAdjustViewBounds(boolean adjustViewBounds) {
this.adjustViewBounds = adjustViewBounds;
super.setAdjustViewBounds(adjustViewBounds);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
Drawable drawable = getDrawable();
if (drawable == null) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
return;
}
if (adjustViewBounds) {
int drawableWidth = drawable.getIntrinsicWidth();
int drawableHeight = drawable.getIntrinsicHeight();
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
if (heightMode == MeasureSpec.EXACTLY && widthMode != MeasureSpec.EXACTLY) {
int height = heightSize;
int width = height * drawableWidth / drawableHeight;
if (isInScrollingContainer())
setMeasuredDimension(width, height);
else
setMeasuredDimension(Math.min(width, widthSize), Math.min(height, heightSize));
} else if (widthMode == MeasureSpec.EXACTLY && heightMode != MeasureSpec.EXACTLY) {
int width = widthSize;
int height = width * drawableHeight / drawableWidth;
if (isInScrollingContainer())
setMeasuredDimension(width, height);
else
setMeasuredDimension(Math.min(width, widthSize), Math.min(height, heightSize));
} else {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
} else {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
private boolean isInScrollingContainer() {
ViewParent parent = getParent();
while (parent != null && parent instanceof ViewGroup) {
if (((ViewGroup) parent).shouldDelayChildPressedState()) {
return true;
}
parent = parent.getParent();
}
return false;
}
}
... который вы использовали бы следующим образом (XML):
<com.YOUR_PACKE_NAME.ScalableImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:src="@drawable/your_drawable" />
Это был единственный способ заставить его работать, чтобы второй ImageView был в центре и меньше, чем первый ImageView, и TextView под вторым ImageView.
К сожалению, он использует фиксированный размер изображения "200dp" во втором ImageView, поэтому он не выглядит одинаковым на устройствах различного размера.
Он также разрушает мой ViewFlipper, поскольку любой макет, который я пробовал во втором ImageView и TextView, делает их перемещением или изменением размера.
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<ImageView
android:id="@+id/imageview1"
android:contentDescription="@string/desc"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:src="@drawable/background" />
<ImageView
android:id="@+id/imageview2"
android:layout_centerInParent="true"
android:contentDescription="@string/desc"
android:layout_height="200dp"
android:layout_width="200dp"
android:adjustViewBounds="true"
android:src="@drawable/image2" />
<TextView
android:id="@+id/textview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_below="@id/imageview2"
android:paddingLeft="8dp"
android:paddingRight="8dp"
android:gravity="center"
android:textSize="26sp"
android:textColor="#333"
android:background="#fff"
android:text="this is the text under the image right here"
/>
</RelativeLayout>