ImageView не масштабируется на устройствах с большим экраном - PullRequest
3 голосов
/ 03 марта 2012

Вот мой основной макет:

<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">

    <ImageView
    android:adjustViewBounds="true"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:src="@drawable/welcome_hero" />

</LinearLayout>

Я хочу, чтобы изображение масштабировалось, сохраняя пропорции по размеру экрана, опуская любые последующие виды.

Это прекрасно работает на моих устройствах mdpi (LG LGP509) и hdpi (HTC G2, Nexus One). Тем не менее, на мой Galaxy Nexus (xhdpi), изображение упорно не масштабируется, чтобы соответствовать. Оставляет дополнительное пространство по бокам.

Вот еще немного информации:

  • макет находится в общем макете / папке

  • welcome_hero.png находится в папке drawables / и имеет ширину 320px и высоту 161px

В AndroidManifest.xml есть эта запись:

<uses-sdk
android:targetSdkVersion="10"
android:minSdkVersion="8" />

<supports-screens
android:xlargeScreens="true"
android:largeScreens="true"
android:normalScreens="true"
android:smallScreens="false" />

Некоторые вещи, которые я пробовал:

  • Изменение масштаба типа на fitCenter, fitInside или matrix дало те же результаты, что и без
  • изменяя высоту ImageView на fill_parent, правильно масштабировал изображение, но отталкивал все другие виды от экрана
  • угрожающий монитор с применением физического насилия оставил меня более расстроенным
  • явно установить высоту и ширину в 320dp, а 161dp ничего не изменилось
  • как уже упоминалось выше, я пробовал новые макеты как в программе просмотра IntelliJ, так и на физических устройствах

Я прохожу через StackOverflow около 1,5 часов, сейчас смотрю на сотни сообщений, которые кажутся похожими на мои, но ни одна из них, похоже, не работает на Galaxy Nexus. Я отчаянно пытаюсь быть хорошим разработчиком и доводить свои вещи до новых телефонов, но это оказывается трудным.

Ответы [ 4 ]

3 голосов
/ 03 марта 2012

Возможно, вы хотите установить android:adjustViewBounds в true. Сохраняйте свою ширину fill_parent и высоту wrap_content. Возможно, вам все равно придется поиграть с вашим scaleType, чтобы заставить его работать, как и ожидалось, хотя при таком подходе масштабирование сложнее.

Другой вариант - создать свой собственный подкласс ImageView. Следующее работает хорошо для меня, но может потребоваться некоторая модификация для вашего конкретного случая.

public class AspectRatioImageView extends ImageView {
    private final boolean horizontal;

    public AspectRatioImageView(Context context) {
        this(context, null);
    }

    public AspectRatioImageView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public AspectRatioImageView(Context context, AttributeSet attrs,
            int defStyle) {
        super(context, attrs, defStyle);
        TypedArray array = context.obtainStyledAttributes(attrs,
                R.styleable.AspectRatioImageView, defStyle, 0);
        int h = array
                .getInt(R.styleable.AspectRatioImageView_fixedDimension, 0);
        horizontal = (h == 0);
        array.recycle();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        boolean widthExactly = MeasureSpec.getMode(widthMeasureSpec) == MeasureSpec.EXACTLY;
        boolean heightExactly = MeasureSpec.getMode(heightMeasureSpec) ==           MeasureSpec.EXACTLY;

        float ratio;
        try {
            ratio = ((float) ((BitmapDrawable) getDrawable())
                    .getIntrinsicWidth())
                    / ((float) ((BitmapDrawable) getDrawable())
                            .getIntrinsicHeight());
        } catch (ClassCastException e) {
            ratio = MeasureSpec.getSize(widthMeasureSpec)
                    / MeasureSpec.getSize(heightMeasureSpec);
        }

        int heightRatioSpec = MeasureSpec.makeMeasureSpec(
                (int) (MeasureSpec.getSize(widthMeasureSpec) / ratio),
                MeasureSpec.EXACTLY);   

        int widthRatioSpec = MeasureSpec.makeMeasureSpec(
                (int) (MeasureSpec.getSize(heightMeasureSpec) * ratio),
                MeasureSpec.EXACTLY);   

        if (widthExactly) {
            if (heightExactly) {
                super.onMeasure(widthMeasureSpec, heightMeasureSpec);
            } else {
                super.onMeasure(widthMeasureSpec, heightRatioSpec);
            }
        } else {
            if (heightExactly) {
                super.onMeasure(widthRatioSpec, heightMeasureSpec);
            } else {
                if (horizontal) {
                    super.onMeasure(widthMeasureSpec, heightRatioSpec);
                } else {
                    super.onMeasure(widthRatioSpec, heightMeasureSpec);
                }
            }
        }
    }
}

Вам также необходимо добавить

<declare-styleable name="AspectRatioImageView">
    <attr format="enum" name="fixedDimension">
        <enum name="horizontal" value="0" />
        <enum name="vertical" value="1" />
    </attr>
</declare-styleable>

в /values/attr.xml, чтобы вы могли использовать атрибут app:fixedDimension=horizontal, чтобы он знал, чтобы масштабировать вертикальное измерение.

3 голосов
/ 03 марта 2012

Используйте комбинацию разметки макета и кода для масштабирования:

оставьте ваши layout_width = "fill_parent" и layout_height = "wrap_content".Добавьте

android:scaleType="fitXY"

в своем коде:

ImageView mImageView = findViewById (R.id.yourimageid);
LayoutParams lp = mImageView.getLayoutParams();
lp.height = (int)((float)context.getWindowManager().getDefaultDisplay().getWidth() *
    ((float)mImageView.getDrawable().getIntrinsicHeight() / (float)mImageView.getDrawable().getIntrinsicWidth()));
mImageView.setLayoutParams(lp);

т.е. вы устанавливаете новое значение для layout_height путем умножения ширины экрана * на отношение высоты изображения к ширине.

1 голос
/ 03 марта 2012

То есть вы хотите, чтобы ваш вид растягивался на ширину экрана, а затем на любую высоту, необходимую для сохранения исходного соотношения сторон на этой ширине?

Я полагаю, установка масштаба типа Центра внутри сделает эту работу. Центр урожая стоит попробовать, если центр внутри не работает. Смотри: http://developer.android.com/reference/android/widget/ImageView.ScaleType.html

0 голосов
/ 03 марта 2012

вместо использования android:src в вашем imageView XML, используйте android:background.Это должно решить проблемы с масштабом.

см. Здесь: В чем разница между src и фоном ImageView

...