ImageView - имеют ширину соответствия по высоте?

У меня есть изображение. Я хочу, чтобы его ширина была заполнена. Я хочу, чтобы его высота была такой, какой бы ни была ширина. Например:

<ImageView
  android:layout_width="fill_parent"
  android:layout_height="whatever the width ends up being" />

Возможно ли что-то подобное в файле макета, не создавая собственный класс вида?

Спасибо

Ответ 1

Обновление: 14 сентября 2017 г.

В соответствии с приведенным ниже комментарием, библиотека поддержки процентов устарела, как в Android Support Library 26.0.0. Это новый способ сделать это:

<android.support.constraint.ConstraintLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="0dp"
        app:layout_constraintDimensionRatio="1:1" />

</android.support.constraint.ConstraintLayout>

Смотрите здесь

Устаревшие:

В соответствии с этим сообщением разработчиками Android все, что вам нужно сделать, это обернуть все, что вы хотите, в PercentRelativeLayout или PercentFrameLayout, и затем укажите его отношения, например:

<android.support.percent.PercentRelativeLayout 
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <ImageView
        app:layout_widthPercent="100%"
        app:layout_aspectRatio="100%"/>

</android.support.percent.PercentRelativeLayout>

Ответ 2

Возможно, это ответит на ваш вопрос:

<ImageView
    android:id="@+id/cover_image"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:scaleType="fitCenter"
    android:adjustViewBounds="true" />

Вы можете игнорировать атрибут scaleType для этой конкретной ситуации.

Ответ 3

Это можно сделать с помощью LayoutParams, чтобы динамически устанавливать высоту Views, когда вы знаете ширину представлений во время выполнения. Вам нужно использовать поток Runnable, чтобы получить ширину представлений во время выполнения, иначе вы будете пытаться установить высоту, прежде чем знаете ширину представления, потому что макет еще не нарисован.

Пример того, как я решил свою проблему:

final FrameLayout mFrame = (FrameLayout) findViewById(R.id.frame_id);

    mFrame.post(new Runnable() {

        @Override
        public void run() {
            RelativeLayout.LayoutParams mParams;
            mParams = (RelativeLayout.LayoutParams) mFrame.getLayoutParams();
            mParams.height = mFrame.getWidth();
            mFrame.setLayoutParams(mParams);
            mFrame.postInvalidate();
        }
    });

LayoutParams должен быть типа родительского представления, в котором находится ваше представление. My FrameLayout находится внутри RelativeLayout в XML файле.

    mFrame.postInvalidate();

вызывается для принудительного перерисовки представления в отдельном потоке, чем поток пользовательского интерфейса.

Ответ 4

Здесь я, что я сделал, чтобы иметь ImageButton, который всегда имеет ширину, равен ее высоте (и избегать глупых пустых полей в одном направлении... которые я считаю ошибкой SDK...):

Я определил класс SquareImageButton, который простирается от ImageButton:

package com.myproject;

import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.widget.ImageButton;

    public class SquareImageButton extends ImageButton {

        public SquareImageButton(Context context) {
        super(context);


        // TODO Auto-generated constructor stub
    }

    public SquareImageButton(Context context, AttributeSet attrs) {
        super(context, attrs);
        // TODO Auto-generated constructor stub

    }

    public SquareImageButton(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        // TODO Auto-generated constructor stub

    }

    int squareDim = 1000000000;

    @Override
    public void onMeasure(int widthMeasureSpec, int heightMeasureSpec){
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);


        int h = this.getMeasuredHeight();
        int w = this.getMeasuredWidth();
        int curSquareDim = Math.min(w, h);
        // Inside a viewholder or other grid element,
        // with dynamically added content that is not in the XML,
        // height may be 0.
        // In that case, use the other dimension.
        if (curSquareDim == 0)
            curSquareDim = Math.max(w, h);

        if(curSquareDim < squareDim)
        {
            squareDim = curSquareDim;
        }

        Log.d("MyApp", "h "+h+"w "+w+"squareDim "+squareDim);


        setMeasuredDimension(squareDim, squareDim);

    }

}

Вот мой xml:

<com.myproject.SquareImageButton
            android:id="@+id/speakButton"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:scaleType="centerInside"
            android:src="@drawable/icon_rounded_no_shadow_144px"
            android:background="#00ff00"
            android:layout_alignTop="@+id/searchEditText"
            android:layout_alignBottom="@+id/searchEditText"
            android:layout_alignParentLeft="true"
           />

Работает как шарм!

Ответ 5

Я не мог получить ответ Дэвида Чу для работы в элементе RecyclerView и понял, что мне нужно ограничить ImageView родителем. Установите ширину ImageView на 0dp и ограничьте ее начало и конец родителем. Я не уверен, что если установить ширину в wrap_content или match_parent работает в некоторых случаях, но я думаю, что это лучший способ получить дочерний объект ConstraintLayout для заполнения родительского элемента.

<android.support.constraint.ConstraintLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <ImageView
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintDimensionRatio="1:1"/>

</android.support.constraint.ConstraintLayout>

Ответ 6

Вы не можете сделать это с помощью макета, я пробовал. Я закончил писать очень простой класс, чтобы справиться с этим, вы можете проверить его на github. SquareImage.java Его часть более крупного проекта, но ничто не копирует и не вставляет исправления (лицензируется под Apache 2.0)

По существу вам просто нужно установить высоту/ширину, равную другому размеру (в зависимости от того, какой способ вы хотите масштабировать)

Примечание. Вы можете сделать его квадратным без пользовательского класса с использованием атрибута scaleType, но границы представления выходят за пределы видимого изображения, что делает его проблемой, если вы размещаете другие представления рядом с ним.

Ответ 7

В Android 26.0.0 PercentRelativeLayout устарел.

Лучший способ решить это теперь ConstraintLayout следующим образом:

<android.support.constraint.ConstraintLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content">

    <ImageView android:layout_width="match_parent"
               android:layout_height="0dp"
               android:scaleType="centerCrop"
               android:src="@drawable/you_image"                       
               app:layout_constraintDimensionRatio="1:1"/>


</android.support.constraint.ConstraintLayout>


Вот учебник о том, как добавить ConstraintLayout к вашему проекту.

Ответ 8

Чтобы установить ImageView равным половине экрана, вам нужно добавить следующее в свой XML для ImageView:

<ImageView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_centerInParent="true"
    android:scaleType="fitXY"
    android:adjustViewBounds="true"/>

Чтобы установить высоту, равную этой ширине, вам нужно сделать это в коде. В методе getView вашего адаптера GridView установите высоту ImageView, равную ее измеренной ширине:

mImageView.getLayoutParams().height = mImageView.getMeasuredWidth();

Ответ 9

Для людей, проходящих к настоящему моменту, в 2017 году, новый лучший способ достичь того, чего вы хотите, - это ConstraintLayout следующим образом:

<ImageView
    android:layout_width="0dp"
    android:layout_height="0dp"
    android:scaleType="centerCrop"
    app:layout_constraintDimensionRatio="1:1" />

И не забудьте добавить ограничения по всем четырем направлениям по мере необходимости в вашем макете.

Создайте адаптивный пользовательский интерфейс с ConstraintLayout

Кроме того, теперь PercentRelativeLayout устарел (см. Документация по Android).

Ответ 10

Вот как я решил эту проблему:

int pHeight =  picture.getHeight();
int pWidth = picture.getWidth();
int vWidth = preview.getWidth();
preview.getLayoutParams().height = (int)(vWidth*((double)pHeight/pWidth));

preview - imageView с шириной, заданной для "match_parent" и scaleType, в "cropCenter"

picture - Объект Bitmap для установки в imageView src.

Это хорошо работает для меня.

Ответ 11

Я не думаю, что вы можете сделать это в файле макета XML, и я не думаю, что атрибут android:scaleType будет работать так, как вы хотите. Единственный способ - сделать это программно. Вы можете установить ширину для fill_parent и можете либо использовать ширину экрана как высоту View, либо использовать метод View.getWidth().

Ответ 12

Функция ImageView "scaleType" может помочь вам здесь.

Этот код сохранит пропорции и поместит изображение вверху:

android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:scaleType="fitStart"

Вот отличный пост, показывающий возможности и возможности использования scaleType.

Образцы ImageView scaleType

Ответ 13

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

<ImageView
    android:layout_width="0dp"
    android:layout_height="0dp"
    android:id="@+id/ivImageView"
    app:layout_constraintDimensionRatio="W,1:1"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintEnd_toEndOf="parent"/>