Пользовательский рендерер для Android CardView не показывает содержимое компонента Forms

#xamarin #xamarin.android #xamarin.forms

#xamarin #xamarin.android #xamarin.forms

Вопрос:

Я создал пользовательский компонент, который расширяет contentView и средство визуализации, которое отображает в CardView на Android.

Проблема, с которой я сталкиваюсь, заключается в том, что содержимое форм отображается ниже CardView. На KitKat этого не происходит, но я думаю, что реализация CardView не такая, как на Lollipop или новее.

Установка цвета фона CardView на прозрачный (0x00000000) показывает содержимое под CardView.

Компонент forms:

 using Xamarin.Forms;

namespace CodeFest
{
    public class NativeClientProfile : ContentView
    {
        public NativeClientProfile()
        {
            var grid = new Grid
            {
                RowDefinitions = new RowDefinitionCollection {new RowDefinition()},
                ColumnDefinitions = new ColumnDefinitionCollection {new ColumnDefinition(), new ColumnDefinition()}
            };
            grid.Children.Add(new Label {Text = "FSP No"}, 0, 0);
            grid.Children.Add(new Label {Text = "12345", HorizontalTextAlignment = TextAlignment.Center}, 1, 0);
            grid.Children.Add(new Label {Text = "Risk"}, 0, 1);
            grid.Children.Add(
                new Label {Text = "Low", TextColor = Color.Green, HorizontalTextAlignment = TextAlignment.Center}, 1, 1);
            var item = new Label
            {
                Text = "Foo bar",
                HorizontalTextAlignment = TextAlignment.Center,
                FontSize = 30,
                FontAttributes = FontAttributes.Bold
            }; 
            Content = new StackLayout
            {
                Children =
                {
                    item,
                    new Label
                    {
                        Text = "Financial Services Provider",
                        HorizontalTextAlignment = TextAlignment.Center
                    },
                    grid
                }
            };
        }
    }
}
  

Пользовательский рендерер:

 using Android.Support.V7.Widget;
using Android.Text;
using Android.Views;
using CodeFest;
using CodeFest.Droid.ComponentRenderers;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;

[assembly: ExportRenderer(typeof(NativeClientProfile), typeof(NativeClientProfileRenderer))]
namespace CodeFest.Droid.ComponentRenderers
{
    class NativeClientProfileRenderer : ViewRenderer<NativeClientProfile, CardView>
    {
        protected override void OnElementChanged(ElementChangedEventArgs<NativeClientProfile> elementChangedEventArgs)
        {
            var view = new CardView(Context);
            //view.SetCardBackgroundColor(0x00000000);
            SetNativeControl(view);
        }
    }
}
  

Я ищу пример того, как правильно отображать компоненты forms в пользовательском рендере CardView.

Комментарии:

1. CardView обычно используется с RecyclerView. Вы хотите использовать его вне RecyclerView? Если это автономный просмотр, то зачем вам CardView?

Ответ №1:

Вы можете использовать a Frame в качестве базового класса вместо ContentView . Преимущество этого в том, что вы можете использовать существующий FrameRenderer Xamarin.Forms.Platform.Android.AppCompat , который уже использует CardView . (см.: FrameRenderer.cs).

Объявление FrameRenderer

 public class FrameRenderer : CardView, IVisualElementRenderer, AView.IOnClickListener, AView.IOnTouchListener
  

Средство визуализации

 class NativeClientProfileRenderer : Xamarin.Forms.Platform.Android.AppCompat.FrameRenderer
{
    protected override void OnElementChanged(ElementChangedEventArgs<Frame> e)
    {
        base.OnElementChanged(e);
    }
}
  

NativeClientProfile

 public class NativeClientProfile : Frame
{
    public NativeClientProfile()
    {
        // your stuff...
        Content = new StackLayout
        {
            Children =
            {
                item,
                new Label
                {
                    Text = "Financial Services Provider",
                    HorizontalTextAlignment = TextAlignment.Center
                },
                grid
            }
        };
    }
}
  

Обсуждение

Средство визуализации показывает вам, что ему нужно, если вы действительно хотите сделать это вручную. Использование FrameRenderer делает ваш код зависимым от реализации Xamarin. Если они когда-либо изменят тип представления, отображаемого для a Frame , это приведет к поломке вашего приложения. Но если вы посмотрите на реализацию FrameRenderer, я бы постарался не создавать его полностью с нуля (простая оценка риска и усилий).