لا يقوم MvvmCross ViewTypeResolver بحل العلامة (الجزء أو النوع المخصص)

StackOverflow https://stackoverflow.com//questions/10698638

  •  12-12-2019
  •  | 
  •  

سؤال

الوضع الفعلي هو أنني أضفت إلى MvxViewTypeResolver فئة "الشظية" -Case، بحيث تبدو كما يلي:

 #region Copyright
// <copyright file="MvxViewTypeResolver.cs" company="Cirrious">
// (c) Copyright Cirrious. http://www.cirrious.com
// This source is subject to the Microsoft Public License (Ms-PL)
// Please see license.txt on http://opensource.org/licenses/ms-pl.html
// All other rights reserved.
// </copyright>
// 
// Project Lead - Stuart Lodge, Cirrious. http://www.cirrious.com
#endregion

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Android.Views;
using Cirrious.MvvmCross.Binding.Android.Interfaces.Binders;

namespace Cirrious.MvvmCross.Binding.Android.Binders
{
    public class MvxViewTypeResolver : IMvxViewTypeResolver
    {
        private Dictionary<string, Type> _cache = new Dictionary<string, Type>();

        public IDictionary<string, string> ViewNamespaceAbbreviations { get; set; }

        #region IMvxViewTypeResolver Members

        public virtual Type Resolve(string tagName)
        {
            Type toReturn;
            if (_cache.TryGetValue(tagName, out toReturn))
                return toReturn;

            var unabbreviatedTagName = UnabbreviateTagName(tagName);

            var longLowerCaseName = GetLookupName(unabbreviatedTagName);
            var viewType = typeof(View);

#warning AppDomain.CurrentDomain.GetAssemblies is only the loaded assemblies - so we might miss controls if not already loaded
            var query = from assembly in AppDomain.CurrentDomain.GetAssemblies()
                        from type in assembly.GetTypes()
                        where viewType.IsAssignableFrom(type)
                        where (type.FullName ?? "-").ToLowerInvariant() == longLowerCaseName
                        select type;

            toReturn = query.FirstOrDefault();
            _cache[tagName] = toReturn;

            return toReturn;
        }

        private string UnabbreviateTagName(string tagName)
        {
            var filteredTagName = tagName;
            if (ViewNamespaceAbbreviations != null)
            {
                var split = tagName.Split(new char[] {'.'}, 2, StringSplitOptions.RemoveEmptyEntries);
                if (split.Length == 2)
                {
                    var abbreviate = split[0];
                    string fullName;
                    if (ViewNamespaceAbbreviations.TryGetValue(abbreviate, out fullName))
                    {
                        filteredTagName = fullName + "." + split[1];
                    }
                }
            }
            return filteredTagName;
        }

        #endregion

        protected string GetLookupName(string tagName)
        {
            var nameBuilder = new StringBuilder();

            switch (tagName)
            {
                case "View":
                case "ViewGroup":
                    nameBuilder.Append("android.view.");
                    break;
                case "fragment":
                    nameBuilder.Append("android.app.");
                    break;
                default:
                    if (!IsFullyQualified(tagName))
                        nameBuilder.Append("android.widget.");
                    break;
            }

            nameBuilder.Append(tagName);
            return nameBuilder.ToString().ToLowerInvariant();
        }

        private static bool IsFullyQualified(string tagName)
        {
            return tagName.Contains(".");
        }
    }
}

الآن يتم تقديم الصحيح longLowerCaseTagName (android.app.fragment) ولكن في الاستعلام لا يتمكن من حل النوع.

اقتراحي هو عدم تحميل عنصر التحكم بالجزء عندما يجب حل النوع.ربما هناك طريقة أخرى لحل النوع؟

أيضًا إذا قمت بإضافة نوع مخصص (إعطاء العلامة Mvx.MyCustomType في axml) لم يتم حلها.هل يجب علي إضافة شيء ما في MvxBindingAttributes.xml في هذه الحالة؟

شكرا للمساعدة!

هل كانت مفيدة؟

المحلول

أولا شرح الكود :

يحاول مصنع نفخ XML المخصص الذي يستخدمه MvvmCross Binder تحميل طرق العرض بطريقة مشابهة جدًا لـ 2.x Android XML inflater القياسي.

الرمز الافتراضي لدقة نوع العرض موجود بالفعل في: https://github.com/slodge/MvvmCross/blob/master/Cirrious/Cirrious.MvvmCross.Binding/Android/Binders/MvxViewTypeResolver.cs

إذا كان ملف XML الخاص بك يحتوي على اسم مثل <MyCompany.MyProject.MyViews.MyFirstView /> ثم محلل نوع العرض:

  • يتحقق أولاً من الاختصارات ويوسعها إلى مساحات أسماء كاملة - بشكل افتراضي، الاختصار الوحيد المعروف هو Mvx. والذي اتسع ليشمل: Cirrious.MvvmCross.Binding.Android.Views..إذا كنت تريد إضافة المزيد من الاختصارات، فقم بالتجاوز ViewNamespaceAbbreviations في https://github.com/slodge/MvvmCross/blob/master/Cirrious/Cirrious.MvvmCross.Binding/Android/MvxBaseAndroidBindingSetup.cs

  • ثم يتحقق لمعرفة ما إذا كان الاسم غير المختصر هو اسم بدون مساحة اسم.إذا كان الأمر كذلك، فإنه يفترض أن الفئة هي مساحة اسم Android وتسبقها android.view. أو android.widget.

  • ثم يقوم بتحويل اسم مساحة الاسم بالكامل إلى أحرف صغيرة كمفتاح بحث غير حساس لحالة الأحرف

  • يستخدم هذا المفتاح الصغير للبحث في جميع الأنواع المشتقة من العرض في جميع التجميعات المحملة.

  • يقوم بتخزين النتيجة مؤقتًا (سواء كانت فارغة أم لا) من أجل تسريع عمليات التضخم اللاحقة.

تم تصميم كل هذا السلوك ليتوافق مع كود تضخم عرض Android xml الافتراضي http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/2.3.6_r1/android/view/LayoutInflater.java#LayoutInflater.createViewFromTag%28java.lang.String% 2Candroid.util.AttributeSet%29


مع هذا التوضيح بعيدًا - إليك إجابة لأسئلتك:


لا يحتوي MvvmCross حاليًا على أي دعم للأجزاء.تم إصدار دعم جزء MonoDroid الرسمي نفسه في الأسبوع الماضي فقط، ولم أطلب أي أجزاء حتى الآن - يبدو أن "تجزئة" Android قد أبقت معظم الأشخاص على التعليمات البرمجية المستندة إلى النشاط والحوار.

باختصار ؛ النظر في الوثائق ، fragment ليس عرض Android - يبدو أن Fragment يرث مباشرةً من Java.Lang.Object - راجع http://developer.android.com/reference/android/app/Fragment.html

ولهذا السبب، من غير الممكن أن يعمل MvvmCross ViewTypeResolver حاليًا مع الأجزاء.

أود أن أقترح أنه إذا كنت بحاجة إلى كل من mvvmcross والأجزاء اليوم، فإن أفضل رهان لك هو استبدال وحدة الحل الافتراضية (باستخدام IoC) بوحدة الحل الخاصة بك - ولكن لا يمكنني تقديم الكثير من النصائح حول هذا الأمر لأنني لم أقرأها بالكامل بعد وفهمت مستندات الروبوت على http://developer.android.com/guide/topics/fundamentals/fragments.html

من خلال خبرتي في إنشاء رمز التضخم الحالي، أعتقد أنك ستجد القراءة الأساسية للمصدر عند القيام بذلك - على سبيل المثال.يرى : http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/4.0.1_r1/android/view/LayoutInflater.java#LayoutInflater.createViewFromTag%28android.view.View% 2Cjava.lang.String%2Candroid.util.AttributeSet%29

لا أستطيع أن أقدم لك أي معلومات حول متى سيكون الدعم الرسمي لجزء mvvmcross متاحًا - فهو ليس شيئًا مجدولًا حاليًا.


يتم دعم طرق العرض المخصصة، ولكنها لن تكون موجودة عادةً في Mvx. مساحة الاسم المختصرة.

من الأرجح أن يعيشوا في مساحة اسم تطبيق واجهة المستخدم الخاصة بك، أو في بعض المكتبات المشتركة.

لرؤية طريقة عرض مخصصة أثناء العمل، راجع مثال PullToRefresh في البرنامج التعليمي - https://github.com/slodge/MvvmCross/blob/master/Sample%20-%20Tutorial/Tutorial/Tutorial.UI.Droid/Resources/Layout/Page_PullToRefreshView.axml

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top