类ButterKnife,注解绑定控件

Unity开发过程中,控件的获取是件繁琐的工作。Android的ButterKnife可很好绑定控件,以此为灵感,在Unity中实现了控件的注解绑定。

步骤一:自定义属性

 [AttributeUsage(AttributeTargets.Field)]
    public class ComponentKey : Attribute
    {
        private string key;

        public string Key => key;

        public ComponentKey(string key)
        {
            this.key = key;
        }
    }
[AttributeUsage(AttributeTargets.Field)]为字段属性。key为对应的控件关键字。

步骤二:定义基类ButterKnifeBaseView

 public class ButterKnifeBaseView : MonoBehaviour
    {
        private static readonly List<string> keyHeads = new List<string>()
        {
            "btn_", "image_", "txt_", "ipt_"
        };

        private Dictionary<string, GameObject> _dicObjectList = new Dictionary<string, GameObject>();

        protected virtual void Awake()
        {
            InitComponent();
            ButterKnifeBind();
        }

        private void ButterKnifeBind()
        {
            var type = GetType();
            var fieldInfos = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
            foreach (var fieldInfo in fieldInfos)
            {
                var attribute = fieldInfo.GetCustomAttributes(typeof(ComponentKey)).FirstOrDefault();
                if (attribute != null && attribute is ComponentKey)
                {
                    var componentKey = (attribute as ComponentKey).Key;
                    var component = GetComponentByObjName(fieldInfo.FieldType, componentKey);
                    fieldInfo.SetValue(this, component);
                }
            }
        }

        private void InitComponent()
        {
            var childArray = GetComponentsInChildren<Transform>(true);
            if (childArray != null && childArray.Length > 0)
            {
                foreach (var childTf in childArray)
                {
                    int index = childTf.name.IndexOf("_", StringComparison.Ordinal);
                    if (index == -1)
                    {
                        continue;
                    }

                    string head = childTf.name.Substring(0, index + 1);
                    if (keyHeads.Contains(head))
                    {
                        if (!_dicObjectList.ContainsKey(childTf.name))
                        {
                            _dicObjectList[childTf.name] = childTf.gameObject;
                        }
                        else
                        {
                            Debug.LogError(string.Format("key:{0} has exist,please check", childTf.name));
                        }
                    }
                }
            }
        }

        protected Component GetComponentByObjName(Type type, string name)
        {
            if (_dicObjectList.ContainsKey(name) && _dicObjectList[name] != null)
            {
                return _dicObjectList[name].GetComponent(type);
            }

            return null;
        }
    }

关键方法ButterKnifeBind通过反射获取控件中属性值。获取控件通过Type方法获取。获取完后, fieldInfo.SetValue(this, component)将值设置到控件中即可

步骤三:预制中需绑定的脚本

 [AASKey("TestButterKnifePrefab")]
    public class TestButterKnifePrefab : ButterKnifeBaseView
    {
        [ComponentKey("btn_click")] private Button btn_click;
        [ComponentKey("txt_content")] private Text txt_content;
        [ComponentKey("image_bg")] private Image image_bg;
        [ComponentKey("ipt_name")] private InputField ipt_name;
        
        private const string Sprite_Key = "TestImage";

        private void Awake()
        {
            base.Awake();
            
            btn_click.onClick.AddListener(OnBtnClick);
            txt_content.text = "hello world!!!";
            ipt_name.text = "unity3d";
            Addressables.LoadAssetAsync<Sprite>(Sprite_Key).Completed += op => { image_bg.sprite = op.Result; };
        }
        
        private void OnBtnClick()
        {
            Debug.LogError("OnBtnClick Event");
        }
    }

使用方式简单,只要在控件变量中定义属性的key即可获取到控件。可以很方便程序开发。
利用反射的方式获取控件缺点:反射比较耗性能,故需实例化大量的预制不推荐使用此方式。

步骤四:资源获取

https://download.csdn.net/download/EIE08027/11970159

免费获取,可以加我qq:416390409获取,备注csdn
TODO 后期会更新用编辑器的方式动态生成控件定义的基础脚本,使用只要实现逻辑部分。这样会更方便大家的使用。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值