2017-06-05 63 views
1

我在運行時在畫布內呈現RelativeLayout時遇到問題。我知道這是Xamarin.Android,但它實際上與「原始」Android非常相似,所以我會接受所有可行的解決方案。RelativeLayout不尊重父界限

我有這樣的XML正確呈現我的觀點裏(向下滾動,爲 「score_progress_bar」 XML):

<LinearLayout android:layout_width="wrap_content" 
       android:layout_height="wrap_content"> 
      <include 
       layout="@layout/score_progress_bar" 
       android:layout_width="50dp" 
       android:layout_height="50dp" /> 
</LinearLayout> 

這裏是正確的結果:

Expected result

如果我嘗試通過Canvas加載相同的東西,我沒有得到相同的結果。這裏就是我試圖在運行時加載相同的控制代碼:

var id = Application.Context.Resources.GetIdentifier("score_progress_bar", "layout", Application.Context.PackageName); 

var ll = new LinearLayout(Application.Context); 
ll.SetBackgroundColor(AndroidColor.Red); 
ll.Measure(50, 50); 
ll.Layout(0, 0, 50, 50); 

var li = (LayoutInflater)Application.Context.GetSystemService(Context.LayoutInflaterService); 
var v = (RelativeLayout)li.Inflate(id, null, true); 
v.LayoutParameters = new RelativeLayout.LayoutParams(50, 50); 
v.Measure(50, 50); 
v.Layout(0, 0, 50, 50); 

ll.AddView(v); 
ll.Draw(Native); 

只要是明確的,「本地」是我的畫布對象,我設置一個紅色的背景色爲的LinearLayout所以我可以看到這是在我的視圖中加載的位置。

我得到的結果是怪異的的LinearLayout是被正確渲染,但在「score_progress_bar」對象不是,現在看來似乎有邊距或某個地方的界限沒有設置(注意, TextView中以數字 「25」 是不是在觀察中心):

Actual result

如果您需要 「score_progress_xml」,這裏是(它只是一個的RelativeLayout有一些看法):

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:local="http://schemas.android.com/apk/res-auto" 
    android:orientation="vertical" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent"> 
    <View 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:background="@drawable/score_white_background" 
     android:layout_marginLeft="2dp" 
     android:layout_marginRight="2dp" 
     android:layout_marginTop="2dp" 
     android:layout_marginBottom="2dp" /> 
    <ProgressBar 
     android:id="@+id/progressRing" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     android:indeterminate="false" 
     android:progressDrawable="@drawable/score_background_ring" 
     style="?android:attr/progressBarStyleHorizontal" 
     android:max="100" 
     android:progress="25" /> 
    <TextView 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     android:text="25" 
     android:textSize="17dp" 
     android:textColor="#000000" 
     android:id="@+id/progressText" 
     android:gravity="center" /> 
</RelativeLayout> 

你對這裏發生了什麼有什麼想法嗎?

編輯:發現解決方案感謝SushiHangover! 剛剛完成的情況下,其他人可能需要它這個問題,這是我在這個特定的情況下,如何解決:

var id = Application.Context.Resources.GetIdentifier("score_progress_bar", "layout", Application.Context.PackageName); 
var li = (LayoutInflater)Application.Context.GetSystemService(Context.LayoutInflaterService); 
var progressView = (RelativeLayout)li.Inflate(id, null, true); 

var measuredWidth = View.MeasureSpec.MakeMeasureSpec(50, MeasureSpecMode.Exactly); 
var measuredHeight = View.MeasureSpec.MakeMeasureSpec(50, MeasureSpecMode.Exactly); 
progressView.Measure(measuredWidth, measuredHeight); 
progressView.Layout(0, 0, progressView.MeasuredWidth, progressView.MeasuredWidth); 

progressView.Draw(Native); 

回答

1

您需要使用的結果從View.MeasureSpec.MakeMeasureSpec爲你的X/Y測量的產地爲呼叫到View.Measure,然後使用View.MeasuredWidth,在你的情況下,你的View.Layout調用應該是50。現在視圖及其所有子項都正確佈置,您可以將Draw添加到您的Canvas

下面是我用來生成一系列倒計時位圖的例程的一個版本(它們被作爲紋理饋給OpenGL)。

var xy = 200; 
var inflater = (LayoutInflater)ApplicationContext.GetSystemService(LayoutInflaterService); 
var progressIncludeID = ApplicationContext.Resources.GetIdentifier("progress_include", "layout", ApplicationContext.PackageName); 
var pseudoProgressView = (RelativeLayout)inflater.Inflate(progressIncludeID, null, false); 

int measuredWidth = View.MeasureSpec.MakeMeasureSpec(xy, MeasureSpecMode.Exactly); 
int measuredHeight = View.MeasureSpec.MakeMeasureSpec(xy, MeasureSpecMode.Exactly); 
pseudoProgressView.Measure(measuredWidth, measuredHeight); 
pseudoProgressView.Layout(0, 0, pseudoProgressView.MeasuredWidth, pseudoProgressView.MeasuredWidth); 

var imageBitmap = Bitmap.CreateBitmap(xy, xy, Bitmap.Config.Argb8888); 
var canvas = new Canvas(imageBitmap); 
pseudoProgressView.Draw(canvas); 

圖像下面內呈現在頂進度一個包括基礎的屏幕上的RelativeLayout和底部的一個是ImageView表示完全離屏描繪的相同的RelativeLayout的位圖充氣axml :

enter image description here

+0

在我來說,特別是我已經做到了,而無需創建一個新的位圖,因爲渲染直接應用到畫布上,但它的作品。謝謝! – xTuMiOx