#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);
Этот код обновляет левое поле каждого изображения до значения, найденного ранее, выравнивая все строки.