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

Высота изображения в виде обертывания отображаемого изображения

Я хочу, чтобы ширина 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 и не удалось.

Любые идеи?

4b9b3361

Ответ 1

Вы должны установить adjustViewBounds значение true.

imageView.setAdjustViewBounds(true);

Ответ 2

Существует два случая, если ваш фактический размер изображения равен или больше, чем ширина и ширина изображения 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"/>

Ответ 3

Таким образом, у меня была одна и та же проблема более одного раза, и при просмотре существующих ответов stackoverflow поняли, что никакой ответ не дает полного объяснения реальной путаницы в решении этой проблемы. Итак, вы идете:

API 17 +

imageView.setAdjustViewBounds(true);

ИЛИ (в XML)

android:adjustViewBounds="true"

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

Ниже API 17

Ниже 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" />

Ответ 4

Это был единственный способ заставить его работать, чтобы второй 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>