Исходный фон шрифта для Android с привязкой к сетке 4dp

Спецификация дизайна материала для Android говорит: "Тип выравнивается по базовой линии с 4 дБ" (http://www.google.com/design/spec/layout/metrics-and-keylines.html#)

В примерной графике также говорится, что строка в списке должна быть 72dp.

В нем также указываются разные стили шрифтов и размер шрифта, а также его лидирующие позиции (http://www.google.com/design/spec/style/typography.html#typography-standard-styles).

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

У меня есть 3 строки текста для отображения в каждой моей строке

Линия заголовка одноразмерная 14sp  Подробности линии двух размеров 12 ср.  Строка 3 - размер 12sp

Как обеспечить соответствие базовой линии текста в каждом из этих текстовых полей сетке? Я не могу выровнять нижнюю часть текстового поля, так как это не базовая строка, нижняя часть текстового поля - это базовая линия + спуск, не так ли?

Мне нужно выделить 3 строки текста как можно более равномерно, но обеспечить их исходные линии в соответствии с сеткой.

Я не верю, что могу просто использовать padding/margin, так как это не гарантирует, что базовые линии каждой строки текста выравниваются с сеткой.

Более того, когда я делаю все эти вычисления, мне нужно убедиться, что высота строки равна 72dp (для устройства mdpi с указанным нормальным размером шрифта).

Наконец, как бы я определил ведущий? Как я понимаю, это пространство от базовой линии текста строки выше до верхней части наивысшего текста в нижней строке. Снова я не могу использовать прописку/маржу, поскольку это не от базовой линии.

enter image description here

Изменить: Спецификация материала для списков содержит немного больше информации о том, как должны появляться Плитки в списке, когда у вас есть 3 строки текста. http://www.google.co.uk/design/spec/components/lists.html#lists-keylines

Но он по-прежнему не указывает, как 3 строки текста фактически размещены вертикально, так что их базовые линии выравниваются по сетке 4dp. enter image description here

Ответ 1

Обновление

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

Вместо простого обеспечения выравнивания 4dp, он позволяет устанавливать ведущие по всем линиям и первой строке отдельно, а последний спуск линии:

введите описание изображения здесь


Предыдущий ответ, оставленный для исторических целей (удаленный большой снимок)

Хорошо, это довольно поздно, но я понял, как это сделать наименее опасным способом.

Этот метод применит существующий вид базовой сетки, учитывая, что его верхняя граница уже находится в базовой сетке. Входными параметрами являются шаг сетки (4dp в пикселях, возможно, считываемый из ресурсов) и желаемое начало строки (например, 20dp в пикселях).

Обратите внимание, что это не даст вам точных высот, которые вам нужны, но это сделает размер TextView детерминированным (т.е. высота, кратная step с базовым уровнем, находящимся в сетке), что делает гораздо проще в компоновке по мере необходимости с использованием целых полей.

private static void setLeading(TextView view, int step, int leading) {
    // This is to make the behavior more deterministic: remove extra top/bottom padding
    view.setIncludeFontPadding(false);

    // Get font metrics and calculate required inter-line extra
    Paint.FontMetricsInt metrics = view.getPaint().getFontMetricsInt();
    final int extra = leading - metrics.descent + metrics.ascent;
    view.setLineSpacing(extra, 1);

    // Determine minimum required top extra so that the view lands on the grid
    final int alignTopExtra = (step + metrics.ascent % step) % step;
    // Determine minimum required bottom extra so that view bounds are aligned with the grid
    final int alignBottomExtra = (step - metrics.descent % step) % step;

    view.setPadding(view.getPaddingLeft(), view.getPaddingTop() + alignTopExtra, view.getPaddingRight(), view.getPaddingBottom() + alignBottomExtra);
}

Ответ 2

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

<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" >

    <com.example.baselinetest.BaseLineHelperView
    android:id="@+id/v_baselinehelper"
    android:layout_width="match_parent"
    android:layout_height="30dp"
    android:background="#FF0000" />

    <TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignBaseline="@id/v_baselinehelper"
    android:text="@string/hello_world" />

    </RelativeLayout>

Используйте этот вспомогательный просмотр

public class BaseLineHelperView extends View {

   @TargetApi(Build.VERSION_CODES.LOLLIPOP)
   public BaseLineHelperView(Context context, AttributeSet attrs, int  defStyleAttr, int defStyleRes) {
      super(context, attrs, defStyleAttr, defStyleRes);
   }

   public BaseLineHelperView(Context context, AttributeSet attrs, int defStyleAttr) {
      super(context, attrs, defStyleAttr);
   }

   public BaseLineHelperView(Context context, AttributeSet attrs) {
     super(context, attrs);
   }

   public BaseLineHelperView(Context context) {
     super(context);
   }

   @Override
   @ExportedProperty(category = "layout")
   public int getBaseline() {
     return getHeight();
   }
}

Ответ 3

Вы можете использовать android: lineSpacingExtra и android: lineSpacingMultiplier в вашем XML файле для межстрочного интервала. Чтобы иметь правильную компоновку одной строки ListView, она может помочь: -

<?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="88dp"
    android:background="#fff"
    android:orientation="horizontal"
    android:paddingTop="8dp"
    android:paddingBottom="8dp"
    android:paddingLeft="16dp" >

    <ImageView
        android:id="@+id/imageView1"
        android:layout_width="45dp"
        android:layout_height="match_parent"
        android:background="#000"
        android:padding="16dp" />

    <LinearLayout
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:paddingRight="72dp"
        android:paddingLeft="16dp"
        android:orientation="vertical" >

        <TextView
            android:id="@+id/textView1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"            
            android:text="TextView"
            android:textColor="#000"
            android:textSize="16sp" />

        <TextView
            android:id="@+id/textView2"
            android:layout_weight="1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="14sp"
            android:text="asdjkfah asdfakj sdfjshd sdgf dfg " />
    </LinearLayout>

</LinearLayout>