Pergunta

Situação real é que eu adicionei para o MvxViewTypeResolver classe a "Fragmento"-Caso, então, ela não esta aparência:

 #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(".");
        }
    }
}

Agora ele está enviando o correto longLowerCaseTagName (android.app.fragmento), mas na consulta não é capaz de resolver o tipo.

Minha sugestão é que o fragmento de controle não é carregado quando o tipo deve ser resolvido.Talvez haja uma outra forma de obter o tipo resolvido?

Também se eu adicionar um tipo personalizado (dando a tag Mvx.MyCustomType no axml) não resolvido.Eu tenho que adicionar algo na MvxBindingAttributes.xml neste caso?

Obrigado pela ajuda!

Foi útil?

Solução

Primeiro uma explicação do código:

O XML personalizada inflater de fábrica, usado pelo MvvmCross Fichário tenta carregar Vistas de uma forma muito semelhante ao padrão 2.x XML Android inflater.

O código padrão para o tipo de modo de exibição de resolução é, de fato, em: https://github.com/slodge/MvvmCross/blob/master/Cirrious/Cirrious.MvvmCross.Binding/Android/Binders/MvxViewTypeResolver.cs

Se o xml contém um nome como <MyCompany.MyProject.MyViews.MyFirstView /> em seguida, o tipo de modo de exibição de resolução:

  • primeiro, verifica abreviaturas e expande-se estes em espaços de nomes - por padrão, o único conhecido abreviação é Mvx. o que é expandido para: Cirrious.MvvmCross.Binding.Android.Views..Se você deseja adicionar mais abreviaturas, em seguida, substituir ViewNamespaceAbbreviations no https://github.com/slodge/MvvmCross/blob/master/Cirrious/Cirrious.MvvmCross.Binding/Android/MvxBaseAndroidBindingSetup.cs

  • em seguida, verifica se o nome abreviado é um não-namespace nome.Se for, então ele assume que a classe é o Android espaço de nomes e acrescenta-lo com android.view. ou android.widget.

  • em seguida, converte totalmente namespace nome para todas as minúsculas como um case-insensitive chave de pesquisa

  • utiliza minúsculas chave para pesquisa de todos os Tipos, provenientes de Vista em todas as assemblies carregados.

  • armazena em cache o resultado (se a sua nulo ou não), a fim de acelerar subsequentes inflations.

Todo esse comportamento foi projetado para combinar com o padrão xml Android visualizar a inflação código 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


Com essa explicação fora do caminho - aqui está a resposta para as suas perguntas:


MvvmCross ainda não contêm qualquer Fragmento de suporte.O oficial MonoDroid fragmento de suporte propriamente dito só foi lançado na semana passada, e eu ainda não tinha ninguém pedido de fragmentos - Android "fragmentação" parece ter-se mantido a maioria das pessoas volta-se na Actividade e de Diálogo com base no código.

Brevemente ;ooking a documentação, fragment não é um Android de Vista, parece Fragmento herda diretamente a partir do Java.Lang.Objeto - ver http://developer.android.com/reference/android/app/Fragment.html

Devido a isso, não há nenhuma maneira que o MvvmCross ViewTypeResolver atualmente trabalho com fragmentos.

Eu gostaria de sugerir que se você precisa de ambos mvvmcross e fragmentos de hoje, então sua melhor aposta é a de substituir a resolução padrão (utilizando o Coi) com a sua própria resolução - mas eu não posso oferecer muito aconselhamento sobre isso, eu ainda não totalmente lido e entendido o droid docs http://developer.android.com/guide/topics/fundamentals/fragments.html

A partir de minha experiência na criação de inflação actual código, então eu acho que você vai encontrar a fonte de uma leitura essencial quando você fizer isso - e.veja : 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

Eu não posso lhe dar nenhuma informação sobre quando o oficial mvvmcross fragmento de suporte estará disponível - não é algo que está programado.


Modos de exibição personalizados são suportados, mas não vivem normalmente nos Mvx. abreviado espaço de nomes.

Eles são muito mais propensos a viver em sua INTERFACE do usuário do aplicativo de espaço de nomes, ou em alguma biblioteca compartilhada.

Para ver um modo de exibição personalizado em ação, veja o PullToRefresh exemplo no tutorial - https://github.com/slodge/MvvmCross/blob/master/Sample%20-%20Tutorial/Tutorial/Tutorial.UI.Droid/Resources/Layout/Page_PullToRefreshView.axml

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top