it-swarm.com.de

So erhalten Sie eine Enumeration, die in attrs.xml im Code erstellt wird

Ich habe eine benutzerdefinierte Ansicht (find it here ) mit einem deklarationsfähigen Attribut vom Typ enum erstellt. In XML kann ich jetzt einen der Aufzählungseinträge für mein benutzerdefiniertes Attribut auswählen. Jetzt möchte ich eine Methode zum programmgesteuerten Festlegen dieses Werts erstellen, kann jedoch nicht auf die Enumeration zugreifen.

attr.xml

<declare-styleable name="IconView">
    <attr name="icon" format="enum">
        <enum name="enum_name_one" value="0"/>
        ....
        <enum name="enum_name_n" value="666"/>
   </attr>
</declare-styleable>     

layout.xml

<com.xyz.views.IconView
    Android:id="@+id/heart_icon"
    Android:layout_width="wrap_content"
    Android:layout_height="wrap_content"
    app:icon="enum_name_x"/>

Was ich brauche ist etwas wie: mCustomView.setIcon(R.id.enum_name_x); Aber ich kann die Aufzählung nicht finden oder ich habe sogar keine Ahnung, wie ich die Aufzählung oder die Namen der Aufzählung bekommen kann.

92
Informatic0re

Es scheint keine automatisierte Möglichkeit zu geben, eine Java - Aufzählung aus einer Attributaufzählung abzurufen. In Java können Sie den von Ihnen angegebenen numerischen Wert abrufen. Die Zeichenfolge wird in XML-Dateien verwendet (wie Sie zeigen) ).

Sie können dies in Ihrem Ansichtskonstruktor tun:

TypedArray a = context.getTheme().obtainStyledAttributes(
                attrs,
                R.styleable.IconView,
                0, 0);

    // Gets you the 'value' number - 0 or 666 in your example
    if (a.hasValue(R.styleable.IconView_icon)) {
        int value = a.getInt(R.styleable.IconView_icon, 0));
    }

    a.recycle();
}

Wenn Sie den Wert in eine Aufzählung aufnehmen möchten, müssen Sie den Wert entweder selbst in eine Java - Aufzählung abbilden, z.

private enum Format {
    enum_name_one(0), enum_name_n(666);
    int id;

    Format(int id) {
        this.id = id;
    }

    static Format fromId(int id) {
        for (Format f : values()) {
            if (f.id == id) return f;
        }
        throw new IllegalArgumentException();
    }
}

Dann können Sie im ersten Codeblock Folgendes verwenden:

Format format = Format.fromId(a.getInt(R.styleable.IconView_icon, 0))); 

(Obwohl das Auslösen einer Ausnahme an dieser Stelle möglicherweise keine gute Idee ist, ist es wahrscheinlich besser, einen vernünftigen Standardwert zu wählen.)

89
Andy Mell

Es ist ganz einfach, wir zeigen allen ein Beispiel, um zu zeigen, wie einfach es ist:

attr.xml:

<declare-styleable name="MyMotionLayout">
    <attr name="motionOrientation" format="enum">
        <enum name="RIGHT_TO_LEFT" value="0"/>
        <enum name="LEFT_TO_RIGHT" value="1"/>
        <enum name="TOP_TO_BOTTOM" value="2"/>
        <enum name="BOTTOM_TO_TOP" value="3"/>
    </attr>
</declare-styleable>

Benutzerdefiniertes Layout:

public enum Direction {RIGHT_TO_LEFT, LEFT_TO_RIGHT, TOP_TO_BOTTOM, BOTTOM_TO_TOP}
Direction direction;
...
    TypedArray ta = getContext().obtainStyledAttributes(attrs, R.styleable.MyMotionLayout);
    Direction direction = Direction.values()[ta.getInt(R.styleable.MyMotionLayout_motionOrientation,0)];

verwenden Sie jetzt die Richtung wie jede andere Aufzählungsvariable.

16
steve moretz

Nun, um der Vernunft willen. Stellen Sie sicher, dass Ihre Ordnungszahlen in Ihrem deklarierten Stil mit denen in Ihrer Enum-Deklaration übereinstimmen, und greifen Sie als Array darauf zu.

TypedArray a = context.getTheme().obtainStyledAttributes(
                   attrs,
                   R.styleable.IconView,
                   0, 0);

int ordinal = a.getInt(R.styleable.IconView_icon, 0);

if (ordinal >= 0 && ordinal < MyEnum.values().length) {
      enumValue = MyEnum.values()[ordinal];
}
11
Dave Thomas

Ich weiß, es ist schon eine Weile her, seit die Frage veröffentlicht wurde, aber ich hatte vor kurzem das gleiche Problem. Ich habe ein bisschen etwas zusammen gehackt, das das JavaPoet von Square und einige Dinge im build.gradle verwendet, die automatisch eine Java= enum-Klasse aus der attrs.xml bei der Projekterstellung erstellen.

Es gibt eine kleine Demo und eine Readme-Datei mit einer Erklärung unter https://github.com/afterecho/create_enum_from_xml

Ich hoffe es hilft.

3
Darren