Pregunta

Situación Actual, que he añadido a la MvxViewTypeResolver la clase, el "Fragmento"-Caso, por lo que tiene un aspecto como este:

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

Ahora es la presentación de la correcta longLowerCaseTagName (android.app.fragmento), pero en la consulta no es capaz de resolver el tipo.

Mi sugerencia es, que el fragmento de control no se carga cuando el tipo debe ser resuelto.Tal vez hay otra manera de conseguir el tipo resuelto?

También si puedo agregar un tipo personalizado (dando la etiqueta Mvx.MyCustomType en el axml) que no se resuelve.Tengo que agregar algo en el MvxBindingAttributes.xml en este caso?

Gracias por la ayuda!

¿Fue útil?

Solución

Primero una explicación del código:

El XML personalizado inflater fábrica utilizada por el MvvmCross Cuaderno intenta cargar las Vistas de una manera muy similar a la norma 2.x XML Android inflater.

El código predeterminado para el tipo de vista que la resolución es de hecho en: https://github.com/slodge/MvvmCross/blob/master/Cirrious/Cirrious.MvvmCross.Binding/Android/Binders/MvxViewTypeResolver.cs

Si el xml contiene un nombre como <MyCompany.MyProject.MyViews.MyFirstView /> a continuación, el tipo de vista de resolución:

  • comprueba primero abreviaturas y expande estas en plena espacios de nombres por defecto, el único conocido abreviatura es Mvx. que se expande a: Cirrious.MvvmCross.Binding.Android.Views..Si desea agregar más abbrevations a continuación, reemplazar ViewNamespaceAbbreviations en https://github.com/slodge/MvvmCross/blob/master/Cirrious/Cirrious.MvvmCross.Binding/Android/MvxBaseAndroidBindingSetup.cs

  • a continuación, comprueba si el nombre sin abreviar, es un no-nombres de espacios de nombre.Si es así, entonces se asume que la clase es el Android de espacio de nombres y antepone con android.view. o android.widget.

  • a continuación, se convierte totalmente nombres de espacios de nombres en minúsculas como mayúsculas y minúsculas clave de búsqueda

  • los usos que minúsculas clave para la búsqueda de todo Tipo que se derivan de la Vista en todos los ensamblados cargados.

  • almacena el resultado (ya sea nulo o no) con el fin de acelerar posterior inflaciones.

Todos los de este comportamiento fue diseñado para que coincida con el de Android por defecto xml de la vista de código de la inflación en 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


Con esa explicación de la forma - he aquí una respuesta a sus preguntas:


MvvmCross aún no contienen ningún Fragmento de apoyo.El oficial de MonoDroid fragmento de mantenerse a sí mismo sólo fue liberado la semana pasada, y todavía no he tenido a nadie solicitud de fragmentos - Android "fragmentación" parece que han mantenido la mayoría de la gente de nuevo en la Actividad y en el cuadro de Diálogo de código.

Brevemente ;cocinar en la documentación, fragment no es un Android de Vista parece Fragmento hereda directamente de Java.Lang.Objeto - ver http://developer.android.com/reference/android/app/Fragment.html

Debido a esto, no hay manera de que el MvvmCross ViewTypeResolver actualmente trabajo con fragmentos.

Yo sugiero que si usted necesita el mvvmcross y fragmentos de hoy, entonces su mejor apuesta es para sustituir la resolución predeterminada (utilizando Coi) con su propia resolución - pero que no puede ofrecer muchos consejos en este como todavía no he leído y entendido el droid docs en http://developer.android.com/guide/topics/fundamentals/fragments.html

Desde mi experiencia en la creación de la inflación actual código, entonces creo que usted va a encontrar la fuente esencial de la lectura al hacerlo - por ejemplo,ver : 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

No te puedo dar ninguna información sobre cuándo oficial mvvmcross fragmento de apoyo estará disponible - no es algo que está actualmente programada.


Vistas personalizadas son compatibles, pero no viven normalmente en la Mvx. abreviado de espacio de nombres.

Ellos son mucho más propensos a vivir en la interfaz de usuario de la aplicación de espacio de nombres, o en alguna biblioteca compartida.

Para ver una vista personalizada en acción, ver el PullToRefresh ejemplo en el tutorial - https://github.com/slodge/MvvmCross/blob/master/Sample%20-%20Tutorial/Tutorial/Tutorial.UI.Droid/Resources/Layout/Page_PullToRefreshView.axml

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top