Android图形布局编辑器黑色主窗口,带有自定义布局

时间:2013-08-03 21:54:15

标签: android layout editor

我目前正在测试我在博客文章中找到的“ScalingLinearLayout”。 http://www.quadra-tec.net/~floppie/blag/2013/01/scalinglinearlayout-auto-scaling-layouts-in-android/

我的问题是图形布局编辑器的主预览窗口是黑色,而其他窗口显示预览(见下图)。

我之前已经看到过与自定义组件相似的行为,但根据我的经验,总是会出现任何内容都没有显示的情况。

之前有没有人见过这种行为并知道是什么原因造成的?

另请参阅以下相关代码

enter image description here

图片中的示例布局:

<com.nightfox.testapp.ScalingLinearLayout 
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FFFFFF"
android:gravity="center"
android:orientation="vertical"
tools:context=".FlowA1" >

<RelativeLayout
    android:layout_width="640px"
    android:layout_height="960px"
    android:gravity="center|bottom" >

    <Button
        android:id="@+id/button1"
        android:layout_width="400px"
        android:layout_height="200px"
        android:layout_alignParentTop="true"
        android:text="@string/no_set_alarm" />

    <Button
        android:id="@+id/button1"
        android:layout_width="400px"
        android:layout_height="200px"
        android:layout_alignParentBottom="true"
        android:text="@string/no_set_alarm" />

</RelativeLayout>

自定义ScalingLinearLayout如下所示:

package com.nightfox.testapp;

import android.content.Context;
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.util.Log;
import android.widget.LinearLayout;


public class ScalingLinearLayout extends LinearLayout {
int baseWidth;
int baseHeight;
boolean alreadyScaled;
float scale;
int expectedWidth;
int expectedHeight;

public ScalingLinearLayout(Context context) {
    super(context);

    Log.d("notcloud.view", "ScalingLinearLayout: width=" + this.getWidth() + ", height=" + this.getHeight());
    this.alreadyScaled = false;
}

public ScalingLinearLayout(Context context, AttributeSet attributes) {
    super(context, attributes);

    Log.d("notcloud.view", "ScalingLinearLayout: width=" + this.getWidth() + ", height=" + this.getHeight());
    this.alreadyScaled = false;
}

public void onFinishInflate() {
    Log.d("notcloud.view", "ScalingLinearLayout::onFinishInflate: 1 width=" + this.getWidth() + ", height=" + this.getHeight());

    // Do an initial measurement of this layout with no major restrictions on size.
    // This will allow us to figure out what the original desired width and height are.
    this.measure(1000, 1000); // Adjust this up if necessary.
    this.baseWidth = this.getMeasuredWidth();
    this.baseHeight = this.getMeasuredHeight();
    Log.d("notcloud.view", "ScalingLinearLayout::onFinishInflate: 2 width=" + this.getWidth() + ", height=" + this.getHeight());

    Log.d("notcloud.view", "ScalingLinearLayout::onFinishInflate: alreadyScaled=" + this.alreadyScaled);
    Log.d("notcloud.view", "ScalingLinearLayout::onFinishInflate: scale=" + this.scale);
    if(this.alreadyScaled) {
        Scale.scaleViewAndChildren((LinearLayout)this, this.scale, 0);
    }
}

public void draw(Canvas canvas) {
    // Get the current width and height.
    int width = this.getWidth();
    int height = this.getHeight();

    // Figure out if we need to scale the layout.
    // We may need to scale if:
    //    1. We haven't scaled it before.
    //    2. The width has changed.
    //    3. The height has changed.
    if(!this.alreadyScaled || width != this.expectedWidth || height != this.expectedHeight) {
        // Figure out the x-scaling.
        float xScale = (float)width / this.baseWidth;
        if(this.alreadyScaled && width != this.expectedWidth) {
            xScale = (float)width / this.expectedWidth;
        }
        // Figure out the y-scaling.
        float yScale = (float)height / this.baseHeight;
        if(this.alreadyScaled && height != this.expectedHeight) {
            yScale = (float)height / this.expectedHeight;
        }

        // Scale the layout.
        this.scale = Math.min(xScale, yScale);
        Log.d("notcloud.view", "ScalingLinearLayout::onLayout: Scaling!");
        Scale.scaleViewAndChildren((LinearLayout)this, this.scale, 0);

        // Mark that we've already scaled this layout, and what
        // the width and height were when we did so.
        this.alreadyScaled = true;
        this.expectedWidth = width;
        this.expectedHeight = height;

        // Finally, return.
        return;
    }

    super.draw(canvas);
}

}

和Scale类:

package com.nightfox.testapp;

import android.util.Log;
import android.view.View;
import android.view.ViewGroup;

public class Scale {
public static void scaleContents(View rootView, View container) {
    Scale.scaleContents(rootView, container, rootView.getWidth(), rootView.getHeight());
}

// Scales the contents of the given view so that it completely fills the given
// container on one axis (that is, we're scaling isotropically).
public static void scaleContents(View rootView, View container, int width, int height) {
    Log.d("notcloud.scale", "Scale::scaleContents: container: " + container.getWidth() + "x" + container.getHeight() + ".");

    // Compute the scaling ratio
    float xScale = (float)container.getWidth() / width;
    float yScale = (float)container.getHeight() / height;
    float scale = Math.min(xScale, yScale);

    // Scale our contents
    Log.d("notcloud.scale", "Scale::scaleContents: scale=" + scale + ", width=" + width + ", height=" + height + ".");
    scaleViewAndChildren(rootView, scale, 0);
}

// Scale the given view, its contents, and all of its children by the given factor.
public static void scaleViewAndChildren(View root, float scale, int canary) {
    // Retrieve the view's layout information
    ViewGroup.LayoutParams layoutParams = root.getLayoutParams();

    // Scale the View itself
    if(layoutParams.width != ViewGroup.LayoutParams.MATCH_PARENT && layoutParams.width != ViewGroup.LayoutParams.WRAP_CONTENT) {
        layoutParams.width *= scale;
    }
    if(layoutParams.height != ViewGroup.LayoutParams.MATCH_PARENT && layoutParams.height != ViewGroup.LayoutParams.WRAP_CONTENT) {
        layoutParams.height *= scale;
    }

    // If the View has margins, scale those too
    if(layoutParams instanceof ViewGroup.MarginLayoutParams) {
        ViewGroup.MarginLayoutParams marginParams = (ViewGroup.MarginLayoutParams)layoutParams;
        marginParams.leftMargin *= scale;
        marginParams.topMargin *= scale;
        marginParams.rightMargin *= scale;
        marginParams.bottomMargin *= scale;
    }
    root.setLayoutParams(layoutParams);

    // Same treatment for padding
    root.setPadding(
        (int)(root.getPaddingLeft() * scale),
        (int)(root.getPaddingTop() * scale),
        (int)(root.getPaddingRight() * scale),
        (int)(root.getPaddingBottom() * scale)
    );

    // If it's a TextView, scale the font size
    /*
    if(root instanceof TextView) {
        TextView tv = (TextView)root;
        tv.setTextSize(tv.getTextSize() * scale); //< We do NOT want to do this.
    }
    */

    // If it's a ViewGroup, recurse!
    if(root instanceof ViewGroup) {
        ViewGroup vg = (ViewGroup)root;
        for(int i = 0; i < vg.getChildCount(); i++) {
            scaleViewAndChildren(vg.getChildAt(i), scale, canary + 1);
        }
    }
}

}

1 个答案:

答案 0 :(得分:1)

这是因为您已编辑该特定xml文件的主题。你只需要点击你想要的xml并从屏幕右侧的主题选项中改变它的主题,从你的nexus S选择...或者你可以转到res&gt;值&gt;字符串并更改负责的字符串主题选择。