কোডটিতে attrs.xML এ তৈরি হওয়া এনাম কীভাবে পাবেন


108

আমি এনাম টাইপের একটি ঘোষিত-স্টাইলযোগ্য বৈশিষ্ট্য সহ একটি কাস্টম ভিউ তৈরি করেছি (এটি এখানে সন্ধান করুন )। এক্সএমএল-তে আমি এখন আমার কাস্টম বৈশিষ্ট্যের জন্য এনম এন্ট্রিগুলির একটি চয়ন করতে পারি। এখন আমি প্রোগ্রামটিমেটিকভাবে এই মানটি সেট করার জন্য একটি পদ্ধতি তৈরি করতে চাই, তবে আমি এনামটি অ্যাক্সেস করতে পারি না।

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"/>

আমার যা দরকার তা হ'ল: mCustomView.setIcon(R.id.enum_name_x); তবে আমি এনাম খুঁজে পাচ্ছি না বা এমনকি এনাম বা এনামের নাম কীভাবে পাব তাও আমার কোনও ধারণা নেই।

উত্তর:


100

কোনও এনট্রিবিউট এনুম থেকে জাভা এনাম পাওয়ার কোনও স্বয়ংক্রিয় উপায় বলে মনে হচ্ছে না - জাভাতে আপনি যে সংখ্যার মান নির্দিষ্ট করেছেন তা পেতে পারেন - এক্সএমএল ফাইলগুলিতে স্ট্রিংটি ব্যবহারের জন্য (আপনি যেমন দেখিয়েছেন)।

আপনি আপনার ভিউ কনস্ট্রাক্টরে এটি করতে পারেন:

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

আপনি যদি এনামে মানটি চান তবে আপনাকে নিজের মানটি একটি জাভা এনামে তৈরি করতে হবে, যেমন:

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

তারপরে প্রথম কোড ব্লকে আপনি ব্যবহার করতে পারেন:

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

(যদিও এই মুহুর্তে একটি ব্যতিক্রম ছুঁড়ে ফেলা একটি দুর্দান্ত ধারণা নাও হতে পারে, বুদ্ধিমান ডিফল্ট মান চয়ন করা আরও ভাল)


38

এটি সহজ যে আসুন সবাইকে এটির উদাহরণ দেখানোর জন্য এটি কত সহজ show

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>

কাস্টম বিন্যাস:

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)];

এখন অন্যান্য গণনা ভেরিয়েবলের মতো দিক ব্যবহার করুন।


উপসংহারে, কেবল এনাম অ্যাটর পেতে এটি ব্যবহার করুন: টাইপডআরে.জেটইন্ট (আর। স্টাইলিয়েবল.নেম_ইউর_ডিফাইন, ডিফল্টভ্যালু)
ক্যালভিনে

@ ক্যালভিনেচে, এটি একটি ফেরত দেয় int। স্টিভ মোর্টজ এর আছে এটি দেখতে না পেয়ে আমি বোবা বোধ করি, তবে এটি সকাল সাড়ে ৪ টা । বিছানার জন্য সময় ...
n00dles

হ্যাঁ ঠিক তত সহজ The উত্তরটি আরও ভাল উদাহরণ দিয়ে দেওয়ার জন্য এটি একটি উদাহরণ।
স্টিভ মোরেটজ

2
তবে এটি দুটি চিহ্নের সমান্তরাল সংজ্ঞা তৈরি করে। এটি কেবলমাত্র এতক্ষণ কাজ করে যতক্ষণ সংজ্ঞাগুলি অভিন্ন - তবে এটি ভঙ্গুর। ওপি এক্সএমএল থেকে উত্পন্ন একটি এনামে কোড অ্যাক্সেসের প্রত্যাশা করেছিল। এটা সম্ভব হওয়া উচিত বলে মনে হচ্ছে।
স্টিভ হোয়াইট

@ স্টিভওয়াইট যেহেতু আপনার এক্সএমএল অ্যাক্সেস নেই তাই এটিকে স্বয়ংক্রিয়ভাবে চালানোর কোনও উপায় নেই এবং এটি একটি সংজ্ঞার উপর নির্ভর করতে দিন it এটি অর্জনের পক্ষে এটি সবচেয়ে পরিষ্কার (সম্ভাব্য) উপায় I যদি আপনি এক্সএমএলকে বিশ্লেষণ করতে এবং এমনভাবে প্রবেশ করতে পারেন তবে দুর্দান্ত হতে পারে তবে আপনি পারবেন না। (কোডটি না থাকলে আপনি XML পড়তে এবং আপনার জাভাতে মানগুলি বের করতে একটি প্লাগইন লিখতে পারেন যাতে এটি সিঙ্ক্রোনাইজ হবে তাই হ্যাঁ যেভাবে এটি ভঙ্গুর হবে না কারণ এটি অটোমেটেড))
স্টিভ মোরেটজ

13

স্যানিটির পক্ষে! নিশ্চিত হয়ে নিন যে আপনার অর্ডিনালগুলি আপনার এনাম ঘোষণার মতো আপনার ঘোষিত স্টাইলযোগ্যতে একই এবং এ্যারে হিসাবে অ্যাক্সেস করুন।

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];
}

3
আমি মনে করি এখানে এনাম অর্ডিনালের উপর নির্ভর করা অবিশ্বাস্য কোড তৈরির লক্ষ্যযুক্ত। একটি জিনিস আপডেট হবে এবং অন্যটি নয় এবং তারপরে আপনার সমস্যা হবে।
tir38

1
সুতরাং এটি করার একটি ভাল উপায় কি?
জোনাথন

6

আমাকে কোটলিনে লেখা একটি সমাধান যুক্ত করুন। ইনলাইন এক্সটেনশন ফাংশন যুক্ত করুন:

inline fun <reified T : Enum<T>> TypedArray.getEnum(index: Int, default: T) =
    getInt(index, -1).let { if (it >= 0) enumValues<T>()[it] else default 
}

এখন এনাম পাওয়া সহজ:

val a: TypedArray = obtainStyledAttributes(...)
val yourEnum: YourEnum = a.getEnum(R.styleable.YourView_someAttr, YourEnum.DEFAULT)
a.recycle()

4

আমি জানি প্রশ্ন পোস্ট হওয়ার পরে অনেক সময় হয়ে গেছে, তবে সম্প্রতি আমার একই সমস্যা ছিল। আমি স্কয়ারের জাভাপাটি এবং বিল্ডপ্রেডেলের কিছু স্টাফ ব্যবহার করে একসাথে কিছু হ্যাক করেছি যা প্রকল্প বিল্ডে attrs.xml থেকে স্বয়ংক্রিয়ভাবে একটি জাভা এনাম ক্লাস তৈরি করে।

এখানে একটি ব্যাখ্যা সহ একটি সামান্য ডেমো এবং একটি রেডমে রয়েছে Https://github.com/afterecho/create_enum_from_xML

আশা করি এটা সাহায্য করবে.

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.