আমার নিজের মতো করে নিজস্ব বৈশিষ্ট্যগুলি প্রয়োগ করতে হবে com.android.R.attr
অফিসিয়াল ডকুমেন্টেশনে কিছুই পাওয়া যায় নি তাই এই অ্যাটর্সগুলিকে কীভাবে সংজ্ঞায়িত করা যায় এবং কীভাবে আমার কোড থেকে সেগুলি ব্যবহার করতে হয় সে সম্পর্কে আমার তথ্য দরকার।
আমার নিজের মতো করে নিজস্ব বৈশিষ্ট্যগুলি প্রয়োগ করতে হবে com.android.R.attr
অফিসিয়াল ডকুমেন্টেশনে কিছুই পাওয়া যায় নি তাই এই অ্যাটর্সগুলিকে কীভাবে সংজ্ঞায়িত করা যায় এবং কীভাবে আমার কোড থেকে সেগুলি ব্যবহার করতে হয় সে সম্পর্কে আমার তথ্য দরকার।
উত্তর:
বর্তমানে সেরা ডকুমেন্টেশন হ'ল উত্স। আপনি এখানে এটি একবার দেখতে পারেন (attrs.xML) ।
আপনি <resources>
একটি <declare-styleable>
উপাদানের শীর্ষ উপাদান বা অভ্যন্তরে বৈশিষ্ট্যগুলি সংজ্ঞায়িত করতে পারেন । যদি আমি একাধিক স্থানে কোনও অ্যাটর ব্যবহার করতে যাচ্ছি তবে আমি এটিকে মূল উপাদানটিতে রেখেছি। দ্রষ্টব্য, সমস্ত বৈশিষ্ট্য একই গ্লোবাল নেমস্পেস ভাগ করে। এর অর্থ হ'ল আপনি যদি কোনও <declare-styleable>
উপাদানের অভ্যন্তরে একটি নতুন বৈশিষ্ট্য তৈরি করেন তবে এটি এর বাইরেও ব্যবহার করা যেতে পারে এবং আপনি ভিন্ন ধরণের একই নামের সাথে অন্য কোনও বৈশিষ্ট্য তৈরি করতে পারবেন না।
একটি <attr>
উপাদান দুটি এক্সএমএল বৈশিষ্ট্য name
এবং format
। name
আপনাকে এটিকে কিছু বলতে দেয় এবং কোডের মধ্যে যেমন এটি উল্লেখ করা শেষ হয় তেমনি R.attr.my_attribute
। format
অ্যাট্রিবিউট 'টাইপ' অ্যাট্রিবিউট এর যদি আপনি চান তার উপর নির্ভর করে বিভিন্ন মান থাকতে পারে।
আপনি |
উদাহরণস্বরূপ, ব্যবহার করে একাধিক ধরণের বিন্যাস সেট করতে পারেন format="reference|color"
।
enum
বৈশিষ্ট্যগুলি নিম্নলিখিত হিসাবে সংজ্ঞায়িত করা যায়:
<attr name="my_enum_attr">
<enum name="value1" value="1" />
<enum name="value2" value="2" />
</attr>
flag
মানগুলি সংজ্ঞায়িত করা প্রয়োজন ব্যতীত বৈশিষ্ট্যগুলি সমান হয় যাতে তারা একসাথে কিছুটা
<attr name="my_flag_attr">
<flag name="fuzzy" value="0x01" />
<flag name="cold" value="0x02" />
</attr>
গুণাবলী ছাড়াও <declare-styleable>
উপাদান রয়েছে। এটি আপনাকে কাস্টম দর্শনটি ব্যবহার করতে পারে এমন বৈশিষ্ট্যগুলি সংজ্ঞায়িত করতে দেয়। আপনি কোনও <attr>
উপাদান নির্দিষ্ট করে এটি করেন, যদি এটি পূর্বনির্ধারিত হয় তবে আপনি এটি নির্দিষ্ট করে না format
। যদি আপনি কোনও অ্যান্ড্রয়েড অ্যাটরকে পুনরায় ব্যবহার করতে চান, উদাহরণস্বরূপ, অ্যান্ড্রয়েড: মাধ্যাকর্ষণ, তবে আপনি নীচে এটি করতে পারেন name
।
একটি কাস্টম দর্শন উদাহরণ <declare-styleable>
:
<declare-styleable name="MyCustomView">
<attr name="my_custom_attribute" />
<attr name="android:gravity" />
</declare-styleable>
আপনার কাস্টম ভিউতে এক্সএমএলে আপনার কাস্টম বৈশিষ্ট্যগুলি সংজ্ঞায়িত করার সময় আপনাকে কয়েকটি জিনিস করতে হবে। আপনার বৈশিষ্ট্যগুলি খুঁজতে প্রথমে আপনাকে অবশ্যই একটি নেমস্পেস ঘোষণা করতে হবে। আপনি এটি মূল বিন্যাস উপাদানটিতে করেন। সাধারণত আছে xmlns:android="http://schemas.android.com/apk/res/android"
। আপনি এখন যোগ করতে হবে xmlns:whatever="http://schemas.android.com/apk/res-auto"
।
উদাহরণ:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:whatever="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<org.example.mypackage.MyCustomView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center"
whatever:my_custom_attribute="Hello, world!" />
</LinearLayout>
অবশেষে, সেই কাস্টম বৈশিষ্ট্যটি অ্যাক্সেস করতে আপনি সাধারণত আপনার কাস্টম ভিউর কনস্ট্রাক্টরে নিম্নরূপ করুন।
public MyCustomView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.MyCustomView, defStyle, 0);
String str = a.getString(R.styleable.MyCustomView_my_custom_attribute);
//do something with str
a.recycle();
}
শেষ। :)
View
: github.com/commonsguy/cw-advandroid/tree/master/Views/…
xmlns:my="http://schemas.android.com/apk/lib/my.namespace"
- কোনও অনুলিপি করা Attrs.xML নেই। নোটস্পেসের ইউআরআই পাথটি অবশ্যই / apk / * lib * নয় / apk / res হওয়া উচিত Note
apk/lib
একটি গ্রন্থাগার প্রকল্পের রেফারেন্স ফর্ম্যাট সহ কাস্টম বৈশিষ্ট্যে আমার জন্য কাজ করে নি। কি করেনি কাজ ব্যবহার ছিল apk/res-auto
হিসাবে প্রস্তাব, stackoverflow.com/a/13420366/22904 এবং মাত্র নিচের এছাড়াও stackoverflow.com/a/10217752
enum
এবং এর মধ্যে মূল পার্থক্যকে হ্রাস করার মতো flag
: পূর্ববর্তীটি আমাদের একটি এবং শুধুমাত্র একটি মান বাছাই করতে দেয়, পরবর্তীটি আমাদের বেশ কয়েকটিকে একত্রিত করতে দেয়। আমি এখানে একটি অনুরূপ প্রশ্নে একটি দীর্ঘ উত্তর লিখেছিলাম , এবং এখন এই প্রশ্নটি পেয়ে আমি অনুভব করেছি যে আমি এটির সাথে লিঙ্ক করব।
a.recycle()
স্মৃতি মুক্ত করার জন্য এখানে খুব গুরুত্বপূর্ণ
কিবার্টিকাসের উত্তরটি ভাল তবে একটি দরকারী বিশদ অনুপস্থিত। আপনি যদি একটি লাইব্রেরিতে এগুলি প্রয়োগ করেন তবে প্রতিস্থাপন করুন:
xmlns:whatever="http://schemas.android.com/apk/res/org.example.mypackage"
সঙ্গে:
xmlns:whatever="http://schemas.android.com/apk/res-auto"
অন্যথায় অ্যাপ্লিকেশন যা গ্রন্থাগারটি ব্যবহার করে তাতে রানটাইম ত্রুটি থাকবে।
উপরের উত্তরটি কয়েকটি জিনিস বাদ দিয়ে সমস্ত কিছু দুর্দান্তভাবে কভার করে।
প্রথমত, যদি কোনও শৈলী না থাকে, তবে (Context context, AttributeSet attrs)
পদ্ধতিটি স্বাক্ষরটি পছন্দটি ইনস্ট্যান্ট করতে ব্যবহৃত হবে। context.obtainStyledAttributes(attrs, R.styleable.MyCustomView)
এক্ষেত্রে কেবল টাইপড্রেই পেতে ব্যবহার করুন ।
দ্বিতীয়ত এটি প্লুরালসের সংস্থানগুলি (পরিমাণের স্ট্রিং) কীভাবে মোকাবেলা করতে হবে তা কভার করে না। এগুলি টাইপড্রাই ব্যবহার করে মোকাবেলা করা যাবে না। এখানে আমার সেকবারপ্রিফারেন্সির একটি কোড স্নিপেট রয়েছে যা পছন্দের সংক্ষিপ্তসারটিকে অগ্রাধিকারের মান অনুসারে এর মানটিকে বিন্যাস করে sets পছন্দের জন্য xML যদি অ্যান্ড্রয়েড সেট করে: কোনও পাঠ্য স্ট্রিংয়ের একটি সংক্ষিপ্তসার বা স্ট্রিংটিকে পছন্দ করে দেওয়া পছন্দটির মানটিকে স্ট্রিংয়ে ফর্ম্যাট করা হয় (মানটি তুলতে এটিতে এটি% d থাকা উচিত)। যদি অ্যান্ড্রয়েড: সংক্ষিপ্তসারটি বহুবিধ সংস্থানে সেট করা থাকে, তবে ফলাফলটি ফর্ম্যাট করতে এটি ব্যবহৃত হয়।
// Use your own name space if not using an android resource.
final static private String ANDROID_NS =
"http://schemas.android.com/apk/res/android";
private int pluralResource;
private Resources resources;
private String summary;
public SeekBarPreference(Context context, AttributeSet attrs) {
// ...
TypedArray attributes = context.obtainStyledAttributes(
attrs, R.styleable.SeekBarPreference);
pluralResource = attrs.getAttributeResourceValue(ANDROID_NS, "summary", 0);
if (pluralResource != 0) {
if (! resources.getResourceTypeName(pluralResource).equals("plurals")) {
pluralResource = 0;
}
}
if (pluralResource == 0) {
summary = attributes.getString(
R.styleable.SeekBarPreference_android_summary);
}
attributes.recycle();
}
@Override
public CharSequence getSummary() {
int value = getPersistedInt(defaultValue);
if (pluralResource != 0) {
return resources.getQuantityString(pluralResource, value, value);
}
return (summary == null) ? null : String.format(summary, value);
}
notifyChanged()
পছন্দের onDialogClosed
পদ্ধতিতে কল করতে হবে ।প্রচলিত পদ্ধতির বয়লারপ্লেট কোড এবং আনাড়ি সংস্থান হ্যান্ডলিং পূর্ণ। এজন্যই আমি স্পাইগ্লাস ফ্রেমওয়ার্ক তৈরি করেছি । এটি কীভাবে কাজ করে তা প্রদর্শনের জন্য, এখানে একটি উদাহরণ এখানে কীভাবে একটি কাস্টম ভিউ তৈরি করতে হয় যা একটি স্ট্রিং শিরোনাম প্রদর্শন করে।
পদক্ষেপ 1: একটি কাস্টম ভিউ ক্লাস তৈরি করুন।
public class CustomView extends FrameLayout {
private TextView titleView;
public CustomView(Context context) {
super(context);
init(null, 0, 0);
}
public CustomView(Context context, AttributeSet attrs) {
super(context, attrs);
init(attrs, 0, 0);
}
public CustomView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(attrs, defStyleAttr, 0);
}
@RequiresApi(21)
public CustomView(
Context context,
AttributeSet attrs,
int defStyleAttr,
int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
init(attrs, defStyleAttr, defStyleRes);
}
public void setTitle(String title) {
titleView.setText(title);
}
private void init(AttributeSet attrs, int defStyleAttr, int defStyleRes) {
inflate(getContext(), R.layout.custom_view, this);
titleView = findViewById(R.id.title_view);
}
}
পদক্ষেপ 2: values/attrs.xml
রিসোর্স ফাইলে একটি স্ট্রিং বৈশিষ্ট্য নির্ধারণ করুন:
<resources>
<declare-styleable name="CustomView">
<attr name="title" format="string"/>
</declare-styleable>
</resources>
পদক্ষেপ 3: প্রয়োগ @StringHandler
করতে টীকা setTitle
পদ্ধতি যখন দৃশ্য স্ফীত হয় ক্ষুদ্র দুরবিনবিশেষ ফ্রেমওয়ার্ক রুট অ্যাট্রিবিউট মান এই পদ্ধতিতে বলতে।
@HandlesString(attributeId = R.styleable.CustomView_title)
public void setTitle(String title) {
titleView.setText(title);
}
এখন আপনার ক্লাসে একটি স্পাইগ্লাস টিকা রয়েছে, স্পাইগ্লাস ফ্রেমওয়ার্কটি এটি সংকলন-সময় সনাক্ত করে এবং স্বয়ংক্রিয়ভাবে CustomView_SpyglassCompanion
শ্রেণিটি তৈরি করবে ।
পদক্ষেপ 4: কাস্টম ভিউয়ের init
পদ্ধতিতে উত্পন্ন শ্রেণিটি ব্যবহার করুন :
private void init(AttributeSet attrs, int defStyleAttr, int defStyleRes) {
inflate(getContext(), R.layout.custom_view, this);
titleView = findViewById(R.id.title_view);
CustomView_SpyglassCompanion
.builder()
.withTarget(this)
.withContext(getContext())
.withAttributeSet(attrs)
.withDefaultStyleAttribute(defStyleAttr)
.withDefaultStyleResource(defStyleRes)
.build()
.callTargetMethodsNow();
}
এটাই. এখন আপনি যখন এক্সএমএল থেকে ক্লাসটি ইনস্ট্যান্ট করেন, স্পাইগ্লাসের সহযোগী বৈশিষ্ট্যগুলি ব্যাখ্যা করে এবং প্রয়োজনীয় পদ্ধতিতে কল দেয়। উদাহরণস্বরূপ, যদি আমরা নীচের লেআউটটি স্ফীত করি তবে আর্গুমেন্ট হিসাবে setTitle
ডাকা হবে "Hello, World!"
।
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:width="match_parent"
android:height="match_parent">
<com.example.CustomView
android:width="match_parent"
android:height="match_parent"
app:title="Hello, World!"/>
</FrameLayout>
ফ্রেমওয়ার্কটিতে স্ট্রিং রিসোর্সগুলির মধ্যে সীমাবদ্ধ নয় অন্যান্য সংস্থার ধরণের হ্যান্ডল করার জন্য প্রচুর বিভিন্ন টিকা রয়েছে। এটিতে ডিফল্ট মানগুলি সংজ্ঞায়িত করার জন্য এবং স্থানধারক মানগুলিতে পাস করার জন্য টিকা আছে যদি আপনার পদ্ধতিগুলির একাধিক পরামিতি থাকে।
আরও তথ্য এবং উদাহরণের জন্য গিথুব রেপোতে দেখুন।
android:title="@{"Hello, world!"}"
।
যদি আপনি উপাদান format
থেকে বৈশিষ্ট্য বাদ দেন attr
, আপনি এটি এক্সএমএল লেআউট থেকে কোনও শ্রেণি রেফারেন্স করতে ব্যবহার করতে পারেন।
Refactor > Rename
কাজFind Usages
কাজ... / src / main / res / মান / attrs.xML এ কোনও format
বৈশিষ্ট্য নির্দিষ্ট করবেন না
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="MyCustomView">
....
<attr name="give_me_a_class"/>
....
</declare-styleable>
</resources>
এটি কোনও লেআউট ফাইলটিতে ব্যবহার করুন ...
<?xml version="1.0" encoding="utf-8"?>
<SomeLayout
xmlns:app="http://schemas.android.com/apk/res-auto">
<!-- make sure to use $ dollar signs for nested classes -->
<MyCustomView
app:give_me_a_class="class.type.name.Outer$Nested/>
<MyCustomView
app:give_me_a_class="class.type.name.AnotherClass/>
</SomeLayout>
আপনার দর্শন শুরুর কোডটিতে শ্রেণি পার্স করুন ...
class MyCustomView(
context:Context,
attrs:AttributeSet)
:View(context,attrs)
{
// parse XML attributes
....
private val giveMeAClass:SomeCustomInterface
init
{
context.theme.obtainStyledAttributes(attrs,R.styleable.ColorPreference,0,0).apply()
{
try
{
// very important to use the class loader from the passed-in context
giveMeAClass = context::class.java.classLoader!!
.loadClass(getString(R.styleable.MyCustomView_give_me_a_class))
.newInstance() // instantiate using 0-args constructor
.let {it as SomeCustomInterface}
}
finally
{
recycle()
}
}
}