2013-08-03 51 views
1

我目前正在测试我在博客文章中找到的“ScalingLinearLayout”。 http://www.quadra-tec.net/~floppie/blag/2013/01/scalinglinearlayout-auto-scaling-layouts-in-android/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); 
} 

}

和规模类:

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

这是因为你已经编辑特定的XML文件的主题。你只需要点击你想要的xml,并从屏幕右侧的主题选项右键改变它的主题,从你的nexus S选择...或者你可以转到res> values>字符串,并改变字符串负责为主题选择。

+0

或者可能你的主题是黑色的,但你已经手动将背景设置为白色,如上面给出的xml文件中所示 –

+0

我尝试将主题改变为一堆不同的替代品,但我仍然没有看到布局。如果我例如选择Theme.Light,屏幕变成白色而不是黑色,但我仍然没有看到我的组件 – Daniel

+0

替换你的这行xml布局** android:background =“#FFFFFF”** with this ** android:background =“#66FFFFFF”**如果你发现了这个改变,那么你可能需要删除这行...... –