এক্সএমএল ব্যবহার করে আমি কীভাবে একটি Android ইউআই উপাদান ঘোষণা করতে পারি?
এক্সএমএল ব্যবহার করে আমি কীভাবে একটি Android ইউআই উপাদান ঘোষণা করতে পারি?
উত্তর:
অ্যান্ড্রয়েড বিকাশকারী গাইডের বিল্ডিং কাস্টম উপাদানগুলি নামে একটি বিভাগ রয়েছে । দুর্ভাগ্যবশত, এক্সএমএল বৈশিষ্ট্যগুলির আলোচনাটি কেবলমাত্র লেআউট ফাইলের অভ্যন্তরে নিয়ন্ত্রণ ঘোষণা করে এবং প্রকৃতপক্ষে শ্রেণি সূচনাতে মানগুলি পরিচালনা করে না। নিম্নরূপ পদক্ষেপ:
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
তাদের প্রকারটি ঘোষণা করা দরকার। সুপারক্লাসে ঘোষিত ট্যাগগুলি আবার ঘোষিত না করে সাবক্লাসে উপলব্ধ।
যেহেতু দুটি কনস্ট্রাক্টর রয়েছে যা একটি 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"
/>
সম্পূর্ণরূপে যোগ্যতাসম্পন্ন নাম ব্যবহার করে কাস্টম ভিউটি উল্লেখ করুন।
আপনি যদি একটি সম্পূর্ণ উদাহরণ চান তবে অ্যান্ড্রয়েড লেবেল দেখার নমুনাটি দেখুন।
TypedArray a=context.obtainStyledAttributes(attrs, R.styleable.LabelView);
CharSequences=a.getString(R.styleable.LabelView_text);
<declare-styleable name="LabelView">
<attr name="text"format="string"/>
<attr name="textColor"format="color"/>
<attr name="textSize"format="dimension"/>
</declare-styleable>
<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"
দুর্দান্ত রেফারেন্স। ধন্যবাদ! এটি সংযোজন:
যদি আপনার কাছে এমন কোনও লাইব্রেরি প্রকল্প অন্তর্ভুক্ত থাকে যা কাস্টম দর্শনের জন্য কাস্টম বৈশিষ্ট্যগুলি ঘোষণা করে থাকে তবে আপনাকে লাইব্রেরির নয়, আপনার প্রকল্পের নাম স্থানটি ঘোষণা করতে হবে। উদাহরণ:
প্রদত্ত যে লাইব্রেরিতে "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" />
Suspicious namespace: Did you mean http://schemas.android.com/apk/res-auto
res-auto
কারণ আমরা অ্যান্ড্রয়েড স্টুডিও এবং গ্রেডল ব্যবহার করছি। অন্যথায় (উদাহরণস্বরূপ, কিছু Eclipse সংস্করণ) এটি সাধারণত শেষ হয় lib/[your package name]
। যেমনhttp://schemas.android.com/apk/lib/[your package name]
সর্বাধিক ভোট দেওয়া উত্তরের সাথে যোগ করুন।
আমি যখন অ্যান্ড্রয়েড: এক্সএক্সএক্স এক্সেরডিফাইন্ড অ্যাট্রিবিউট ব্যবহার করে কাস্টম ভিউ তৈরি করি তখন আমি রেকর্ড স্ট্যাটেল অ্যাট্রিবিউটস () ব্যবহার সম্পর্কে কিছু শব্দ যুক্ত করতে চাই। বিশেষত যখন আমরা টেক্সটঅ্যাপেন্স ব্যবহার করি।
"২। কনস্ট্রাক্টর তৈরি করা" তে যেমন উল্লেখ করা হয়েছে, কাস্টম ভিউ তার তৈরিতে অ্যাট্রিবিউটসেট পায়। প্রধান ব্যবহার আমরা টেক্সটভিউ উত্স কোড (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>
হতে পারে, আমি কোনওভাবেই ভুল হয়েছি, তবে রেকর্ড স্ট্যাটরিবিটস () এ অ্যান্ড্রয়েড ডকুমেন্টেশন খুব খারাপ।
একই সাথে আমরা এর সমস্ত ঘোষিত বৈশিষ্ট্যগুলি ব্যবহার করে কেবলমাত্র স্ট্যান্ডার্ড ইউআই উপাদানটি প্রসারিত করতে পারি। এই পদ্ধতিটি এতটা ভাল নয়, কারণ টেক্সটভিউ উদাহরণস্বরূপ প্রচুর সম্পত্তি ঘোষণা করে। এবং ওভাররডেন onMeasure () এবং onDraw () এ সম্পূর্ণ কার্যকারিতা প্রয়োগ করা অসম্ভব।
তবে আমরা কাস্টম উপাদানগুলির তাত্ত্বিক প্রশস্ত পুনরায় ব্যবহারের ত্যাগ করতে পারি। "আমি কী বৈশিষ্ট্যগুলি ব্যবহার করব তা আমি ঠিক জানি" বলুন এবং কারও সাথে কোড ভাগ করবেন না।
তারপরে আমরা কনস্ট্রাক্টর বাস্তবায়ন করতে পারি CustomComponent(Context, AttributeSet, defStyle)
। কল করার পরে super(...)
আমাদের সমস্ত বৈশিষ্ট্য পার্সড এবং গেটর পদ্ধতির মাধ্যমে পাওয়া যাবে।
প্রথম উত্তরের জন্য অনেক ধন্যবাদ।
আমার হিসাবে, এটির সাথে আমার কেবল একটি সমস্যা ছিল। আমার দৃষ্টিভঙ্গি বাড়ানোর সময় আমার একটি বাগ ছিল: java.lang.NoSuchMethodException: MyView (প্রসঙ্গ, বৈশিষ্ট্য)
আমি একটি নতুন নির্মাতা তৈরি করে এটি সমাধান করেছি:
public MyView(Context context, AttributeSet attrs) {
super(context, attrs);
// some code
}
আশা করি এটি সাহায্য করবে!
আপনি অন্য লেআউট ফাইলে যে কোনও লেআউট ফাইল এতে অন্তর্ভুক্ত করতে পারেন-
<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 লেআউট ফাইল।