Android Resource Selection Layout- und Werte-Inkonsistenzen

Das aufgetretene Problem weist darauf hin, dass der Ressourcen-Bucket für eine bestimmte Aktivität ausgewählt wurdelayout XML ist nicht konsistent mit den Ressourcen, die aus der Liste ausgewählt werdenvalues Ordner, obwohl in jedem Ordnersatz genau dieselben Ressourcenqualifizierer verwendet werden.

Beispiel

Nachdem ich einen Teil des Protokollcodes in die abstrakte übergeordnete Aktivität meiner Anwendung eingefügt habe, kann ich feststellen, dass beim Starten meiner Anwendung über einen Nexus 7-Emulator (Android 4.1) die kleinste Breite in der Tat 600 dpi beträgtlayout-sw600dp-* Ordner wird verwendet, um die Benutzeroberfläche für die Aktivität abzurufen, aber der Ordner, der für die Aktivität verwendet wirdvalues istvalues-large-*. Ich hatte das erwartetvalues-sw600dp-* Auf diese Weise erhalte ich wichtige Informationen darüber, unter welchem ​​Ressourceneimer die Aktivität ausgeführt wird.

Code für die Protokollierung in der übergeordneten Aktivität meiner App für alleandroid.app.Activitys

  protected void onCreate(final Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    final Configuration config = getResources().getConfiguration();
    Log.i(this.getClass().getSimpleName(), String.format("Smallest width is [%s]", config.smallestScreenWidthDp));
    configurationContext = SupportedDeviceConfiguration.fromResourceQualifer(getString(string.resourceQualifier));
    Log.i(this.getClass().getSimpleName(), String.format("Running under the [%s] configuration context.", configurationContext.getResourceQualifier()));
...

Protokollierung der Ausgabe von, wenn ich diesen Code auf einem Nexus 7-Gerät ausführe;

[Logging fluff] Smallest width is [600]
[Logging fluff] Running under the [layout-large-land] configuration context.

Ich weiß, was du denkst - wo hast du das gemacht?layout-large-land Ableitung kommen aus? Weiter lesen...

Hintergrund

Ich probiere einen Ansatz ausHier Dies würde es mir ermöglichen, den zur Laufzeit verwendeten Ressourcen-Bucket zu überprüfen. Im Wesentlichen hat der Ansatz, den ich implementiert habe, die folgende Struktur von Ressourcenqualifizierern.

- res
  + layout                   // Default portrait layout.
  + layout-land              // Default landscape layout
  + layout-large-land        // pre 3.2 phablet landscape layout (Galaxy Note at v2.3.3)
  + layout-xlarge-land       // pre 3.2 tablet landscape layout
  + layout-xlarge-port       // pre 3.2 tablet portrait layout
  + layout-sw520dp-port      // post 3.1 phablet portrait layout (Galaxy Note at v4.0.3)
  + layout-sw520dp-land      // post 3.1 phablet landscape layout
  + layout-sw600dp-port      // post 3.1 mini-tablet portrait layout (Nexus 7)
  + layout-sw600dp-land      // post 3.1 mini-tablet-landscape layout 
  + layout-sw700dp-port      // post 3.1 tablet portrait layout
  + layout-sw700dp-land      // post 3.1 tablet landscape layout
  - values                   // Contains the root strings.xml
     strings.xml
  - values-land
     default-config.xml            
  - values-large-land
     default-config.xml        
  - values-xlarge-land
     default-config.xml     
  - values-xlarge-port
     default-config.xml     
  - values-sw520dp-port
     default-config.xml     
  - values-sw520dp-land
     default-config.xml     
  - values-sw600dp-port
     default-config.xml     
  - values-sw600dp-land
     default-config.xml     
  - values-sw700dp-port
     default-config.xml     
  - values-sw700dp-land
     default-config.xml

Also im Wesentlichen dievalues Qualifikanten spiegeln die derlayout Qualifikanten. Unter jedem vonvalues-* Ordner Ich habe eine einzelne XML-Datei namens definiertdevice-config.xml mit inhalt;

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="resourceQualifier">layout-{qualifier of values folder}</string>
</resources>

So zum Beispiel dievalues-sw600dp-land Ordnerdevice-config.xml enthält eine einzelne Zeichenfolge mit Wertlayout-sw600dp-land. Das Ziel hier ist, dass mein Code mit den auf dem Bildschirm angezeigten Ressourcenlayouts synchron bleibt. Dies wird benötigt, damit mein Code nicht "Finding by Id" eines Elements auslöst, das auf dem angezeigten Layout aufgrund der betroffenen Immobilie nicht vorhanden ist.

(Optional) Weitere Gründe, warum ich das tue

Die tieferen Gründe für den Wunsch, den zur Laufzeit verwendeten Bucket zu kennen, ergaben sich aus der Erkenntnis, dass mein Code mit einem einzigen Fragment für alle Konfigurationen mit verschiedenen switch-basierten Logikfunktionen, die nicht transparent waren und häufig von Funktionen dupliziert wurden, nur schwer zu verwalten war andere Layouts ... es war, als ob ich irgendeine Art von brauchteFragmentvererbung ... was, wenn Sie dem Link folgen, genau das ist, was ich getan habe. Der Nachteil dabei ist, dass ich wissen muss, mit welchem ​​Bildschirm ich arbeite, bevor ich das Framework anweise, das X-, Y- oder Z-Fragment zu instanziieren. Dabei ist sichergestellt, dass das zu erstellende Fragment niemals nicht mit dem Layout synchron ist soll aufblasen. Diese Vererbung funktioniert und ermöglicht einen weitaus handlicheren Fragmentstapel (Sonar ist auch glücklicher, was gut ist).

Zusammenfassung

Ich wurde jedoch durch diese offensichtliche Diskrepanz zwischen dem vom Framework ausgewählten Layoutordner und dem vom Framework ausgewählten Wertordner vereitelt. Jeder hat die gleichen Qualifikationsmerkmale. Warum nutzt eine Aktivität die nicht?layout-sw600dp-land UI XML verwenden dievalues-sw600dp-land Ressource? Ich hoffe, dass ich etwas falsch gemacht habe, weil es die sauberste der möglichen Lösungen war, die in der SO-Diskussion veröffentlicht wurden, auf die ich oben verwiesen habe.

Antworten auf die Frage(2)

Ihre Antwort auf die Frage