এক্সএমএল ব্যবহার করে একটি কাস্টম অ্যান্ড্রয়েড ইউআই উপাদান ঘোষণা করে


472

এক্সএমএল ব্যবহার করে আমি কীভাবে একটি Android ইউআই উপাদান ঘোষণা করতে পারি?


15
যদি কেউ সমর্থিত, অন্তর্নির্মিত বিশিষ্ট বিন্যাসগুলির তালিকার সন্ধান করে তবে এটি এখানে পাওয়া যাবে
মার্সিন ওরোলোস্কি

উত্তর:


840

অ্যান্ড্রয়েড বিকাশকারী গাইডের বিল্ডিং কাস্টম উপাদানগুলি নামে একটি বিভাগ রয়েছে । দুর্ভাগ্যবশত, এক্সএমএল বৈশিষ্ট্যগুলির আলোচনাটি কেবলমাত্র লেআউট ফাইলের অভ্যন্তরে নিয়ন্ত্রণ ঘোষণা করে এবং প্রকৃতপক্ষে শ্রেণি সূচনাতে মানগুলি পরিচালনা করে না। নিম্নরূপ পদক্ষেপ:

1. বৈশিষ্ট্য ঘোষণা করুন values\attrs.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="MyCustomView">
        <attr name="android:text"/>
        <attr name="android:textColor"/>            
        <attr name="extraInformation" format="string" />
    </declare-styleable>
</resources>

declare-styleableট্যাগটিতে অযোগ্য নাম ব্যবহারের বিষয়টি লক্ষ্য করুন । অ-মানক অ্যান্ড্রয়েড বৈশিষ্ট্য পছন্দ করেextraInformation তাদের প্রকারটি ঘোষণা করা দরকার। সুপারক্লাসে ঘোষিত ট্যাগগুলি আবার ঘোষিত না করে সাবক্লাসে উপলব্ধ।

2. নির্মাণকারী তৈরি করুন

যেহেতু দুটি কনস্ট্রাক্টর রয়েছে যা একটি AttributeSetপ্রারম্ভিককরণের জন্য ব্যবহার করে , তাই কনস্ট্রাক্টরদের কল করার জন্য একটি পৃথক সূচনা পদ্ধতি তৈরি করা সুবিধাজনক।

private void init(AttributeSet attrs) { 
    TypedArray a=getContext().obtainStyledAttributes(
         attrs,
         R.styleable.MyCustomView);

    //Use a
    Log.i("test",a.getString(
         R.styleable.MyCustomView_android_text));
    Log.i("test",""+a.getColor(
         R.styleable.MyCustomView_android_textColor, Color.BLACK));
    Log.i("test",a.getString(
         R.styleable.MyCustomView_extraInformation));

    //Don't forget this
    a.recycle();
}

R.styleable.MyCustomViewহ'ল একটি অটো-জেনেটেড int[]রিসোর্স যেখানে প্রতিটি উপাদান একটি গুনের আইডি। এক্সিএমএলে প্রতিটি সম্পত্তির জন্য বৈশিষ্ট্যের নামটি উপাদানটির নামের সাথে যুক্ত করে বৈশিষ্ট্য তৈরি করা হয়। উদাহরণস্বরূপ, R.styleable.MyCustomView_android_textএর জন্য android_textবৈশিষ্ট্য রয়েছে MyCustomView। বৈশিষ্ট্যগুলি তখন TypedArrayবিভিন্ন getফাংশন ব্যবহার করে পুনরুদ্ধার করা যায় । এক্সএমএলে সংজ্ঞায়িত করে যদি অ্যাট্রিবিউটটি সংজ্ঞায়িত না করা হয়, তবে nullফিরে আসে। অবশ্যই, ব্যতীত, যদি ফেরতের ধরণটি আদিম হয়, সেই ক্ষেত্রে দ্বিতীয় যুক্তিটি ফিরে আসে।

আপনি যদি সমস্ত বৈশিষ্ট্য পুনরুদ্ধার করতে না চান তবে এই অ্যারেটি নিজেই তৈরি করা সম্ভব standard মানক অ্যান্ড্রয়েড বৈশিষ্ট্যের জন্য আইডি অন্তর্ভুক্ত রয়েছে android.R.attr, যখন এই প্রকল্পের বৈশিষ্ট্যগুলি অন্তর্ভুক্ত রয়েছে R.attr

int attrsWanted[]=new int[]{android.R.attr.text, R.attr.textColor};

দয়া করে মনে রাখবেন আপনি উচিত না কিছু ব্যবহার android.R.styleable, অনুযায়ী এই থ্রেড এটি ভবিষ্যতে পরিবর্তন হতে পারে। ডকুমেন্টেশনে এখনও এই সমস্ত ধ্রুবককে এক জায়গায় দেখার জন্য ব্যবহার করা দরকারী।

৩. লেআউট ফাইলগুলিতে এটি ব্যবহার করুন layout\main.xml

xmlns:app="http://schemas.android.com/apk/res-auto"শীর্ষ স্তরের এক্সএমএল উপাদানগুলিতে নেমস্পেসের ঘোষণাটি অন্তর্ভুক্ত করুন । নেমস্পেসগুলি দ্বন্দ্বগুলি এড়ানোর জন্য একটি পদ্ধতি সরবরাহ করে যা কখনও কখনও ঘটে যখন বিভিন্ন স্কিমা একই উপাদানগুলির নাম ব্যবহার করে ( আরও তথ্যের জন্য এই নিবন্ধটি দেখুন)। ইউআরএল হ'ল স্বতন্ত্রভাবে স্কিমগুলি সনাক্ত করার একটি পদ্ধতি - সেই URL এ আসলে কিছুই হোস্ট করার দরকার নেই । যদি এটি কিছু করছে বলে মনে হয় না, কারণ আপনার কোনও দ্বন্দ্বের সমাধানের প্রয়োজন না হলে আপনাকে প্রকৃতপক্ষে নেমস্পেসের উপসর্গ যুক্ত করার দরকার নেই।

<com.mycompany.projectname.MyCustomView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="@android:color/transparent"
    android:text="Test text"
    android:textColor="#FFFFFF"
    app:extraInformation="My extra information"
/> 

সম্পূর্ণরূপে যোগ্যতাসম্পন্ন নাম ব্যবহার করে কাস্টম ভিউটি উল্লেখ করুন।

অ্যান্ড্রয়েড লেবেলভিউ নমুনা

আপনি যদি একটি সম্পূর্ণ উদাহরণ চান তবে অ্যান্ড্রয়েড লেবেল দেখার নমুনাটি দেখুন।

LabelView.java

 TypedArray a=context.obtainStyledAttributes(attrs, R.styleable.LabelView);
 CharSequences=a.getString(R.styleable.LabelView_text);

attrs.xml

<declare-styleable name="LabelView">
    <attr name="text"format="string"/>
    <attr name="textColor"format="color"/>
    <attr name="textSize"format="dimension"/>
</declare-styleable>

custom_view_1.xml

<com.example.android.apis.view.LabelView
    android:background="@drawable/blue"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    app:text="Blue" app:textSize="20dp"/>

এই মধ্যে অন্তর্ভুক্ত করা হয় LinearLayoutএকটি নামস্থান অ্যাট্রিবিউট সাথেxmlns:app="http://schemas.android.com/apk/res-auto"

লিংক


14
আমি যুক্ত করতে চাই যে যদি আপনার মূল উপাদানটির জন্য আপনার কাস্টম নেমস্পেসের প্রয়োজন হয় তবে আপনাকে স্ট্যান্ডার্ড অ্যান্ড্রয়েড নেমস্পেস এবং আপনার নিজস্ব কাস্টম দুটি যুক্ত করতে হবে অথবা অন্যথায় আপনি বিল্ড ত্রুটিগুলির সম্মুখীন হতে পারেন।
2:14

11
এই উত্তরটি হ'ল কাস্টম এক্সএমএল প্যারামগুলিতে ইন্টারনেটের স্পষ্ট সংস্থান যা আমি খুঁজে পেতে সক্ষম হয়েছিলাম। ধন্যবাদ, কেসব্যাশ
আর্টেম রাশাকোভস্কিই

2
কোনও কারণে, ভিজ্যুয়াল সম্পাদক অ্যান্ড্রয়েডের জন্য লিখিত পাঠ্য মানটি ব্যবহার করতে অস্বীকার করেছে: পাঠ্য, তবুও ডিভাইসটি এটি ঠিকঠাক ব্যবহার করে। কিভাবে ?
অ্যান্ড্রয়েড বিকাশকারী

2
@ অ্যান্ড্রয়েড ডেভেলপার মনে হয় যে গ্রহচিত্র সম্পাদক সমস্ত অ্যান্ড্রয়েডের জন্য মানগুলি ব্যবহার করতে অস্বীকার করেছেন: বৈশিষ্ট্যগুলি। আমি এটি কোনও বৈশিষ্ট্য বা বাগ কিনা তা জানতে চাই
দিজ

4
এক্সএমএলএনএস এর উদ্দেশ্য কী: অ্যাপ নেমস্পেস এবং পুনরায় অটো?
ইগোরগানাপলস্কি

91

দুর্দান্ত রেফারেন্স। ধন্যবাদ! এটি সংযোজন:

যদি আপনার কাছে এমন কোনও লাইব্রেরি প্রকল্প অন্তর্ভুক্ত থাকে যা কাস্টম দর্শনের জন্য কাস্টম বৈশিষ্ট্যগুলি ঘোষণা করে থাকে তবে আপনাকে লাইব্রেরির নয়, আপনার প্রকল্পের নাম স্থানটি ঘোষণা করতে হবে। উদাহরণ:

প্রদত্ত যে লাইব্রেরিতে "com.example.library.customview" প্যাকেজ রয়েছে এবং কার্যকারী প্রকল্পে "com.example.customview" প্যাকেজ রয়েছে, তারপরে:

কাজ করবে না (ত্রুটিটি দেখায় "ত্রুটি: প্যাকেজ 'com.example.library.customview'" "newAttr 'এ্যাট্রিবিউটটির জন্য কোনও সংস্থান সনাক্তকারী পাওয়া যায় নি):

<com.library.CustomView
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res/com.example.library.customview"
        android:id="@+id/myView"
        app:newAttr="value" />

কাজ করবে:

<com.library.CustomView
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res/com.example.customview"
        android:id="@+id/myView"
        app:newAttr="value" />

47
এটি ADT 17 পূর্বরূপে স্থির করা হয়েছে। লাইব্রেরি থেকে অ্যাপটির নেমস্পেসটি ব্যবহার করতে ঘোষনা xmlns:app="http://schemas.android.com/apk/res-auto"করুন কোড জিমেইল
এনএমআর

2
আপনার কাস্টম নেমস্পেস সহ এখন একটি ত্রুটি ফিরে আসেSuspicious namespace: Did you mean http://schemas.android.com/apk/res-auto
বেন উইলকিনসন

কাস্টম নেমস্পেস রি-অটোতে শেষ হয় কারণ আমরা অ্যান্ড্রয়েড স্টুডিও এবং গ্রেডল ব্যবহার করছি। অন্যথায় (উদাহরণস্বরূপ, কিছু Eclipse সংস্করণ) এটি সাধারণত lib / [আপনার প্যাকেজের নাম]
ইউনিভার্সে শেষ হয়

কাস্টম নেমস্পেস শেষ হয় res-autoকারণ আমরা অ্যান্ড্রয়েড স্টুডিও এবং গ্রেডল ব্যবহার করছি। অন্যথায় (উদাহরণস্বরূপ, কিছু Eclipse সংস্করণ) এটি সাধারণত শেষ হয় lib/[your package name]। যেমনhttp://schemas.android.com/apk/lib/[your package name]
মহাবিশ্ব

27

সর্বাধিক ভোট দেওয়া উত্তরের সাথে যোগ করুন।

obtainStyledAttributes ()

আমি যখন অ্যান্ড্রয়েড: এক্সএক্সএক্স এক্সেরডিফাইন্ড অ্যাট্রিবিউট ব্যবহার করে কাস্টম ভিউ তৈরি করি তখন আমি রেকর্ড স্ট্যাটেল অ্যাট্রিবিউটস () ব্যবহার সম্পর্কে কিছু শব্দ যুক্ত করতে চাই। বিশেষত যখন আমরা টেক্সটঅ্যাপেন্স ব্যবহার করি।
"২। কনস্ট্রাক্টর তৈরি করা" তে যেমন উল্লেখ করা হয়েছে, কাস্টম ভিউ তার তৈরিতে অ্যাট্রিবিউটসেট পায়। প্রধান ব্যবহার আমরা টেক্সটভিউ উত্স কোড (API 16) এ দেখতে পারি।

final Resources.Theme theme = context.getTheme();

// TextAppearance is inspected first, but let observe it later

TypedArray a = theme.obtainStyledAttributes(
            attrs, com.android.internal.R.styleable.TextView, defStyle, 0);

int n = a.getIndexCount();
for (int i = 0; i < n; i++) 
{
    int attr = a.getIndex(i);
    // huge switch with pattern value=a.getXXX(attr) <=> a.getXXX(a.getIndex(i))
}
a.recycle();

আমরা এখানে কি দেখতে পারি?
obtainStyledAttributes(AttributeSet set, int[] attrs, int defStyleAttr, int defStyleRes)
ডকুমেন্টেশন অনুযায়ী বৈশিষ্ট্য সেট থিম দ্বারা প্রক্রিয়া করা হয়। গুণ মানগুলি ধাপে ধাপে সংকলিত হয়। প্রথম বৈশিষ্ট্যগুলি থিম থেকে পূর্ণ করা হয়, তারপরে মানগুলি শৈলীর মান দ্বারা প্রতিস্থাপন করা হয় এবং শেষ পর্যন্ত এক্সএমএল থেকে নির্দিষ্ট মানগুলির জন্য অন্যের পরিবর্তনের জন্য সঠিক মানগুলি প্রতিস্থাপন করা হয়।
অনুরোধ করা বৈশিষ্ট্যের অ্যারে - com.android.internal.R.styleable.TextView
এটি ধ্রুবকের একটি সাধারণ অ্যারে। আমরা যদি স্ট্যান্ডার্ড বৈশিষ্ট্যগুলির জন্য অনুরোধ করি তবে আমরা এই অ্যারেটি ম্যানুয়ালি তৈরি করতে পারি।

ডকুমেন্টেশনে যা উল্লেখ করা হয়নি - ফলাফল টাইপড্রাই উপাদানগুলির ক্রম।
যখন কাস্টম ভিউটি অ্যাটর্স.এক্সএমএল-এ ঘোষণা করা হয়, অ্যাট্রিবিউট সূচকগুলির জন্য বিশেষ ধ্রুবক তৈরি করা হয়। এবং আমরা মান এই ভাবে নিষ্কাশন করতে পারেন: a.getString(R.styleable.MyCustomView_android_text)। ম্যানুয়াল জন্যint[] জন্য কোন ধ্রুবক আছে। আমি মনে করি, এটি এক্সএক্সএক্সএক্সএক্সএলভিও (অ্যারেআইএনডেক্স) ঠিকঠাক কাজ করবে।

এবং অন্যান্য প্রশ্ন হ'ল: "কীভাবে আমরা অভ্যন্তরীণ ধ্রুবকগুলি প্রতিস্থাপন করতে পারি, এবং মানক বৈশিষ্ট্যের জন্য অনুরোধ করব?" আমরা android.R.attr। * মান ব্যবহার করতে পারি।

সুতরাং আমরা যদি কাস্টম ভিউতে স্ট্যান্ডার্ড টেক্সটএপরিয়েন্স অ্যাট্রিবিউটটি ব্যবহার করতে এবং কনস্ট্রাক্টরে এর মানগুলি পড়তে চাই তবে আমরা এইভাবে টেক্সটভিউ থেকে কোডটি সংশোধন করতে পারি:

ColorStateList textColorApp = null;
int textSize = 15;
int typefaceIndex = -1;
int styleIndex = -1;

Resources.Theme theme = context.getTheme();

TypedArray a = theme.obtainStyledAttributes(attrs, R.styleable.CustomLabel, defStyle, 0);
TypedArray appearance = null;
int apResourceId = a.getResourceId(R.styleable.CustomLabel_android_textAppearance, -1);
a.recycle();
if (apResourceId != -1)
{
    appearance = 
        theme.obtainStyledAttributes(apResourceId, new int[] { android.R.attr.textColor, android.R.attr.textSize, 
            android.R.attr.typeface, android.R.attr.textStyle });
}
if (appearance != null)
{
    textColorApp = appearance.getColorStateList(0);
    textSize = appearance.getDimensionPixelSize(1, textSize);
    typefaceIndex = appearance.getInt(2, -1);
    styleIndex = appearance.getInt(3, -1);

    appearance.recycle();
}

যেখানে কাস্টম লেবেল সংজ্ঞায়িত করা হয়েছে:

<declare-styleable name="CustomLabel">
    <!-- Label text. -->
    <attr name="android:text" />
    <!-- Label text color. -->
    <attr name="android:textColor" />
    <!-- Combined text appearance properties. -->
    <attr name="android:textAppearance" />
</declare-styleable>

হতে পারে, আমি কোনওভাবেই ভুল হয়েছি, তবে রেকর্ড স্ট্যাটরিবিটস () এ অ্যান্ড্রয়েড ডকুমেন্টেশন খুব খারাপ।

মানক UI উপাদান বাড়ানো হচ্ছে

একই সাথে আমরা এর সমস্ত ঘোষিত বৈশিষ্ট্যগুলি ব্যবহার করে কেবলমাত্র স্ট্যান্ডার্ড ইউআই উপাদানটি প্রসারিত করতে পারি। এই পদ্ধতিটি এতটা ভাল নয়, কারণ টেক্সটভিউ উদাহরণস্বরূপ প্রচুর সম্পত্তি ঘোষণা করে। এবং ওভাররডেন onMeasure () এবং onDraw () এ সম্পূর্ণ কার্যকারিতা প্রয়োগ করা অসম্ভব।

তবে আমরা কাস্টম উপাদানগুলির তাত্ত্বিক প্রশস্ত পুনরায় ব্যবহারের ত্যাগ করতে পারি। "আমি কী বৈশিষ্ট্যগুলি ব্যবহার করব তা আমি ঠিক জানি" বলুন এবং কারও সাথে কোড ভাগ করবেন না।

তারপরে আমরা কনস্ট্রাক্টর বাস্তবায়ন করতে পারি CustomComponent(Context, AttributeSet, defStyle)। কল করার পরে super(...)আমাদের সমস্ত বৈশিষ্ট্য পার্সড এবং গেটর পদ্ধতির মাধ্যমে পাওয়া যাবে।


অ্যান্ড্রয়েড করবেন: এক্সএক্সএক্সএক্স পূর্বনির্ধারিত বৈশিষ্ট্যগুলি গ্রিপ্স গুই ডিজাইনারে কাজ করে?
দিজ

এই জাতীয় বৈশিষ্ট্যগুলি সম্পত্তি সম্পাদকের এক্লিপস এডিটি প্লাগইন দ্বারা স্বীকৃত। আমি আমার স্টাইল থেকে ডিফল্ট দেখতে পাচ্ছি, যদি কিছু মান সংজ্ঞায়িত না হয়। এবং আপনার ক্লাসে @ রিমোটভিউ টীকা যুক্ত করতে ভুলবেন না।
ইউরিউইউইস

এটি কাজ করতে পারে না। গ্রহনটি getText এর জন্য নালগুলি লোড করে অ্যান্ড্রয়েডকন্টেন্ট.রেস রাখে R
দেজে

দুঃখিত, আমি আপনাকে সাহায্য করতে পারি না। আমি সম্ভাব্যতা পরীক্ষা করার জন্য কেবল ডেমো প্রকল্প তৈরি করেছি, এবং এ জাতীয় ত্রুটিগুলি পূরণ করি নি।
yuriy.weiss

এটি অভ্যন্তর অন্তর্নির্মিত দর্শনের অন্তর্নির্মিত বৈশিষ্ট্যগুলিতে কাস্টম ভিউয়ের কাস্টম বৈশিষ্ট্যের মানচিত্রের চেয়ে অনেক বেশি ভাল is
সামিস

13

দেখে মনে হচ্ছে গুগল তার বিকাশকারী পৃষ্ঠা আপডেট করেছে এবং সেখানে বিভিন্ন প্রশিক্ষণ যুক্ত করেছে।

এর মধ্যে একটি কাস্টম দর্শন তৈরির সাথে সম্পর্কিত এবং এটি এখানে পাওয়া যাবে


5

প্রথম উত্তরের জন্য অনেক ধন্যবাদ।

আমার হিসাবে, এটির সাথে আমার কেবল একটি সমস্যা ছিল। আমার দৃষ্টিভঙ্গি বাড়ানোর সময় আমার একটি বাগ ছিল: java.lang.NoSuchMethodException: MyView (প্রসঙ্গ, বৈশিষ্ট্য)

আমি একটি নতুন নির্মাতা তৈরি করে এটি সমাধান করেছি:

public MyView(Context context, AttributeSet attrs) {
     super(context, attrs);
     // some code
}

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


0

আপনি অন্য লেআউট ফাইলে যে কোনও লেআউট ফাইল এতে অন্তর্ভুক্ত করতে পারেন-

             <RelativeLayout
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginLeft="10dp"
                android:layout_marginRight="30dp" >

                <include
                    android:id="@+id/frnd_img_file"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    layout="@layout/include_imagefile"/>

                <include
                    android:id="@+id/frnd_video_file"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    layout="@layout/include_video_lay" />

                <ImageView
                    android:id="@+id/downloadbtn"
                    android:layout_width="30dp"
                    android:layout_height="30dp"
                    android:layout_centerInParent="true"
                    android:src="@drawable/plus"/>
            </RelativeLayout>

এখানে অন্তর্ভুক্ত ট্যাগের লেআউট ফাইলগুলি একই রেস ফোল্ডারের অন্যান্য .xML লেআউট ফাইল।


আমি এটি চেষ্টা করেছি, এতে আমার যে সমস্যাটি রয়েছে তা হ'ল অন্তর্ভুক্ত লেআউটটি 'অভিযোজিত' করা যায় না, জেনেরিক তৈরি করতে পারে না। উদাহরণস্বরূপ যখন আমি কোনও বোতামটি একইভাবে অন্তর্ভুক্ত করি, আমি যদি xML এ পাঠ্য সেট করার চেষ্টা করি তবে এটি কার্যকর হয়।
সিএফএল
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.