xamarin.forms中自定义控件的android实现

之前有介绍了forms和native的交互处理,为了使用第三方的android插件,做了forms到native的跳转,这时会有个性能问题:forms和native的出入口必须为指定的MainActivity和Application class,而每次经过这两个类时,所有的成员都会重新初始化。使用android的renderer自定义控件可以避免这个问题。

1、PCL中的Demo.xaml,在根节点ContentPage(举个例子)设置xmlns声明自定义控件所在的命名空间及程序集

xmlns:customcontrols="clr-namespace:AppPortable;assembly=AppPortable"

在控件调用处使用自定义节点

<customcontrols:Demo></customcontrols:Demo>

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:customcontrols="clr-namespace:AppPortable;assembly=AppPortable"
             x:Class="StoneAppPortable.CropImage">
  <customcontrols:Demo></customcontrols:Demo>
</ContentPage>
2、PCL中的Demo.cs,继承自View(举个例子,Forms内置很多控件类用来继承,与android项目中的renderer对应)

namespace AppPortable
{
    public class Demo : View
    {
        public Demo()
        {
            
        }
    }
}
3、android中的renderer,render的说明之前介绍过,这边只对实现逻辑说明

[assembly: ExportRenderer(typeof(StoneAppPortable.Demo), typeof(StoneApp.Droid.Renderers.DemoRenderer))]

namespace StoneApp.Droid.Renderers
{
    public class CropPageRenderer : ViewRenderer<Demo, Android.Views.View>
    {
        protected override void OnElementChanged(ElementChangedEventArgs<Demo> e)
        {
            base.OnElementChanged(e);
            if (e.NewElement != null)
            {
                //获取绑定的自定义控件对象
                var demo = e.NewElement as Demo;
                //获取当前上下文环境
                var activity = this.Context as Activity;
                //使用LayoutInflater获取Resource下layout,即用户自定义的控件布局
                var layoutId = Context.Resources.GetIdentifier("demolayout", "layout", activity.PackageName);
                var inflater = LayoutInflater.FromContext(activity);                
                var customView = inflater.Inflate(layoutId, null, false);\\参数请看官方api
                //获取layout中的控件,innerControlView为自定义的相应View,GetIdentifier的参数请看官方api
                var innerControlId = Context.Resources.GetIdentifier("innerControl", "id", activity.PackageName);
                innerControlView = customView.FindViewById<innerControlView>(imageId);
                
                //renderder结束后回调,这边假设自定义layout中按钮点击调用PCL中Demo类的成员函数OnSaveClicked
                var buttonId = Context.Resources.GetIdentifier("save", "id", activity.PackageName);
                customView.FindViewById<Android.Widget.Button>(buttonId).Click += async (sender, args) => {
                    await Elemnt.OnSaveClicked(activity);//Element为PCL中的绑定类
                };

                //完成控件的设置,若customView已存在则移除,最后加载
                var contentView = (ViewGroup)customView.Parent;
                if (contentView != null)
                {
                    var oldLayout = contentView.GetChildAt(1);
                    contentView.RemoveView(oldLayout);
                }
                SetNativeControl(customView);
            }
        }
    }
}






  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值