Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Render Xamarin Forms view as Android view without specifying size

I am using a native Xamarin.Android RecyclerView in my XAML as described here. RecyclerView manages one view per item on the screen (just displayed as a vertical list in my app). This works fine if I use a Xamarin.Android view as the item view (in this example, a TextView):

public override RecyclerView.ViewHolder OnCreateViewHolder(ViewGroup parent, int viewType)
{
  var view = new TextView(parent.Context);
  return new TestViewHolder(view);
}

What I'd really like to do, though, is define a Xamarin.Forms control and have the RecyclerView use that. I can use a built-in Android renderer to get an Android view, and that works (i.e., displays the correct data):

public override RecyclerView.ViewHolder OnCreateViewHolder(ViewGroup parent, int viewType)
{
    var label = new Label { Text = "Hello!" };
    var cv = new ContentView
    {
        VerticalOptions = LayoutOptions.Start,
        HorizontalOptions = LayoutOptions.Start,
        Content = label,
    };
    var renderer = Xamarin.Forms.Platform.Android.Platform.CreateRendererWithContext(cv, parent.Context);
    var view = renderer.View;
    renderer.Tracker.UpdateLayout();
    view.LayoutParameters = new RecyclerView.LayoutParams(parent.Width, parent.Height);
    cv.Layout(Rectangle.FromLTRB(0, 0, parent.Width, parent.Height));
    view.Layout(0, 0, (int)cv.Width, (int)cv.Height);

    return new TestViewHolder(label, view);
}

However, the resulting Android view always has its height and width set to whatever size I pass in, even if I use horizontal/vertical options of Start everywhere. What I want is for the Android view to only take up the space that it needs (at least vertically; it's free to expand horizontally).

Similar question, without any answers: How to add Xamarin Forms content as a subview in Xamarin.Android and Xamarin.iOS

like image 857
Stephen Cleary Avatar asked Feb 17 '18 16:02

Stephen Cleary


1 Answers

You can use the native UI control.

TextView instead of Label, LinearLayout or other ViewGroup instead of ContentView.

These Native UI control can achieve the same goal, just change TestViewHolder class and OnCreateViewHolder method, like below:

TestViewHolder:

public class TestViewHolder : RecyclerView.ViewHolder
{

    public TextView Label { get; }

    public TestViewHolder(TextView label, Android.Views.View view) : base(view)
    {
        Label = label;

    }
}

OnCreateViewHolder:

public override RecyclerView.ViewHolder OnCreateViewHolder(ViewGroup parent, int viewType)
{
    TextView tv = new TextView(parent.Context);
    tv.SetTextColor(Android.Graphics.Color.Black);
    tv.SetTextSize(Android.Util.ComplexUnitType.Dip,5.0f);
    tv.SetBackgroundColor(Android.Graphics.Color.Red);
    LinearLayout ll = new LinearLayout(parent.Context);
    ll.LayoutParameters=new RecyclerView.LayoutParams(RecyclerView.LayoutParams.MatchParent, RecyclerView.LayoutParams.WrapContent);
    ll.SetBackgroundColor(Android.Graphics.Color.Green);
    ll.AddView(tv);

    return new TestViewHolder(tv,ll);
}
like image 71
Robbit Avatar answered Sep 29 '22 00:09

Robbit