Текст между двумя представлениями

#android #android-layout

#Android #android-макет

Вопрос:

Я хочу добиться следующего результата:

  • ТВ: текстовый просмотр
  • IV: Просмотр изображений

Относительный макет

Все четыре представления заполняются из базы данных, поэтому имеют динамическую ширину (кроме IV).

Идентификаторы слева направо:

 icon
tv_top
tv_bottom
tv_right
  

Я сделал этот относительный макет, взятый из этого руководства (Vogella Android ListView):

 <?xml version="1.0" encoding="utf-8"?>

<RelativeLayout  xmlns:android="http://schemas.android.com/apk/res/android"
                 android:layout_width="fill_parent"
                 android:layout_height="?android:attr/listPreferredItemHeight"
                 android:padding="5dip" >

    <ImageView
            android:id="@ id/icon"
            android:layout_width="@dimen/photo_item_size"
            android:layout_height="@dimen/photo_item_size"
            android:layout_alignParentBottom="true"
            android:layout_alignParentTop="true"
            android:layout_marginRight="10dp"
            android:src="@drawable/ic_launcher"
            >
    </ImageView>

    <TextView
            android:id="@ id/tv_right"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignBaseline="@id/icon"
            android:layout_gravity="right"
            android:layout_alignParentRight="true"
            android:layout_centerVertical="true"
            android:layout_marginRight="1dp"
            android:textSize="27sp"
            >
    </TextView>

    <TextView
            android:id="@ id/tv_bottom"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:layout_alignParentRight="true"
            android:layout_toRightOf="@id/icon"
            android:ellipsize="end"
            android:singleLine="true"
            android:textSize="14sp"
            >
    </TextView>

    <TextView
            android:id="@ id/tv_top"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center_vertical"
            android:ems="10"
            android:textSize="21.5sp"
            android:layout_alignParentRight="true"
            android:layout_alignParentTop="true"
            android:layout_alignWithParentIfMissing="true"
            android:layout_toRightOf="@id/icon"
            android:singleLine="true"
            android:ellipsize="end"

            android:layout_marginRight="70dp"

            >
    </TextView>
  

Моя проблема в том, что я хочу динамически изменять ширину моего tv_top в соответствии с шириной tv_right. Если tv_right становится больше, я хочу уменьшить ширину моего tv_top.

В настоящее время я выполняю эту свою android:layout_marginRight="70dp" команду, которая устанавливает фиксированный размер для моего представления.

Я также пробовал (в моем адаптере — программно) такие вещи, как :

 RelativeLayout.LayoutParams llp = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
int relativeUsageWidth = viewHolder.tvAppRelativeUsage.getWidth(); // width is always 0
llp.addRule(RelativeLayout.ALIGN_PARENT_RIGHT | RelativeLayout.ALIGN_PARENT_TOP);
llp.addRule(RelativeLayout.RIGHT_OF,R.id.icon);
llp.setMargins(0, 0, relativeUsageWidth, 0);
  

Есть ли лучший способ сделать это, чем программно (возможно, xml-способом)? Должен ли я использовать линейные макеты? Какой лучший способ решить эту проблему?

Ответ №1:

В ваших текстовых представлениях в середине не используйте android:layout_alignParentRight="true" с дополнительным полем, но установите их справа от левого изображения и слева от правого текстового представления и установите ширину на match_parent . Это позволит им помещаться непосредственно между двумя другими представлениями.

Пример для двух текстовых представлений:

  <TextView
        android:id="@ id/tv_bottom"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_toLeftOf="@id/tv_right"
        android:layout_toRightOf="@id/icon"
        android:ellipsize="end"
        android:singleLine="true"
        android:textSize="14sp"
        >
</TextView>

<TextView
        android:id="@ id/tv_top"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:ems="10"
        android:layout_alignParentTop="true"
        android:layout_alignWithParentIfMissing="true"
        android:gravity="center_vertical"
        android:ellipsize="end"
        android:layout_toLeftOf="@id/tv_right"
        android:layout_toRightOf="@id/icon"
        android:textSize="21.5sp"
        android:singleLine="true">
</TextView>
  

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

Комментарии:

1. Я пытался это сделать, но у меня также было alignParentRight=»true». Я думаю, что это более простое решение.

2. Да, но alignParentRight=»true» приведет к тому, что изображения будут заканчиваться справа от родительского элемента, в то время как android:layout_toLeftOf=»@id /tv_right» приведет к тому, что они будут заканчиваться слева от tv_right, что больше соответствует тому, что вы хотели.

Ответ №2:

Вы можете использовать LinearLayout и layout_weight для этого.

 <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="match_parent"
              android:layout_height="?android:attr/listPreferredItemHeight"
              android:orientation="horizontal">

    <ImageView
        android:id="@ id/icon"
        android:layout_width="80dp"
        android:layout_height="match_parent"
        android:src="@drawable/ic_launcher"/>

    <!-- weight 3 of 4 = 3/4 of available width for this LinearLayout -->
    <RelativeLayout
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="3"
        android:orientation="vertical">

        <TextView
            android:id="@ id/tv_top"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentTop="true"
            android:layout_alignBottom="@ id/tv_bottom"
            android:text="Top line"/>

        <TextView
            android:id="@ id/tv_bottom"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:text="Bottom line"/>

    </RelativeLayout>

    <!-- weight 1 of 4 = 1/4 of available width for this TextView -->
    <TextView
        android:id="@ id/tv_right"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:text="Right text"/>

</LinearLayout>
  

Комментарии:

1. Вы имеете в виду tv_top и tv_bottom в LinearLayout? Я отредактировал свой вопрос, чтобы указать, какой идентификатор принадлежит изображению.

2. @AndreasLympouras, я удалил большую часть ваших данных, чтобы упростить отслеживание. Я обновил свой ответ, поскольку у меня были перепутаны идентификаторы. Я также использовал a RelativeLayout для двух средних TextViews , чтобы показать возможный способ отображения их так, как, я думаю, вы хотите.

3. Я оставлю ваши желаемые размеры в упражнении для вас — я намеренно сделал ответ более общим для будущих читателей.

4. Спасибо за ваш ответ, но я считаю layout_toLeftOf , layout_toRightOf что это более простое решение.

5. @AndreasLympouras Конечно, ваш звонок. Это действительно зависит от того, как вы хотите определить масштабирование размера. Это позволит middle TextView right TextView равномерно / пропорционально масштабировать ширину и по всем размерам экрана, тогда как корневая RelativeLayout опция изменит размер в соответствии с содержимым middle TextViews и оставит значение right TextView на его wrap_content (или определенной определенной) ширине. Отметьте тот вариант, который подходит для вашего варианта использования, я оставлю это здесь в качестве альтернативного варианта для будущих пользователей с аналогичными проблемами.

Ответ №3:

Это может быть достигнуто без использования любого дополнительного макета. Все, что нам нужно, это просто RelativeLayout :

 <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" >

    <ImageView
        android:id="@ id/iv_left"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:src="@drawable/ic_launcher" />

    <TextView
        android:id="@ id/tv_right"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_alignBottom="@ id/iv_left"
        android:layout_alignParentRight="true"
        android:gravity="center"
        android:singleLine="true"
        android:text="ABC"
        android:textSize="24sp"
        android:background="#888"
        android:textStyle="bold" />

    <TextView
        android:id="@ id/et_top"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@id/iv_left"
        android:layout_toLeftOf="@id/tv_right"
        android:singleLine="true"
        android:text="@string/app_name"
        android:textSize="18sp"
        android:textStyle="bold" />

    <TextView
        android:id="@ id/et_bottom"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@id/iv_left"
        android:layout_toLeftOf="@id/tv_right"
        android:layout_below="@id/et_top"
        android:singleLine="true"
        android:text="@string/app_name"
        android:textSize="14sp" />

</RelativeLayout>
  

Вы можете установить отступы и поля в соответствии с вашим желанием.

[РЕДАКТИРОВАТЬ] упс не заметил, что правильным был TextView… Код обновлен..

Надеюсь, это поможет 🙂

Комментарии:

1. Да! это решение, но ‘tknell’ дал его первым. В любом случае спасибо.

2. * TextView не редактирует текст