Сумма веса макета Android не разделена должным образом
Страница в моем приложении имеет страницу макета таблицы, и кажется, что одна строка не работает. Моя цель - равномерно разделить страницу между левой и правой ячейками. Левая ячейка содержит строку, правая ячейка - изображение и строку. Я пытался сделать это с помощью WeightSum. Левая ячейка получила вес 4/8, а правая ячейка была помещена в линейную схему, в которой изображение получило вес 1/8, а строка получила вес 3/8. Тем не менее, в макете левая ячейка занимает большую часть ряда, около 75%, и я не уверен, почему.
Мои строки ниже этой попытки почти одинаковы, но не имеют той же проблемы.
Мой xml(вырезано для релевантности):
<TableRow
android:layout_width="match_parent">
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="Class"
android:id="@+id/classTextView"
android:layout_marginTop="14dp"
android:layout_weight="1"
android:gravity="center"/>
<LinearLayout>
<View
android:layout_width="4dp"
android:gravity="left"
android:layout_height="match_parent"
android:background="#663300"/>
<ImageView
tools:ignore="ContentDescription"
android:id="@+id/classicon"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:src="@drawable/barbarianicon50"
android:layout_gravity="end"
android:layout_weight="1"/>
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="Class Value"
android:id="@+id/classValueView"
android:layout_marginTop="14dp"
android:layout_weight="3"
android:gravity="left"/>
</LinearLayout>
</TableRow>
<View
android:layout_width="match_parent"
android:layout_height="4dp"
android:background="#663300"/>
<TableRow android:layout_width="match_parent">
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="Strength"
android:id="@+id/strengthTextView"
android:layout_marginTop="20dp"
android:layout_weight="4"
android:gravity="center" />
<LinearLayout>
<View
android:layout_width="4dp"
android:gravity="left"
android:layout_weight="0"
android:layout_height="match_parent"
android:background="#663300"/>
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="Strength Value"
android:id="@+id/strengthValView"
android:layout_marginTop="20dp"
android:layout_weight="4"
android:gravity="center" />
</LinearLayout>
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="Intelligence"
android:id="@+id/intelligenceTextView"
android:layout_marginTop="20dp"
android:layout_weight="4"
android:gravity="center" />
<LinearLayout>
<View
android:layout_width="4dp"
android:gravity="left"
android:layout_weight="0"
android:layout_height="match_parent"
android:background="#663300"/>
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="Intelligence Value"
android:id="@+id/intelligenceValView"
android:layout_marginTop="20dp"
android:layout_weight="4"
android:gravity="center" />
</LinearLayout>
</TableRow>
Первая строка таблицы является проблематичной - она должна быть равномерно разделена между левой и правой ячейками, но в основном направо.
Вторая строка таблицы является примером ее правильной работы - в этой строке 2 пары ячеек, но каждая из ячеек и пары ячеек правильно делят ширину между собой равномерно.
Я не могу понять, почему первый не работает. Я ценю любую помощь!
1 ответ
Мне наконец удалось исправить макет!
Метод был использован для <include />
другой макет как элемент строки внутри этого. Все эти элементы строки имели одинаковые данные, поэтому я затем программно заполнял элементы строки их необходимыми данными при каждом изменении вида. Вы также можете сделать это как ListView, где каждая строка в ListView является другой парой элементов, но я не уверен, насколько хорошо это работает для строк шириной 4 элемента.
XML каждой строки:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal" android:layout_width="match_parent"
android:layout_height="match_parent"
android:weightSum="2">
<TextView
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="@string/statNameString"
android:id="@+id/statName"
android:layout_marginTop="30dp"
android:gravity="center" />
<View
android:layout_width="4dp"
android:gravity="left"
android:layout_height="match_parent"
android:background="#663300"/>
<TextView
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="@string/statValString"
android:id="@+id/statVal"
android:layout_marginTop="30dp"
android:gravity="center" />
</LinearLayout>
Верхняя строка (которая представляла класс персонажа в моем приложении) должна была включать ImageView, поэтому она имела слегка измененный макет. ImageView был размещен после панели View и перед последним TextView.
XML, включающий каждую строку в окончательный макет для макета Land:
<TableRow
android:layout_width="match_parent"
android:layout_height="match_parent">
<include
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
layout="@layout/horizontal_class_row_layout"
android:id="@+id/strValues"
android:layout_column="0" />
<include
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
layout="@layout/horizontal_class_row_layout"
android:id="@+id/intValues"
android:layout_column="0" />
</TableRow>
Если вам нужна только 1 пара элементов в каждой строке, вы можете просто удалить один из тегов включения. Как упоминалось ранее, вы также можете использовать ListView для этого и заполнить данные, и я, вероятно, изменю его, чтобы сделать это в конце концов.
Наконец, вы программно заполняете элементы их данными в Java, чтобы они не просто произносили "Класс" и "Значение класса" или любые другие данные по умолчанию:
private void fillViewValues() {
//Gather views
LinearLayout llClass = (LinearLayout)findViewById(R.id.classValues);
LinearLayout llStr = (LinearLayout)findViewById(R.id.strValues);
LinearLayout llDex = (LinearLayout)findViewById(R.id.dexValues);
LinearLayout llCon = (LinearLayout)findViewById(R.id.conValues);
LinearLayout llInt = (LinearLayout)findViewById(R.id.intValues);
LinearLayout llWis = (LinearLayout)findViewById(R.id.wisValues);
LinearLayout llCha = (LinearLayout)findViewById(R.id.chaValues);
//Get the layout's locations
TextView classNameView = (TextView) llClass.findViewById(R.id.statName);
TextView classValView = (TextView) llClass.findViewById(R.id.statVal);
ImageView classImage = (ImageView) llClass.findViewById(R.id.classicon);
TextView strNameView = (TextView) llStr.findViewById(R.id.statName);
TextView strValView = (TextView) llStr.findViewById(R.id.statVal);
TextView dexNameView = (TextView) llDex.findViewById(R.id.statName);
TextView dexValView = (TextView) llDex.findViewById(R.id.statVal);
TextView conNameView = (TextView) llCon.findViewById(R.id.statName);
TextView conValView = (TextView) llCon.findViewById(R.id.statVal);
TextView intNameView = (TextView) llInt.findViewById(R.id.statName);
TextView intValView = (TextView) llInt.findViewById(R.id.statVal);
TextView wisNameView = (TextView) llWis.findViewById(R.id.statName);
TextView wisValView = (TextView) llWis.findViewById(R.id.statVal);
TextView chaNameView = (TextView) llCha.findViewById(R.id.statName);
TextView chaValView = (TextView) llCha.findViewById(R.id.statVal);
//Fill those values
//Names of sections
classNameView.setText(getResources().getString(R.string.classString));
strNameView.setText(getResources().getString(R.string.strString));
dexNameView.setText(getResources().getString(R.string.dexString));
conNameView.setText(getResources().getString(R.string.conString));
intNameView.setText(getResources().getString(R.string.intString));
wisNameView.setText(getResources().getString(R.string.wisString));
chaNameView.setText(getResources().getString(R.string.chaString));
//Values
classValView.setText(classString);
setImage(classImage, classString);
strValView.setText(String.format("%d", finalStats[0]));
dexValView.setText(String.format("%d", finalStats[1]));
conValView.setText(String.format("%d", finalStats[2]));
intValView.setText(String.format("%d", finalStats[3]));
wisValView.setText(String.format("%d", finalStats[4]));
chaValView.setText(String.format("%d", finalStats[5]));
}
Это следует совету в этом посте Stackru.
Я хотел бы отметить одну вещь: когда вы изменяете макет, вам нужно сбросить представление контента к вашему текущему макету. В моем случае функция выглядела так:
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
if(newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE)
{
setContentView(R.layout.activity_see_character);
fillViewValues();
}else if(newConfig.orientation == Configuration.ORIENTATION_PORTRAIT)
{
setContentView(R.layout.activity_see_character);
fillViewValues();
}
}
где fillViewValues () - предыдущая функция. Я полагаю, что это устанавливает макет на книжную или альбомную версию макета, к которому затем можно получить доступ к его элементам. Если вы не сделаете этого при попытке доступа к элементам, он не сможет их найти и выдаст исключение NullPointerException.