【问题标题】:Programmatic Margin for LinearLayout is ignored忽略 LinearLayout 的编程边距
【发布时间】:2014-05-17 18:29:36
【问题描述】:

我有一个 Android 布局:

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

我正在尝试以编程方式处理图像的位置。问题是结果不是我想要的,这将是三个以金字塔形式居中的图像。 1 号骰子是顶部,2 号和 3 号分别是左下角和右下角。

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

当前结果:

顺便说一句,代码在 onCreate 方法中。对于 FrameLayouts 和父母,我都尝试过使用和不使用 requestLayout()。

【问题讨论】:

  • 您是否有必要以编程方式进行操作?使用xml中的布局来实现这一点不是更简单吗?
  • 公平的问题。我想这样做是为了省去为所有设备修复此问题的麻烦。虽然我开始觉得我会比手动方式更好。
  • 我明白了。我现在帮不了你了,祝你好运。

标签: android layout imageview layoutparams


【解决方案1】:

除非您确切知道自己在做什么,否则不要为多个 ViewGroup 使用相同的 LayoutParams。解决方案非常简单。为每个 die 创建一个新的 LayoutParams。

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

【讨论】:

    猜你喜欢
    • 2013-11-01
    • 2013-08-18
    • 1970-01-01
    • 2020-06-26
    • 2011-06-22
    • 2020-09-22
    • 2019-12-12
    • 2011-01-29
    • 2019-05-16
    相关资源
    最近更新 更多