Question

I have an Android layout:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/dice_container"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:gravity="center"
    android:orientation="vertical" >

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:gravity="top" >

    <FrameLayout
        android:id="@+id/die_frame_1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center_horizontal|top" >

        <ImageView
            android:id="@+id/die1"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:contentDescription="@string/dice"
            android:src="@drawable/d6" />

        <ImageView 
            android:id="@+id/die_overlay_1"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:alpha="0.4"
            android:visibility="invisible"
            android:src="@drawable/gray_shape" 
            android:contentDescription="@string/gray_overlay" />

    </FrameLayout>

    </LinearLayout>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal" >

        <FrameLayout
            android:id="@+id/die_frame_2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" >

            <ImageView
                android:id="@+id/die2"
                android:layout_width="fill_parent"
                android:layout_height="fill_parent"
                android:contentDescription="@string/dice"
                android:src="@drawable/d2" />

            <ImageView 
                android:id="@+id/die_overlay_2"
                android:layout_width="fill_parent"
                android:layout_height="fill_parent"
                android:alpha="0.4"
                android:visibility="invisible"
                android:src="@drawable/gray_shape" 
                android:contentDescription="@string/gray_overlay" />

        </FrameLayout>

        <FrameLayout
            android:id="@+id/die_frame_3"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" >

            <ImageView
                android:id="@+id/die3"
                android:layout_width="fill_parent"
                android:layout_height="fill_parent"
                android:contentDescription="@string/dice"
                android:src="@drawable/d1" />

            <ImageView 
                android:id="@+id/die_overlay_3"
                android:layout_width="fill_parent"
                android:layout_height="fill_parent"
                android:alpha="0.4"
                android:visibility="invisible"
                android:src="@drawable/gray_shape"
                android:contentDescription="@string/gray_overlay" />

        </FrameLayout>

    </LinearLayout>

</LinearLayout>

And I am trying to programmatically take care of the positions of the images. The problem is that the result is not what I want it to be, which would be three images centered in the form of a pyramid. Die number 1 is the top, and 2 and 3 bottom left and right respectively.

FrameLayout[] frames = new FrameLayout[] {(FrameLayout) findViewById(R.id.die_frame_1),
            (FrameLayout) findViewById(R.id.die_frame_2),
            (FrameLayout) findViewById(R.id.die_frame_3)};
Point size = getSize();
int width = size.x;
int height = size.y;
LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) frames[0].getLayoutParams();
// Width will be restricted either by height or width. Dice should take max 50% of screen
int frameWidth = (int) Math.min(width * 0.44, height * 0.5 * 0.44); // Each dice 40%
params.width = frameWidth;
params.height = frameWidth; // Square, so width equals height
// Ensure that the space between each dice is equal
int frameHeightMargin = (int) (height * 0.5 - frameWidth * 2) / 3; // Divide the remainder evenly
int frameWidthMarginOuter = (int) (width - 2 * frameWidth - frameHeightMargin) / 2; // Calculate outer
int frameWidthMarginCenter = (int) frameHeightMargin / 2; // Same spacing between dice
int frameWidthMarginUpper = (int) (width - frameWidth) / 2; // Upper only
for (int i = 0; i < frames.length; i++) {
    if (i == 0) {
        params.setMargins(frameWidthMarginUpper, frameHeightMargin, frameWidthMarginUpper, frameWidthMarginCenter); // Gravity is centered
    } else if (i == 1) { // Left dice
        params.setMargins(frameWidthMarginOuter, frameWidthMarginCenter, frameWidthMarginCenter, frameHeightMargin);
    } else if (i == 2) {// Right dice
        params.setMargins(frameWidthMarginCenter, frameWidthMarginCenter, frameWidthMarginOuter, frameHeightMargin);
    }
    frames[i].setLayoutParams(params);
}

Current result: Dice

The code is in the onCreate method by the way. I have both tried with and without requestLayout() for the FrameLayouts and the parents.

Était-ce utile?

La solution

Unless you know exactly what you are doing do not use the same LayoutParams for more than one ViewGroup. The solution is very simple. Create a new LayoutParams for each die.

FrameLayout[] frames = new FrameLayout[] {(FrameLayout) findViewById(R.id.die_frame_1),
        (FrameLayout) findViewById(R.id.die_frame_2),
        (FrameLayout) findViewById(R.id.die_frame_3)};
Point size = getSize();
int width = size.x;
int height = size.y;
// Width will be restricted either by height or width. Dice should take max 50% of screen
int frameWidth = (int) Math.min(width * 0.44, height * 0.5 * 0.44); // Each dice 40%
// Ensure that the space between each dice is equal
int frameHeightMargin = (int) (height * 0.5 - frameWidth * 2) / 3; // Divide the remainder evenly
int frameWidthMarginOuter = (int) (width - 2 * frameWidth - frameHeightMargin) / 2; // Calculate outer
int frameWidthMarginCenter = (int) frameHeightMargin / 2; // Same spacing between dice
int frameWidthMarginUpper = (int) (width - frameWidth) / 2; // Upper only
for (int i = 0; i < frames.length; i++) {
    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
    params.width = frameWidth;
    params.height = frameWidth; // Square, so width equals height
    if (i == 0) {
        params.setMargins(frameWidthMarginUpper, frameHeightMargin, frameWidthMarginUpper, frameWidthMarginCenter); // Gravity is centered
    } else if (i == 1) { // Left dice
        params.setMargins(frameWidthMarginOuter, frameWidthMarginCenter, frameWidthMarginCenter, frameHeightMargin);
    } else if (i == 2) {// Right dice
        params.setMargins(frameWidthMarginCenter, frameWidthMarginCenter, frameWidthMarginOuter, frameHeightMargin);
    }
    frames[i].setLayoutParams(params);
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top