Android выравнивает элементы списка по вертикали по самому длинному

#android #listview #tablerow

#Android #listview #tablerow

Вопрос:

Я создал этот макет для ListView

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

<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="@dimen/icon_row"
    android:background="@color/icon_and_name_background"
    android:orientation="horizontal"
    android:gravity="center">

    <TableRow>

        <ImageView
            android:id="@ id/icon"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_gravity="center_vertical"
            android:layout_weight="1" />

        <RelativeLayout
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_gravity="center_vertical"
            android:layout_weight="2">

            <com.Wonderland.graphicObjects.MyTextView
                android:id="@ id/name"
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:textColor="@color/Alice_Title"
                android:textSize="20sp"
                android:layout_alignParentLeft="true" />

        </RelativeLayout>
    </TableRow>
</TableLayout>
  

Он состоит из значка слева и текста справа. Текст выравнивается по левому краю, а все элементы списка выровнены по вертикали.

Клиент хочет, чтобы строка с самым длинным текстом была центрирована по горизонтали (как значок, так и текст), а все остальные строки должны быть выровнены с этим.

Я попытался раздуть строки в ArrayAdapter при инициализации, чтобы выяснить, какая из них самая длинная, но я всегда получаю 0.

Как я могу удовлетворить потребности моего клиента?

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

1. Если вы не можете спорить со своим клиентом, то единственный способ сделать то, что он просит, — создать пользовательский компонент.

Ответ №1:

Я решил проблему, установив пользовательское поле слева от изображения для каждой строки.

Новая строка xml:

 <?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="@dimen/icon_row"
    android:background="@color/icon_and_name_background"
    android:orientation="horizontal"
    android:gravity="center_vertical">

    <ImageView
            android:id="@ id/icon"
        android:layout_width="@dimen/icon_width"
            android:layout_height="wrap_content"
            android:layout_gravity="center_vertical" />


    <com.Wonderland.graphicObjects.MyTextView
                android:id="@ id/name"
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:textColor="@color/Alice_Title"
                android:textSize="20sp"
        android:layout_alignParentLeft="true"
        android:paddingLeft="40px" />


</LinearLayout>
  

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

В пользовательский ArrayAdapter я добавил этот код для вычисления левого поля

 /**
 * Method to calculate the left margin of the object to center the longest
 */
private void calculateLeftMargin() {

    // reset the left margin
    marginLeft = 0;

    WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
    Display display = wm.getDefaultDisplay();
    Point size = new Point();
    display.getSize(size);

    // lenght of the screen
    int width = size.x;
    int height = context.getResources().getDimensionPixelSize(R.dimen.icon_row);

    LinearLayout linearLayout = new LinearLayout(context);
    View row = inflateRow(linearLayout);

    ImageView icon = (ImageView) row.findViewById(R.id.icon);
    TextView name = (TextView) row.findViewById(R.id.name);

    // max length of the object
    int maxLength = 0;

    for (int i = 0; i < getCount(); i  ) {

        Character c = getItem(i);

        icon.setImageDrawable(c.getDrawableImage(context));
        name.setText(c.getName());

        row.measure(width, height);

        int max = icon.getMeasuredWidth()   name.getMeasuredWidth();

        if (maxLength < max)
            maxLength = max;
    }

    // margin left to center the longest object
    marginLeft = (width - maxLength) / 2;
}
  

Я создаю пользовательский объект LinearLayout, раздуваю в нем ресурс ArrayAdapter и заставляю Android вычислять измерения через row.measure(width, height);. Из всех ширин я сохраняю самую длинную для вычисления поля, центрируя по горизонтали самую длинную строку.

В методе getView над возвращаемой строкой я помещаю этот код:

     // Update the margin left of every row to align to the longest object
    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(holder.icon.getLayoutParams());
    params.setMargins(marginLeft, 0, 0, 0);
    holder.icon.setLayoutParams(params);
  

Этот код обновляет левое поле каждого изображения до значения, найденного ранее, выравнивая все строки.