MvvmCross ViewTypeResolver가 태그(조각 또는 사용자 정의 유형)를 확인하지 않습니다.

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

  •  12-12-2019
  •  | 
  •  

문제

실제 상황은 내가 추가한 것입니다. MvxViewTypeResolver "Fragment"-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 이 경우에는?

도와 주셔서 감사합니다!

도움이 되었습니까?

해결책

먼저 코드에 대한 설명:

MvvmCross Binder에서 사용하는 사용자 정의 XML 팽창기 팩토리는 표준 2.x Android XML 팽창기와 매우 유사한 방식으로 뷰를 로드하려고 시도합니다.

뷰 유형 확인을 위한 기본 코드는 실제로 다음과 같습니다. 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.

  • 그런 다음 대소문자를 구분하지 않는 조회 키로서 완전히 네임스페이스화된 이름을 모두 소문자로 변환합니다.

  • 해당 소문자 키를 사용하여 로드된 모든 어셈블리의 View에서 파생된 모든 유형을 검색합니다.

  • 후속 인플레이션 속도를 높이기 위해 결과(null인지 여부)를 캐시합니다.

이 모든 동작은 기본 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에는 현재 Fragment 지원이 포함되어 있지 않습니다.공식 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. 약칭 네임스페이스.

UI 애플리케이션 네임스페이스나 일부 공유 라이브러리에 있을 가능성이 훨씬 더 높습니다.

사용자 정의 뷰가 실제로 작동하는 모습을 보려면 튜토리얼의 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