Android ImageView с настройкой высоты и ширины установки
Обновление: я решил эту проблему, используя метод, описанный в этом ответе
Я немного застрял в этом вопросе, который, я думаю, должен быть довольно простым.
Итак, мое приложение загружает изображение и отображает растровое изображение в ImageView, дочернем элементе RelativeLayout.
Я бы хотел, чтобы ImageView соответствовал ширине родительского элемента и адаптировал его размер, чтобы сохранить соотношение сторон.
Вот мой XML:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<RelativeLayout android:id="@+id/banner" android:layout_width="fill_parent" android:layout_height="wrap_content"></RelativeLayout>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello"
/>
</LinearLayout>
И код:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
RelativeLayout banner = (RelativeLayout) findViewById(R.id.banner);
ImageView imgV = new ImageView(this);
imgV.setScaleType(ImageView.ScaleType.CENTER_CROP);
// I tried all the scale types : CENTER_INSIDE : same effect, FIT_CENTER : same effect...
imgV.setBackgroundColor(0x00FFFF00);
imgV.setAdjustViewBounds(Color.BLUE);
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.FILL_PARENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
banner.addView(imgV,params);
// Some code downloading the image stream
bitmap = BitmapFactory.decodeStream(stream);
imgV.setImageBitmap(bitmap);
}
Желаемый:
![Desired result]()
Результат:
![Current result]()
Ответы
Ответ 1
Благодаря @Julien и @js.
Вот полное решение ImageView, которое будет растягивать соотношение сторон, поддерживающее высоту, даже если растровое изображение меньше, чем ImageView.
public class ResizableImageView extends ImageView {
public ResizableImageView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec){
Drawable d = getDrawable();
if(d!=null){
// ceil not round - avoid thin vertical gaps along the left/right edges
int width = MeasureSpec.getSize(widthMeasureSpec);
int height = (int) Math.ceil((float) width * (float) d.getIntrinsicHeight() / (float) d.getIntrinsicWidth());
setMeasuredDimension(width, height);
}else{
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
}
Вы можете использовать этот класс в своих макетах xml вместо ImageView.
<com.example.ResizableImageView
android:id="@+id/banner"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:src="@drawable/banner" />
Ответ 2
Вероятно, вы ищете android:adjustViewBounds="true"
в xml или imageView.setAdjustViewBounds(true)
в Java.
Ответ 3
Как я уже упоминал в комментарии, я подклассифицировал ImageView. Я нашел свой код, вот вы:
protected class ResizableImageView extends ImageView
{
private Bitmap mBitmap;
// Constructor
public ResizableImageView(Context context)
{
super(context);
}
// Overriden methods
@Override
protected void onMeasure(int widthMeasureSpec,
int heightMeasureSpec) {
if(mBitmap != null)
{
int width = MeasureSpec.getSize(widthMeasureSpec);
int height = width * mBitmap.getHeight() / mBitmap.getWidth();
setMeasuredDimension(width, height);
}
else
{
super.onMeasure(widthMeasureSpec,
heightMeasureSpec);
}
}
@Override
public void setImageBitmap(Bitmap bitmap)
{
mBitmap = bitmap;
super.setImageBitmap(bitmap);
}
}
Ответ 4
Я думаю, вы должны изменить ширину imgV на "match_parent"
Вы должны изменить тип шкалы на imgV.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
Ответ 5
Я сделал небольшое изменение в решении @Seraphim S, чтобы учесть случаи, когда изображение может быть широким, а также ограничением просмотра (например, поворот устройства в альбомный режим).
public class ResizableImageView extends ImageView {
public ResizableImageView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
Drawable d = getDrawable();
if (d != null) {
int width = MeasureSpec.getSize(widthMeasureSpec);
int height = MeasureSpec.getSize(heightMeasureSpec);
if (width >= height) {
width = (int) Math.ceil((float) height * (float) d.getIntrinsicWidth() / (float) d.getIntrinsicHeight());
} else {
height = (int) Math.ceil((float) width * (float) d.getIntrinsicHeight() / (float) d.getIntrinsicWidth());
}
setMeasuredDimension(width, height);
} else {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
}