Frage

Die tatsächliche Situation ist, dass ich dem hinzugefügt habe MvxViewTypeResolver Klasse den „Fragment“-Fall, also sieht es so aus:

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

Jetzt wird das Richtige übermittelt longLowerCaseTagName (android.app.fragment), aber in der Abfrage kann der Typ nicht aufgelöst werden.

Mein Vorschlag ist, dass das Fragment-Steuerelement nicht geladen wird, wenn der Typ aufgelöst werden soll.Gibt es vielleicht eine andere Möglichkeit, den Typ aufzulösen?

Auch wenn ich einen benutzerdefinierten Typ hinzufüge (mit dem Tag Mvx.MyCustomType im axml) wird es nicht aufgelöst.Muss ich etwas hinzufügen? MvxBindingAttributes.xml in diesem Fall?

Danke für die Hilfe!

War es hilfreich?

Lösung

Zunächst eine Erklärung des Codes:

Die vom MvvmCross Binder verwendete benutzerdefinierte XML-Inflater-Factory versucht, Ansichten auf sehr ähnliche Weise wie der Standard-2.x-Android-XML-Inflater zu laden.

Der Standardcode für die Auflösung des Ansichtstyps lautet tatsächlich: https://github.com/slodge/MvvmCross/blob/master/Cirrious/Cirrious.MvvmCross.Binding/Android/Binders/MvxViewTypeResolver.cs

Wenn Ihre XML einen Namen enthält, z <MyCompany.MyProject.MyViews.MyFirstView /> dann der Ansichtstyp-Resolver:

  • sucht zunächst nach Abkürzungen und erweitert diese zu vollständigen Namensräumen – standardmäßig ist die einzige bekannte Abkürzung Mvx. was erweitert wird zu: Cirrious.MvvmCross.Binding.Android.Views..Wenn Sie weitere Abkürzungen hinzufügen möchten, überschreiben Sie diese ViewNamespaceAbbreviations In https://github.com/slodge/MvvmCross/blob/master/Cirrious/Cirrious.MvvmCross.Binding/Android/MvxBaseAndroidBindingSetup.cs

  • Anschließend wird überprüft, ob der ungekürzte Name ein Name ohne Namensraum ist.Wenn dies der Fall ist, geht es davon aus, dass es sich bei der Klasse um den Android-Namespace handelt, und stellt ihm voran android.view. oder android.widget.

  • Konvertiert dann den Namen mit vollständigem Namensraum als Suchschlüssel, bei dem die Groß- und Kleinschreibung nicht berücksichtigt wird, in Kleinbuchstaben

  • verwendet diesen Kleinbuchstabenschlüssel, um alle Typen zu durchsuchen, die von View in allen geladenen Assemblys abgeleitet sind.

  • speichert das Ergebnis (unabhängig davon, ob es Null ist oder nicht) zwischen, um nachfolgende Inflationen zu beschleunigen.

All dieses Verhalten wurde entwickelt, um dem Standard-Inflationscode für die Android-XML-Ansicht zu entsprechen 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


Nachdem wir diese Erklärung hinter uns haben, finden Sie hier eine Antwort auf Ihre Fragen:


MvvmCross enthält derzeit noch keine Fragmentunterstützung.Die offizielle MonoDroid-Fragmentunterstützung selbst wurde erst letzte Woche veröffentlicht, und ich habe noch niemanden gehabt, der Fragmente angefordert hat – die „Fragmentierung“ von Android scheint die meisten Leute davon abgehalten zu haben, auf Aktivitäts- und Dialog-basiertem Code zu arbeiten.

Kurzer Blick auf die Dokumentation, fragment ist keine Android-Ansicht – es sieht so aus, als ob Fragment direkt von Java.Lang.Object erbt – siehe http://developer.android.com/reference/android/app/Fragment.html

Aus diesem Grund besteht derzeit keine Möglichkeit, dass der MvvmCross ViewTypeResolver mit Fragmenten funktioniert.

Wenn Sie heute sowohl mvvmcross als auch Fragmente benötigen, würde ich vorschlagen, dass Sie am besten den Standard-Resolver (unter Verwendung von IoC) durch Ihren eigenen Resolver ersetzen. Ich kann dazu jedoch nicht viele Ratschläge geben, da ich es noch nicht vollständig gelesen habe und habe die Droidendokumente verstanden http://developer.android.com/guide/topics/fundamentals/fragments.html

Aufgrund meiner Erfahrung bei der Erstellung des aktuellen Inflationskodex denke ich, dass Sie dabei die Quelle als wesentliche Lektüre finden werden – z.sehen : 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

Ich kann Ihnen keine Informationen darüber geben, wann die offizielle Unterstützung für mvvmcross-Fragmente verfügbar sein wird – dies ist derzeit nicht geplant.


Benutzerdefinierte Ansichten werden unterstützt, sind jedoch normalerweise nicht in der enthalten Mvx. abgekürzter Namensraum.

Es ist viel wahrscheinlicher, dass sie sich im Namespace Ihrer UI-Anwendung oder in einer gemeinsam genutzten Bibliothek befinden.

Um eine benutzerdefinierte Ansicht in Aktion zu sehen, sehen Sie sich das PullToRefresh-Beispiel im Tutorial an – https://github.com/slodge/MvvmCross/blob/master/Sample%20-%20Tutorial/Tutorial/Tutorial.UI.Droid/Resources/Layout/Page_PullToRefreshView.axml

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top