1

A page on my app has a table layout page, and one row of it seems to not be working. My goal is to evenly split the page between the left cell and right cell. The left cell contains a string, the right cell an image and string. I have tried to do so using weighSum. The left cell got weight of 4/8, and right cell was put into a linear layout, within which the image got weight of 1/8 and the string got weight 3/8. However, in the layout the left cell is taking up the great majority of the row, about 75% and I'm not sure why.

My rows below this one attempt almost the same thing, but don't have the same problem.

My xml(cut for relevancy):

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

The first table row is the problematic one - it should be evenly split between the left and right cells, but is mostly towards the right.

The second table row is an example of it working correctly - this row has 2 pairs of cells, but each of the cells, and the pairs of cells are correctly splitting the width between themselves evenly.

I can't figure out why the first doesn't work. I appreciate any help!

WarSame
  • 870
  • 1
  • 10
  • 24
  • `I have tried to do so using weighSum` I don't see weightSum in the provided xml? – Xiao Oct 11 '15 at 00:36
  • WeightSum was up above this code. My bad, I should have posted that as well. I defined it as android:weightSum="8" EDIT: For clarity, this is using weightSum. – WarSame Oct 11 '15 at 03:32

1 Answers1

0

I have finally succeeded in fixing the layout!

The method used was to <include /> another layout as a row element inside this one. All these row elements had the same data, so I then programmatically filled the row elements with their necessary data whenever the view changed. You could also do this as a ListView, with each row in the ListView being another pair of elements, but I'm not sure how well that works for the 4 element wide rows.

The XML of each row:

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

The top row(which represented the Class of the Character in my app) needed to include an ImageView, so it had a slightly changed layout. The ImageView was placed after the bar View, and before the last TextView.

The XML including each row into the final layout, for the Land layout:

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

If you only wanted 1 pair of elements in each row, you can simply remove one of the include tags. As mentioned before, you could also use the ListView to do these, and fill the data, and I will probably modify it to do that eventually.

Finally, you programmatically fill the elements with their data in the Java, so they don't just say "Class" and "Class Value" or whatever default data:

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]));
}

This follows the advice at at this StackOverflow post.

One thing I would like to note, is that when you change the layout, you need to reset the content view to your current layout. In my case, the function looked like:

@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();
    }
}

where fillViewValues() is the previous function. I believe that this sets the layout to either the portrait or landscape version of the layout, which can then have its elements accessed. If you don't do this when you try to access the elements it can't find them and gives a NullPointerException.

Community
  • 1
  • 1
WarSame
  • 870
  • 1
  • 10
  • 24