2017-06-05 4 views
1

Ich habe Probleme beim Rendern einer RelativeLayout zur Laufzeit innerhalb einer Canvas. Ich weiß, das ist Xamarin.Android, aber es ist eigentlich ziemlich identisch mit "Original" Android, also werde ich jede Lösung akzeptieren, die funktioniert.RelativeLayout respektiert nicht die übergeordneten Grenzen

ich diese xml haben, die richtig in meiner Ansicht rendert (nach unten scrollen für die "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> 

Und hier ist das richtige Ergebnis:

Expected result

Wenn ich versuche, dasselbe über eine Canvas zu laden, bekomme ich nicht das gleiche Ergebnis. Hier ist der Code, wo ich versuche, die gleiche Steuerung zur Laufzeit zu laden:

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

Nur um klar zu sein, „india“ ist mein Canvas-Objekt, und ich bin eine rote Hintergrundfarbe auf das Linearlayout Einstellung so Ich kann sehen, wo das in meiner Sicht geladen ist.

Das Ergebnis erhalte ich seltsam ist, das Linearlayout ist korrekt wiedergegeben werden, aber die „score_progress_bar“ Objekt ist nicht, es scheint, als ob es Spielraum irgendwo hat oder dass die Grenzen nicht gesetzt ist (man beachte, dass die Textview mit der Nummer "25" ist in der Ansicht Zentrum nicht):

Actual result

Wenn Sie die "score_progress_xml" brauchen, hier ist es (es ist nur ein RelativeLayout mit einigen Ansichten):

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

Haben Sie eine Idee, was hier vor sich geht?

Bearbeiten: eine Lösung gefunden dank SushiHangover! Genau diese Frage im Fall, dass jemand zu vervollständigen sonst es brauchen kann, ist hier, wie ich in diesem speziellen Fall gelöst:

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

Antwort

1

Sie müssen das Ergebnis aus View.MeasureSpec.MakeMeasureSpec als Ursprung der X/Y-Messungen für die Verbindung verwenden, zu View.Measure und dann verwenden Sie View.MeasuredWidth, die in Ihrem Fall 50 sein sollten, in Ihrem View.Layout Anruf. Jetzt sind die View und alle ihre Kinder korrekt angelegt und Sie können Draw zu Ihrem Canvas.

Hier ist eine abgespeckte Version der Routine, die ich benutze, um eine Reihe von Countdown-Bitmaps zu generieren (sie werden als Texturen zu OpenGL gefüttert).

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

Die obere ProgressBar- im Bild unten wiedergegeben wird, schließt ein innerhalb RelativeLayout auf den Bildschirm und die auf der Unterseite ist eine -basierte ImageView das Bitmap einer vollständig Off-Screen-Wiedergabe von den gleichen RelativeLayout axml aufgeblasen zeigt, :

enter image description here

+0

In meinem Fall speziell habe ich es getan, ohne eine neue Bitmap Erstellen des Render da direkt auf die Leinwand trifft, aber es funktioniert. Vielen Dank! – xTuMiOx

Verwandte Themen