0

I'm having a hard time understanding what is wrong with my onMeasure. I expect a 2x2 grid with the following layout but when I check the width and height, the height is being calculated as expected but the width is Integer.MAX_VALUE. I can't figure out what is happening to the height that isn't happening to the width. Any help in helping me figure out the correct onMeasure() method to get the expected 2x2 grid would be greatly appreciated. While the example is a 2x2 grid, I need a solution that works for any size of grid.

Following is the XML. Note that DragLayer simply extends FrameLayout. I don't believe the custom tags will cause any formatting difference but I left them in just in case.

<?xml version="1.0" encoding="utf-8"?>
<com.hogenson.dragndrop.DragLayer 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:custom="http://schemas.android.com/apk/res/com.hogenson.dragndrop"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    custom:sfen="@string/start_sfen" >

    <TableLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <TableRow
            android:layout_width="match_parent"
            android:layout_height="match_parent">

            <com.hogenson.dragndrop.DragView
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                custom:border_color="#000000"
                custom:anti_alias="true"
                custom:game_token="r" />

            <com.hogenson.dragndrop.DragView
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                custom:border_color="#000000"
                custom:anti_alias="true"
                custom:game_token="p" />

        </TableRow>

        <TableRow
            android:layout_width="match_parent"
            android:layout_height="match_parent">

            <com.hogenson.dragndrop.DragView
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                custom:border_color="#000000"
                custom:anti_alias="true"
                custom:game_token="K" />

            <com.hogenson.dragndrop.DragView
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                custom:border_color="#000000"
                custom:anti_alias="true"
                custom:game_token="R" />

        </TableRow>

    </TableLayout>

</com.hogenson.dragndrop.DragLayer>

And here is the onMeasure() method I am trying to implement in the DragView class.

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
    int widthMode = MeasureSpec.getMode(widthMeasureSpec);
    int heightMode = MeasureSpec.getMode(heightMeasureSpec);

    int width = MeasureSpec.getSize(widthMeasureSpec);
    int height = MeasureSpec.getSize(heightMeasureSpec);

    if (widthMode != MeasureSpec.EXACTLY)
    {
        width = Integer.MAX_VALUE;
    }

    if (heightMode != MeasureSpec.EXACTLY)
    {
        height = Integer.MAX_VALUE;
    }

    this.setMeasuredDimension(width, height);
}

Edit:

The solution Eric provided below worked perfectly for me with the addition that I needed to add layout_weight to the horizontal layouts as well, which seems to be bad programming practice.

Michael Hogenson
  • 1,292
  • 1
  • 15
  • 31

1 Answers1

1

Nitpick

Could it be the fact that, in both your if statements, you're modifying width?

if (widthMode != MeasureSpec.EXACTLY)
{
    width = Integer.MAX_VALUE;
}

if (heightMode != MeasureSpec.EXACTLY)
{
    width = Integer.MAX_VALUE; // Shouldn't this be height?
}

That aside...

Before I get to my preferred solution, I'll start by suggesting that you attach android:stretchColumns="*" to your TableLayout. This will allow the columns to fill the allotted space (and not be too small).

Using LinearLayouts instead

However, I think what you want to accomplish is best done with LinearLayouts. Basically, this:

<LinearLayout
    ...
    android:orientation="vertical" >

    <LinearLayout
        ...
        android:orientation="horizontal" >

        <com.hogenson.dragndrop.DragView
            android:layout_width="0px"
            android:layout_height="match_parent"
            android:layout_weight="1" />

        <!-- more cells for row 1 -->

    </LinearLayout>

    <LinearLayout
        ...
        android:orientation="horizontal" >

        <com.hogenson.dragndrop.DragView
            android:layout_width="0px"
            android:layout_height="match_parent"
            android:layout_weight="1" />

        <!-- more cells for row 2 -->

    </LinearLayout>

</LinearLayout>

Lastly, squares

Finally, if you want your objects to be square (same width and height), have a look at this answer.

Note that, with the above solutions, you're probably best not to fiddle with onMeasure in this case; the XML should be able to take care of it for you. And as always, good luck!

Community
  • 1
  • 1
Cat
  • 66,919
  • 24
  • 133
  • 141
  • That was a mistake on my part but unfortunately it didn't fix the problem. Width remains Integer.MAX_VALUE while height is modified to be 1/2 of the height. I'll fix this in my example code though. – Michael Hogenson Oct 03 '12 at 02:20
  • @Xyrthon Something seems wrong. None of your code edits anything to be 1/2 of any value (except the fact that you have two `TableRow`s). Why not avoid this and just use `layout_weight` instead? – Cat Oct 03 '12 at 02:25
  • That might be what I want to accomplish. I just started programming in Android. I don't want to modify to be 1/2 of any value because I want the grid to work for more than just 2x2 grids as specified in my question. I don't see how modifying the width and height to be 1/2 of any value would help me in this situation. I will try to make them all the same layout_weight. That might be what I'm missing. – Michael Hogenson Oct 03 '12 at 02:27
  • I tried adding android:layout_weight="1" to each of my DragViews but then it doesn't execute the onDraw() so I'm assuming one of the values becomes 0. – Michael Hogenson Oct 03 '12 at 02:31
  • 1
    Have a look at the edit to my post. I suggest a way to handle it using your existing `TableLayout`; I also addressed `layout_weight`, which is best used with `LinearLayout`. – Cat Oct 03 '12 at 02:32
  • Well at least I'm getting somewhere now. I switched to the LinearLayout, as I like that idea much better and pretty much have what you have, custom tags aside, but it's only showing the first row. There isn't anything like stretchColumns="*" for rows is there? – Michael Hogenson Oct 03 '12 at 02:56
  • What did you set its `layout_height` to be? If it's set to `match_parent`, then it will push all the other rows off the screen. Use `wrap_content` or a fixed-height. – Cat Oct 03 '12 at 04:27