2013-08-03 87 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」**如果你發現了這個改變,那麼你可能需要刪除這行...... –