Установка ширины и высоты ImageView относительно высоты текста

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

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

Все решения, которые я нашел, кажутся слишком сложными, и я бы предположил, что это довольно распространенное требование, поэтому я хотел бы проверить, не упустил ли я что-нибудь. У вас есть идея, как этого добиться проще?

Ниже приведены решения, которые я рассмотрел.

Решение 1:

Вложенные представления для элемента ListView и установки android:layout_height="match_parent". Размер изображения изменяется правильно, но ImageView занимает ширину, как если бы он не был изменен. (См. Следующую картинку. Я добавил черный фон, чтобы увидеть, сколько места занимает ImageView.)

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <LinearLayout
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <ImageView android:id="@+id/Image"
            android:layout_height="match_parent"
            android:layout_width="wrap_content"
            android:adjustViewBounds="true"
            android:scaleType="fitStart"

            android:background="#000000"
            android:padding="1dp"/>
        <TextView
            android:id="@+id/Text"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_above="@id/Image" />
    </LinearLayout>
</RelativeLayout>

Решение 2. Использование

ViewTreeObserver наблюдатель = MyTextView.getViewTreeObserver() наблюдатель.addOnPreDrawListener(новый ViewTreeObserver.OnPreDrawListener () {

public boolean onPreDraw(){
    observer.removeOnPreDrawListener(this);
    // Finding out height of TextView and then calculating width and height of image and setting size of ImageView. Of course, I could also get observer from ImageView and then just set width as height is correct
}

}

Это кажется слишком сложным.

Решение 3:

Используйте, например, Paint.FontMetrics, чтобы вычислить высоту, но мне также нужно выяснить используемый шрифт (например, системный...). Кроме того, ListView, вероятно, имеет некоторые отступы и т. Д., Так что много чего нужно извлечь.

Любое другое более простое решение, пожалуйста?

Редактировать - уточнение

Изображение имеет макс. size, который при достижении останавливает дальнейшее увеличение размера ImageView.

2 ответа

Если вы хотите установить ширину и высоту ImageView на основе ширины и высоты, вы всегда можете получить ширину и высоту TextView программно, затем реализуйте свой собственный алгоритм для масштабирования ImageView соответственно.

Чтобы получить ширину и высоту из textView, давайте назовем его item_textViewэто довольно просто:

TextView item_textView = findViewById(R.id.item_textView);
int text_width = item_textView.getWidth();
int text_height  = item_textView.getHeight();

На этом этапе вы можете выполнить любую математику, необходимую для масштабирования imageView до нужного размера. Чтобы установить размер imageView:

my_imageView.getLayoutParams().width = text_width/2;
my_imageView.getLayoutParams().height = text_height/2;

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

Попробуйте определить точный размер изображения в макете строки. Если вы можете определить его ширину и высоту как 40dp или 48dp, вы сможете достичь своей цели.

Если все элементы зависят от размера друг друга, вы можете увидеть изменения. Попробуйте определить размеры аватара / изображения в определенном дп.

Я попытался настроить ваш макет и получил некоторые результаты. Проверьте следующий код.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    android:padding="16dp">
    <ImageView
        android:id="@+id/earthquake_magnitude"
        android:layout_width="36dp"
        android:layout_height="36dp"
        android:background="@android:color/black"
        android:fontFamily="sans-serif-medium"
        android:src="@mipmap/ic_launcher" />

    <TextView
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:layout_marginLeft="16dp"
        android:layout_marginStart="16dp"
        android:layout_weight="1"
        android:text="CHROME" />
</LinearLayout>
Другие вопросы по тегам