Quantcast
Channel: Xamarin.Forms — Xamarin Community Forums
Viewing all articles
Browse latest Browse all 77050

How do i render the contents of a xamarin forms (portable) control in custom renderers?

$
0
0

This is my code so far (Works, but I can’t figure out the missing bit):

Shared project:

using System;
using Xamarin.Forms;

namespace Solvum.SiteTracker.Mobile.XamarinForms.Framework.Controls
{
public enum DrawerPosition
{
Left,
Right
}

public interface ISideDrawerNativeEventProxy
{
void RaiseSlideChanged(float percentage);
}

public class SideDrawer : Grid, ISideDrawerNativeEventProxy
{

public static BindableProperty DrawerSizeProperty = BindableProperty.Create<SideDrawer, MaxedPercentSize>(d => d.DrawerSize, new MaxedPercentSize(MaxedPercentSizeType.Width, 80, 400));

public MaxedPercentSize DrawerSize
{
get { return (MaxedPercentSize) GetValue(DrawerSizeProperty); }
set { SetValue(DrawerSizeProperty, value); }
}

public static BindableProperty IsOpenProperty = BindableProperty.Create<SideDrawer, bool>(d => d.IsOpen, default(bool));

public bool IsOpen
{
get { return (bool) GetValue(IsOpenProperty); }
set { SetValue(IsOpenProperty, value); }
}

public static BindableProperty DrawerPositionProperty = BindableProperty.Create<SideDrawer, DrawerPosition>(d => d.DrawerPosition, default(DrawerPosition));

public DrawerPosition DrawerPosition
{
get { return (DrawerPosition) GetValue(DrawerPositionProperty); }
set { SetValue(DrawerPositionProperty, value); }
}

public static BindableProperty MainContentProperty = BindableProperty.Create<SideDrawer, View>(d => d.MainContent, default(View));

public View MainContent
{
get { return (View) GetValue(MainContentProperty); }
set { SetValue(MainContentProperty, value); }
}

public static BindableProperty DrawerContentProperty = BindableProperty.Create<SideDrawer, View>(d => d.DrawerContent, default(View));

public View DrawerContent
{
get { return (View) GetValue(DrawerContentProperty); }
set { SetValue(DrawerContentProperty, value); }
}

public static BindableProperty DrawerLengthProperty = BindableProperty.Create<SideDrawer, int>(d => d.DrawerLength, default(int), defaultValueCreator: DrawerLengthDefault);

private static int DrawerLengthDefault(SideDrawer bindable)
{
return 300;
}

public int DrawerLength
{
get { return (int) GetValue(DrawerLengthProperty); }
set { SetValue(DrawerLengthProperty, value); }
}

public static BindableProperty IsContentTranslatedProperty = BindableProperty.Create<SideDrawer, bool>(d => d.IsContentTranslated, true);

public bool IsContentTranslated
{
get { return (bool) GetValue(IsContentTranslatedProperty); }
set { SetValue(IsContentTranslatedProperty, value); }
}

void ISideDrawerNativeEventProxy.RaiseSlideChanged(float percentage)
{
}
}
}

Android:

using System;
using System.ComponentModel;
using Android.Support.V4.Widget;
using Android.Views;
using Android.Widget;
using Solvum.SiteTracker.Mobile.XamarinForms.Droid.Controls.SideDrawer;
using Solvum.SiteTracker.Mobile.XamarinForms.Framework.Controls;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
using Android.Graphics;
using Application = Android.App.Application;
using Color = Android.Graphics.Color;
using RelativeLayout = Android.Widget.RelativeLayout;
using View = Android.Views.View;

[assembly: ExportRenderer(typeof(SideDrawer), typeof(SideDrawerRenderer))]
namespace Solvum.SiteTracker.Mobile.XamarinForms.Droid.Controls.SideDrawer
{
// public class SideDrawerRenderer : Xamarin.Forms.Platform.Android.AppCompat.ViewRenderer<Framework.Controls.SideDrawer, DrawerLayout>, DrawerLayout.IDrawerListener
public class SideDrawerRenderer : ViewRenderer<Framework.Controls.SideDrawer, DrawerLayout>, DrawerLayout.IDrawerListener
{
private DrawerLayout _nativeDrawerLayout;
private MarginLayoutParams _contentLayoutParameters;
private RelativeLayout _contentView;
private TextView _drawerView;

protected override void OnElementChanged(ElementChangedEventArgs<Framework.Controls.SideDrawer> e)
{
base.OnElementChanged(e);

if (this.Control == null)
{
InitializeNativeControl();
}
if (e.OldElement != null)
{
_nativeDrawerLayout.SetDrawerListener(null);
}
if (e.NewElement != null)
{
_nativeDrawerLayout.SetDrawerListener(this);
}
}

private void InitializeNativeControl()
{
_nativeDrawerLayout = new DrawerLayout(Context.ApplicationContext);
_nativeDrawerLayout.SetBackgroundColor(Element.BackgroundColor.ToAndroid());

_contentLayoutParameters = new MarginLayoutParams(LayoutParams.MatchParent, LayoutParams.MatchParent);
var layoutParamsDrawer = new DrawerLayout.LayoutParams(Element.DrawerLength, LinearLayout.LayoutParams.MatchParent);
layoutParamsDrawer.Gravity = GetDrawerGravity();

_drawerView = GetDrawerView(layoutParamsDrawer);
_contentView = GetContentView(_contentLayoutParameters);

// this one works, but i need the content from my forms property
var contentChild = new RelativeLayout(Context.ApplicationContext);
var contentChildLParams = new RelativeLayout.LayoutParams(300, 300);
contentChild.SetBackgroundColor(Color.Yellow);
_contentView.AddView(contentChild, contentChildLParams);

// i need to figure out how to make this work
// var contentRenderer = RendererFactory.GetRenderer(Element.MainContent);
// _contentView.AddView(contentRenderer.ViewGroup, new LayoutParams(LayoutParams.MatchParent, LayoutParams.MatchParent));

_nativeDrawerLayout.AddView(_drawerView);
_nativeDrawerLayout.AddView(_contentView);

SetNativeControl(_nativeDrawerLayout);
}

private int GetDrawerGravity()
{
switch (Element.DrawerPosition)
{
case DrawerPosition.Left:
return (int)GravityFlags.Start;
case DrawerPosition.Right:
return (int)GravityFlags.End;
default:
throw new ArgumentOutOfRangeException();
}
}

private RelativeLayout GetContentView(LayoutParams layoutParameters)
{
var view = new RelativeLayout(Context.ApplicationContext);
view.LayoutParameters = layoutParameters;
view.SetBackgroundColor(Color.Red);
return view;
}

private TextView GetDrawerView(LayoutParams layoutParameters)
{
var view = new TextView(Context.ApplicationContext);
view.LayoutParameters = layoutParameters;
view.SetBackgroundColor(Color.Purple);
view.SetTextColor(Color.Blue);
view.SetText("just some text", TextView.BufferType.Editable);
return view;
}

protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);

switch (e.PropertyName)
{
case nameof(Framework.Controls.SideDrawer.Height):
break;
case nameof(Framework.Controls.SideDrawer.Width):
break;
}
}

public void OnDrawerClosed(View drawerView)
{
Element.IsOpen = false;
System.Diagnostics.Debug.WriteLine("OnDrawerClosed");
}

public void OnDrawerOpened(View drawerView)
{
Element.IsOpen = true;
System.Diagnostics.Debug.WriteLine("OnDrawerOpened");
}

public void OnDrawerSlide(View drawerView, float slideOffset)
{
switch (Element.DrawerPosition)
{
case DrawerPosition.Left:
_contentView.TranslationX = (int) Math.Abs(Element.DrawerLength*slideOffset);
break;
case DrawerPosition.Right:
_contentView.TranslationX = (int) Math.Abs(Element.DrawerLength*slideOffset)*-1;
break;
default:
throw new ArgumentOutOfRangeException();
}

_nativeDrawerLayout.BringChildToFront(_drawerView);
_nativeDrawerLayout.RequestLayout();

((ISideDrawerNativeEventProxy) Element)?.RaiseSlideChanged(slideOffset);
}

public void OnDrawerStateChanged(int newState)
{
// not really needed
// System.Diagnostics.Debug.WriteLine($"OnDrawerStateChanged {newState}");
}
}
}

Any ideas? Support refused to answer this one because it's "code help" (even though there is just no documentation on this).


Viewing all articles
Browse latest Browse all 77050

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>