আপনার অ্যাপে স্থির চিত্র প্রদর্শন করার প্রয়োজন হলে, আপনি বিভিন্ন আকার ও চিত্র আঁকার জন্য Drawable ক্লাস এবং এর সাবক্লাসগুলো ব্যবহার করতে পারেন। Drawable হলো এমন কিছুর একটি সাধারণ ধারণা যা আঁকা যায় । এর বিভিন্ন সাবক্লাসগুলো নির্দিষ্ট চিত্রের ক্ষেত্রে সাহায্য করে এবং আপনি সেগুলোকে প্রসারিত করে আপনার নিজস্ব ড্রয়েবল অবজেক্ট তৈরি করতে পারেন, যেগুলো স্বতন্ত্রভাবে কাজ করে।
ক্লাস কনস্ট্রাক্টর ব্যবহার করা ছাড়াও একটি Drawable সংজ্ঞায়িত এবং ইনস্ট্যানশিয়েট করার দুটি উপায় আছে:
- আপনার প্রজেক্টে সংরক্ষিত একটি ইমেজ রিসোর্স (একটি বিটম্যাপ ফাইল) ইনফ্লেট করুন।
- একটি XML রিসোর্স ইনফ্লেট করুন যা ড্রয়েবল প্রোপার্টিগুলো সংজ্ঞায়িত করে।
দ্রষ্টব্য: এর পরিবর্তে আপনি একটি ভেক্টর ড্রয়েবল ব্যবহার করতে পছন্দ করতে পারেন, যা সংশ্লিষ্ট রঙের তথ্যসহ একগুচ্ছ বিন্দু, রেখা এবং বক্ররেখা দিয়ে একটি চিত্রকে সংজ্ঞায়িত করে। এর ফলে ভেক্টর ড্রয়েবলগুলোকে গুণমান নষ্ট না করেই বিভিন্ন আকারে স্কেল করা যায়। আরও তথ্যের জন্য, ভেক্টর ড্রয়েবল ওভারভিউ দেখুন।
রিসোর্স ইমেজ থেকে ড্রয়েবল তৈরি করুন
আপনার প্রজেক্ট রিসোর্স থেকে একটি ইমেজ ফাইল রেফারেন্স করে আপনি আপনার অ্যাপে গ্রাফিক্স যোগ করতে পারেন। সমর্থিত ফাইলের ধরণগুলো হলো PNG (পছন্দনীয়), JPG (গ্রহণযোগ্য), এবং GIF (অনুৎসাহিত)। অ্যাপ আইকন, লোগো এবং গেমে ব্যবহৃত অন্যান্য গ্রাফিক্স এই পদ্ধতির জন্য বিশেষভাবে উপযুক্ত।
একটি ইমেজ রিসোর্স ব্যবহার করতে, আপনার ফাইলটি আপনার প্রজেক্টের res/drawable/ ডিরেক্টরিতে যুক্ত করুন। প্রজেক্টে যুক্ত করার পর, আপনি আপনার কোড বা XML লেআউট থেকে ইমেজ রিসোর্সটি রেফারেন্স করতে পারবেন। উভয় ক্ষেত্রেই, এটিকে একটি রিসোর্স আইডি ব্যবহার করে উল্লেখ করা হয়, যা হলো ফাইল টাইপ এক্সটেনশন ছাড়া ফাইলের নাম। উদাহরণস্বরূপ, my_image.png কে my_image হিসেবে উল্লেখ করুন।
দ্রষ্টব্য: res/drawable/ ডিরেক্টরিতে রাখা ইমেজ রিসোর্সগুলো বিল্ড প্রক্রিয়ার সময় aapt টুল দ্বারা লসলেস ইমেজ কম্প্রেশন ব্যবহার করে স্বয়ংক্রিয়ভাবে অপ্টিমাইজ করা হতে পারে। উদাহরণস্বরূপ, একটি ট্রু-কালার PNG যাতে ২৫৬টির বেশি রঙের প্রয়োজন হয় না, সেটিকে একটি কালার প্যালেটসহ ৮-বিট PNG-তে রূপান্তর করা হতে পারে। এর ফলে একই মানের একটি ইমেজ তৈরি হয়, কিন্তু সেটির জন্য কম মেমরির প্রয়োজন হয়। ফলস্বরূপ, এই ডিরেক্টরিতে রাখা ইমেজ বাইনারিগুলো বিল্ডের সময় পরিবর্তিত হতে পারে। আপনি যদি কোনো ইমেজকে বিটম্যাপে রূপান্তর করার জন্য বিটস্ট্রিম হিসেবে পড়ার পরিকল্পনা করেন, তবে আপনার ইমেজগুলো res/raw/ ফোল্ডারে রাখুন, যেখানে aapt টুল সেগুলোকে পরিবর্তন করে না।
নিম্নলিখিত কোড স্নিপেটটি দেখায় কিভাবে একটি ImageView তৈরি করতে হয় যা একটি ড্রয়েবল রিসোর্স থেকে তৈরি করা ছবি ব্যবহার করে এবং সেটিকে লেআউটে যুক্ত করে:
কোটলিন
private lateinit var constraintLayout: ConstraintLayout override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // Instantiate an ImageView and define its properties val i = ImageView(this).apply { setImageResource(R.drawable.my_image) contentDescription = resources.getString(R.string.my_image_desc) // set the ImageView bounds to match the Drawable's dimensions adjustViewBounds = true layoutParams = ViewGroup.LayoutParams( ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT) } // Create a ConstraintLayout in which to add the ImageView constraintLayout = ConstraintLayout(this).apply { // Add the ImageView to the layout. addView(i) } // Set the layout as the content view. setContentView(constraintLayout) }
জাভা
ConstraintLayout constraintLayout; protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Create a ConstraintLayout in which to add the ImageView constraintLayout = new ConstraintLayout(this); // Instantiate an ImageView and define its properties ImageView i = new ImageView(this); i.setImageResource(R.drawable.my_image); i.setContentDescription(getResources().getString(R.string.my_image_desc)); // set the ImageView bounds to match the Drawable's dimensions i.setAdjustViewBounds(true); i.setLayoutParams(new ViewGroup.LayoutParams( ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT)); // Add the ImageView to the layout and set the layout as the content view. constraintLayout.addView(i); setContentView(constraintLayout); }
অন্যান্য ক্ষেত্রে, আপনি আপনার ইমেজ রিসোর্সটিকে একটি Drawable অবজেক্ট হিসেবে পরিচালনা করতে চাইতে পারেন, যেমনটি নিম্নলিখিত উদাহরণে দেখানো হয়েছে:
কোটলিন
val myImage: Drawable = ResourcesCompat.getDrawable(context.resources, R.drawable.my_image, null)
জাভা
Resources res = context.getResources(); Drawable myImage = ResourcesCompat.getDrawable(res, R.drawable.my_image, null);
সতর্কতা: আপনার প্রোজেক্টের প্রতিটি স্বতন্ত্র রিসোর্স শুধুমাত্র একটি অবস্থা বজায় রাখতে পারে, আপনি এর জন্য যতগুলোই ভিন্ন অবজেক্ট ইনস্ট্যানশিয়েট করুন না কেন। উদাহরণস্বরূপ, যদি আপনি একই ইমেজ রিসোর্স থেকে দুটি Drawable অবজেক্ট ইনস্ট্যানশিয়েট করেন এবং একটি অবজেক্টের কোনো প্রপার্টি (যেমন আলফা) পরিবর্তন করেন, তাহলে তা অন্যটিকেও প্রভাবিত করবে। একটি ইমেজ রিসোর্সের একাধিক ইনস্ট্যান্স নিয়ে কাজ করার সময়, Drawable অবজেক্টটিকে সরাসরি ট্রান্সফর্ম না করে আপনার একটি টুইন অ্যানিমেশন (tween animation) চালানো উচিত।
নিচের XML কোড স্নিপেটটি দেখাচ্ছে কিভাবে XML লেআউটে একটি ImageView তে একটি ড্রয়েবল রিসোর্স যোগ করতে হয়:
<ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/my_image" android:contentDescription="@string/my_image_desc" />
প্রকল্পের সম্পদ ব্যবহার সম্পর্কে আরও তথ্যের জন্য, সম্পদ ও উপকরণ দেখুন।
দ্রষ্টব্য: আপনার ড্রয়েবলের উৎস হিসেবে ইমেজ রিসোর্স ব্যবহার করার সময়, নিশ্চিত করুন যে ইমেজগুলো বিভিন্ন পিক্সেল ডেনসিটির জন্য উপযুক্ত আকারের। যদি ইমেজগুলো সঠিক না হয়, তবে সেগুলোকে মানানসই করার জন্য স্কেল আপ করা হবে, যা আপনার ড্রয়েবলে আর্টিফ্যাক্টিং সৃষ্টি করতে পারে। আরও তথ্যের জন্য, ‘বিভিন্ন পিক্সেল ডেনসিটি সাপোর্ট’ পড়ুন।
XML রিসোর্স থেকে ড্রয়েবল তৈরি করুন
যদি আপনি এমন একটি Drawable অবজেক্ট তৈরি করতে চান যা প্রাথমিকভাবে আপনার কোড বা ব্যবহারকারীর কার্যকলাপ দ্বারা সংজ্ঞায়িত ভেরিয়েবলের উপর নির্ভরশীল নয়, তাহলে XML-এ Drawable সংজ্ঞায়িত করা একটি ভালো বিকল্প। এমনকি যদি আপনি আশা করেন যে আপনার অ্যাপের সাথে ব্যবহারকারীর কার্যকলাপের সময় আপনার Drawable এর প্রোপার্টিগুলো পরিবর্তিত হবে, তবুও আপনার অবজেক্টটি XML-এ সংজ্ঞায়িত করার কথা বিবেচনা করা উচিত, কারণ অবজেক্টটি ইনস্ট্যানশিয়েট হওয়ার পরেও আপনি এর প্রোপার্টিগুলো পরিবর্তন করতে পারবেন।
XML-এ আপনার Drawable সংজ্ঞায়িত করার পরে, ফাইলটি আপনার প্রোজেক্টের res/drawable/ ডিরেক্টরিতে সেভ করুন। নিম্নলিখিত উদাহরণটি একটি TransitionDrawable রিসোর্সের XML দেখায়, যা Drawable থেকে ইনহেরিট করে:
<!-- res/drawable/expand_collapse.xml --> <transition xmlns:android="http://schemas.android.com/apk/res/android"> <item android:drawable="@drawable/image_expand"/> <item android:drawable="@drawable/image_collapse"/> </transition>
এরপর, Resources#getDrawable() কল করে এবং আপনার XML ফাইলের রিসোর্স আইডি পাস করে অবজেক্টটি পুনরুদ্ধার ও ইনস্ট্যানশিয়েট করুন। inflate() মেথড সমর্থন করে এমন যেকোনো Drawable সাবক্লাস XML-এ সংজ্ঞায়িত করা এবং আপনার অ্যাপ দ্বারা ইনস্ট্যানশিয়েট করা যেতে পারে।
এক্সএমএল ইনফ্লেশন সমর্থনকারী প্রতিটি ড্রয়েবল ক্লাস নির্দিষ্ট এক্সএমএল অ্যাট্রিবিউট ব্যবহার করে, যা অবজেক্টের বৈশিষ্ট্যগুলো নির্ধারণ করতে সাহায্য করে। নিম্নলিখিত কোডটি TransitionDrawable কে ইনস্ট্যানশিয়েট করে এবং এটিকে একটি ImageView অবজেক্টের কন্টেন্ট হিসেবে সেট করে:
কোটলিন
val transition= ResourcesCompat.getDrawable( context.resources, R.drawable.expand_collapse, null ) as TransitionDrawable val image: ImageView = findViewById(R.id.toggle_image) image.setImageDrawable(transition) // Description of the initial state that the drawable represents. image.contentDescription = resources.getString(R.string.collapsed) // Then you can call the TransitionDrawable object's methods. transition.startTransition(1000) // After the transition is complete, change the image's content description // to reflect the new state.
জাভা
Resources res = context.getResources(); TransitionDrawable transition = (TransitionDrawable) ResourcesCompat.getDrawable(res, R.drawable.expand_collapse, null); ImageView image = (ImageView) findViewById(R.id.toggle_image); image.setImageDrawable(transition); // Description of the initial state that the drawable represents. image.setContentDescription(getResources().getString(R.string.collapsed)); // Then you can call the TransitionDrawable object's methods. transition.startTransition(1000); // After the transition is complete, change the image's content description // to reflect the new state.
সমর্থিত XML অ্যাট্রিবিউটগুলো সম্পর্কে আরও তথ্যের জন্য, উপরে তালিকাভুক্ত ক্লাসগুলো দেখুন।
আকৃতি অঙ্কনযোগ্য
যখন আপনি গতিশীলভাবে একটি দ্বি-মাত্রিক গ্রাফিক আঁকতে চান, তখন একটি ShapeDrawable অবজেক্ট একটি ভালো বিকল্প হতে পারে। আপনি প্রোগ্রাম্যাটিকভাবে একটি ShapeDrawable অবজেক্টে আদিম আকার আঁকতে পারেন এবং আপনার অ্যাপের প্রয়োজনীয় স্টাইলগুলো প্রয়োগ করতে পারেন।
ShapeDrawable হলো Drawable এর একটি সাবক্লাস। এই কারণে, যেখানেই একটি Drawable ব্যবহৃত হওয়ার কথা, সেখানেই আপনি ShapeDrawable ব্যবহার করতে পারেন। উদাহরণস্বরূপ, আপনি একটি ভিউ-এর setBackgroundDrawable() মেথডে একটি ShapeDrawable অবজেক্ট পাস করে সেটির ব্যাকগ্রাউন্ড সেট করতে পারেন। এছাড়া, আপনি আপনার শেপটিকে নিজস্ব কাস্টম ভিউ হিসেবেও আঁকতে পারেন এবং আপনার অ্যাপের কোনো লেআউটে তা যুক্ত করতে পারেন।
যেহেতু ShapeDrawable নিজস্ব draw() মেথড আছে, তাই আপনি View এর একটি সাবক্লাস তৈরি করতে পারেন যা onDraw() ইভেন্টের সময় ShapeDrawable অবজেক্টটি অঙ্কন করে, যেমনটি নিম্নলিখিত কোড উদাহরণে দেখানো হয়েছে:
কোটলিন
class CustomDrawableView(context: Context) : View(context) { private val drawable: ShapeDrawable = run { val x = 10 val y = 10 val width = 300 val height = 50 contentDescription = context.resources.getString(R.string.my_view_desc) ShapeDrawable(OvalShape()).apply { // If the color isn't set, the shape uses black as the default. paint.color = 0xff74AC23.toInt() // If the bounds aren't set, the shape can't be drawn. setBounds(x, y, x + width, y + height) } } override fun onDraw(canvas: Canvas) { drawable.draw(canvas) } }
জাভা
public class CustomDrawableView extends View { private ShapeDrawable drawable; public CustomDrawableView(Context context) { super(context); int x = 10; int y = 10; int width = 300; int height = 50; setContentDescription(context.getResources().getString( R.string.my_view_desc)); drawable = new ShapeDrawable(new OvalShape()); // If the color isn't set, the shape uses black as the default. drawable.getPaint().setColor(0xff74AC23); // If the bounds aren't set, the shape can't be drawn. drawable.setBounds(x, y, x + width, y + height); } protected void onDraw(Canvas canvas) { drawable.draw(canvas); } }
উপরের কোড স্যাম্পলে থাকা CustomDrawableView ক্লাসটি আপনি অন্য যেকোনো কাস্টম ভিউয়ের মতোই ব্যবহার করতে পারেন। উদাহরণস্বরূপ, আপনি এটিকে আপনার অ্যাপের কোনো অ্যাক্টিভিটিতে প্রোগ্রাম্যাটিকভাবে যোগ করতে পারেন, যেমনটি নিচের উদাহরণে দেখানো হয়েছে:
কোটলিন
private lateinit var customDrawableView: CustomDrawableView override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) customDrawableView = CustomDrawableView(this) setContentView(customDrawableView) }
জাভা
CustomDrawableView customDrawableView; protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); customDrawableView = new CustomDrawableView(this); setContentView(customDrawableView); }
এর পরিবর্তে যদি আপনি XML লেআউটে কাস্টম ভিউ ব্যবহার করতে চান, তাহলে CustomDrawableView ক্লাসকে অবশ্যই View(Context, AttributeSet) কনস্ট্রাক্টরটি ওভাররাইড করতে হবে, যেটি XML থেকে ক্লাসটি ইনফ্লেট করার সময় কল করা হয়। নিচের উদাহরণটিতে দেখানো হয়েছে কিভাবে XML লেআউটে CustomDrawableView ডিক্লেয়ার করতে হয়:
<com.example.shapedrawable.CustomDrawableView android:layout_width="fill_parent" android:layout_height="wrap_content" />
android.graphics.drawable প্যাকেজের অন্যান্য অনেক ড্রয়েবল টাইপের মতো, ShapeDrawable ক্লাসটিও আপনাকে পাবলিক মেথড ব্যবহার করে অবজেক্টের বিভিন্ন প্রোপার্টি নির্ধারণ করার সুযোগ দেয়। কিছু উদাহরণমূলক প্রোপার্টি যা আপনি পরিবর্তন করতে চাইতে পারেন, তার মধ্যে রয়েছে আলফা ট্রান্সপারেন্সি, কালার ফিল্টার, ডিথার, অপাসিটি এবং কালার।
আপনি XML রিসোর্স ব্যবহার করে আদিম অঙ্কনযোগ্য আকারও সংজ্ঞায়িত করতে পারেন। আরও তথ্যের জন্য, 'ড্রয়েবল রিসোর্স টাইপস'-এর অধীনে 'শেপ ড্রয়েবল' দেখুন।
নাইনপ্যাচ ড্রয়েবলস
একটি NinePatchDrawable গ্রাফিক হলো একটি প্রসারণযোগ্য বিটম্যাপ ইমেজ যা আপনি কোনো ভিউ-এর ব্যাকগ্রাউন্ড হিসেবে ব্যবহার করতে পারেন। অ্যান্ড্রয়েড স্বয়ংক্রিয়ভাবে গ্রাফিকটির আকার পরিবর্তন করে ভিউ-এর বিষয়বস্তুর সাথে মানিয়ে নেয়। নাইনপ্যাচ ইমেজের একটি উদাহরণ হলো সাধারণ অ্যান্ড্রয়েড বাটনগুলোর ব্যাকগ্রাউন্ড—বিভিন্ন দৈর্ঘ্যের স্ট্রিং ধারণ করার জন্য বাটনগুলোকে অবশ্যই প্রসারিত হতে হয়। একটি নাইনপ্যাচ গ্রাফিক হলো একটি সাধারণ পিএনজি ইমেজ যাতে একটি অতিরিক্ত ১-পিক্সেলের বর্ডার থাকে। এটিকে অবশ্যই আপনার প্রজেক্টের res/drawable/ ডিরেক্টরিতে 9.png এক্সটেনশন দিয়ে সেভ করতে হবে।
ছবির প্রসারণযোগ্য এবং স্থির অংশ নির্ধারণ করতে বর্ডার ব্যবহার করুন। বর্ডারের বাম এবং উপরের অংশে এক বা একাধিক ১-পিক্সেল চওড়া কালো রেখা এঁকে একটি প্রসারণযোগ্য অংশ নির্দেশ করুন (বর্ডারের অন্যান্য পিক্সেলগুলো সম্পূর্ণ স্বচ্ছ বা সাদা হওয়া উচিত)। আপনি আপনার ইচ্ছামতো প্রসারণযোগ্য অংশ রাখতে পারেন। প্রসারণযোগ্য অংশগুলোর আপেক্ষিক আকার একই থাকে, তাই সবচেয়ে বড় অংশটি সর্বদা সবচেয়ে বড়ই থাকে।
আপনি ডানদিকে একটি লাইন এবং নীচে একটি লাইন এঁকে ছবির একটি ঐচ্ছিক অঙ্কনযোগ্য অংশও (কার্যত, প্যাডিং লাইনগুলো) নির্ধারণ করতে পারেন। যদি একটি View অবজেক্ট তার ব্যাকগ্রাউন্ড হিসেবে নাইনপ্যাচ গ্রাফিকটি সেট করে এবং তারপর ভিউটির টেক্সট নির্দিষ্ট করে, তবে এটি নিজেকে এমনভাবে প্রসারিত করে যাতে সমস্ত টেক্সট শুধুমাত্র ডান এবং নীচের লাইন দ্বারা নির্ধারিত এলাকা জুড়ে থাকে (যদি অন্তর্ভুক্ত থাকে)। যদি প্যাডিং লাইনগুলো অন্তর্ভুক্ত না থাকে, তবে অ্যান্ড্রয়েড এই অঙ্কনযোগ্য এলাকাটি নির্ধারণ করতে বাম এবং উপরের লাইন ব্যবহার করে।
লাইনগুলোর মধ্যে পার্থক্য স্পষ্ট করার জন্য, বাম এবং উপরের লাইনগুলো নির্ধারণ করে যে ছবিটিকে প্রসারিত করার জন্য এর কোন পিক্সেলগুলোকে প্রতিলিপি করার অনুমতি দেওয়া হবে। নিচের এবং ডান লাইনগুলো ছবির মধ্যে সেই আপেক্ষিক এলাকাটি নির্ধারণ করে, যা ভিউ-এর বিষয়বস্তুগুলো দখল করতে পারবে।
চিত্র ১-এ একটি বাটন নির্ধারণ করতে ব্যবহৃত নাইনপ্যাচ গ্রাফিকের উদাহরণ দেখানো হয়েছে:

চিত্র ১: একটি বাটনকে সংজ্ঞায়িত করে এমন একটি নাইনপ্যাচ গ্রাফিকের উদাহরণ।
এই নাইনপ্যাচ গ্রাফিকটি বাম এবং উপরের লাইন দিয়ে একটি প্রসারণযোগ্য এলাকা এবং নিচের ও ডান লাইন দিয়ে অঙ্কনযোগ্য এলাকা নির্ধারণ করে। উপরের ছবিতে, ডটেড ধূসর লাইনগুলো ছবির সেই অঞ্চলগুলোকে চিহ্নিত করে যেগুলো ছবিটিকে প্রসারিত করার জন্য প্রতিলিপি করা হয়। নিচের ছবিতে গোলাপী আয়তক্ষেত্রটি সেই অঞ্চলকে চিহ্নিত করে যেখানে ভিউ-এর বিষয়বস্তুগুলো থাকতে পারে। যদি বিষয়বস্তুগুলো এই অঞ্চলে না ধরে, তবে সেগুলোকে আঁটানোর জন্য ছবিটি প্রসারিত করা হয়।
ড্র ৯-প্যাচ টুলটি একটি WYSIWYG গ্রাফিক্স এডিটর ব্যবহার করে আপনার নাইনপ্যাচ ইমেজ তৈরি করার একটি অত্যন্ত সুবিধাজনক উপায় প্রদান করে। এমনকি, পিক্সেল রেপ্লিকেশনের ফলে আপনার নির্ধারণ করা প্রসারণযোগ্য অঞ্চলে ড্রয়িং আর্টিফ্যাক্ট তৈরি হওয়ার ঝুঁকি থাকলে এটি সতর্কবার্তাও প্রদর্শন করে।
নিম্নলিখিত নমুনা লেআউট XML-টি দেখায় কিভাবে দুটি বাটনে একটি নাইনপ্যাচ গ্রাফিক যোগ করতে হয়। নাইনপ্যাচ ছবিটি res/drawable/my_button_background.9.png ফোল্ডারে সেভ করা হয়েছে।
<Button android:id="@+id/tiny" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentTop="true" android:layout_centerInParent="true" android:text="Tiny" android:textSize="8sp" android:background="@drawable/my_button_background"/> <Button android:id="@+id/big" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_centerInParent="true" android:text="Biiiiiiig text!" android:textSize="30sp" android:background="@drawable/my_button_background"/>
লক্ষ্য করুন যে, বাটনটিকে টেক্সটের চারপাশে সুন্দরভাবে ফিট করার জন্য layout_width এবং layout_height অ্যাট্রিবিউটগুলোকে wrap_content এ সেট করা হয়েছে।
চিত্র ২-এ উপরে দেখানো XML এবং NinePatch ইমেজ থেকে রেন্ডার করা দুটি বাটন দেখানো হয়েছে। লক্ষ্য করুন, কীভাবে টেক্সটের সাথে বাটনের প্রস্থ ও উচ্চতা পরিবর্তিত হয় এবং ব্যাকগ্রাউন্ড ইমেজটি সেটিকে জায়গা করে দেওয়ার জন্য প্রসারিত হয়।

চিত্র ২: একটি এক্সএমএল রিসোর্স এবং একটি নাইনপ্যাচ গ্রাফিক ব্যবহার করে রেন্ডার করা বাটনসমূহ
কাস্টম ড্রয়েবল
যখন আপনি নিজস্ব কোনো ড্রয়িং তৈরি করতে চান, তখন Drawable ক্লাস (বা এর যেকোনো সাবক্লাস) এক্সটেন্ড করে তা করতে পারেন।
প্রয়োগ করার জন্য সবচেয়ে গুরুত্বপূর্ণ পদ্ধতি হলো draw(Canvas) কারণ এটি আপনাকে সেই Canvas অবজেক্টটি প্রদান করে যা আপনার অঙ্কন নির্দেশাবলী দেওয়ার জন্য অবশ্যই ব্যবহার করতে হবে।
নিচের কোডটি Drawable এর একটি সাধারণ সাবক্লাস দেখাচ্ছে যা একটি বৃত্ত আঁকে:
কোটলিন
class MyDrawable : Drawable() { private val redPaint: Paint = Paint().apply { setARGB(255, 255, 0, 0) } override fun draw(canvas: Canvas) { // Get the drawable's bounds val width: Int = bounds.width() val height: Int = bounds.height() val radius: Float = Math.min(width, height).toFloat() / 2f // Draw a red circle in the center canvas.drawCircle((width / 2).toFloat(), (height / 2).toFloat(), radius, redPaint) } override fun setAlpha(alpha: Int) { // This method is required } override fun setColorFilter(colorFilter: ColorFilter?) { // This method is required } override fun getOpacity(): Int = // Must be PixelFormat.UNKNOWN, TRANSLUCENT, TRANSPARENT, or OPAQUE PixelFormat.OPAQUE }
জাভা
public class MyDrawable extends Drawable { private final Paint redPaint; public MyDrawable() { // Set up color and text size redPaint = new Paint(); redPaint.setARGB(255, 255, 0, 0); } @Override public void draw(Canvas canvas) { // Get the drawable's bounds int width = getBounds().width(); int height = getBounds().height(); float radius = Math.min(width, height) / 2; // Draw a red circle in the center canvas.drawCircle(width/2, height/2, radius, redPaint); } @Override public void setAlpha(int alpha) { // This method is required } @Override public void setColorFilter(ColorFilter colorFilter) { // This method is required } @Override public int getOpacity() { // Must be PixelFormat.UNKNOWN, TRANSLUCENT, TRANSPARENT, or OPAQUE return PixelFormat.OPAQUE; } }
তারপর আপনি আপনার ড্রয়েবলটি যেখানে খুশি যোগ করতে পারেন, যেমন এখানে দেখানো ImageView তে:
কোটলিন
val myDrawing = MyDrawable() val image: ImageView = findViewById(R.id.imageView) image.setImageDrawable(myDrawing) image.contentDescription = resources.getString(R.string.my_image_desc)
জাভা
MyDrawable mydrawing = new MyDrawable(); ImageView image = findViewById(R.id.imageView); image.setImageDrawable(mydrawing); image.setContentDescription(getResources().getString(R.string.my_image_desc));
অ্যান্ড্রয়েড ৭.০ (এপিআই লেভেল ২৪) এবং এর পরবর্তী সংস্করণগুলোতে, আপনি নিম্নলিখিত উপায়ে এক্সএমএল (XML) ব্যবহার করে আপনার কাস্টম ড্রয়েবলের ইনস্ট্যান্স তৈরি করতে পারেন:
- XML এলিমেন্টের নাম হিসেবে সম্পূর্ণ ক্লাস নামটি ব্যবহার করা। এই পদ্ধতির জন্য, কাস্টম ড্রয়েবল ক্লাসটি অবশ্যই একটি পাবলিক টপ-লেভেল ক্লাস হতে হবে:
<com.myapp.MyDrawable xmlns:android="http://schemas.android.com/apk/res/android" android:color="#ffff0000" />
- XML ট্যাগ নাম হিসেবে
drawableব্যবহার করে এবং `class` অ্যাট্রিবিউট থেকে সম্পূর্ণ-যোগ্য ক্লাসের নাম উল্লেখ করে। এই পদ্ধতিটি পাবলিক টপ-লেভেল ক্লাস এবং পাবলিক স্ট্যাটিক ইনার ক্লাস উভয়ের জন্যই ব্যবহার করা যেতে পারে:<drawable xmlns:android="http://schemas.android.com/apk/res/android" class="com.myapp.MyTopLevelClass$MyDrawable" android:color="#ffff0000" />
ড্রয়েবলগুলিতে টিন্ট যোগ করুন
অ্যান্ড্রয়েড ৫.০ (এপিআই লেভেল ২১) এবং তার উপরের সংস্করণগুলোতে, আপনি আলফা মাস্ক হিসেবে সংজ্ঞায়িত বিটম্যাপ এবং নাইন-প্যাচগুলোকে টিন্ট করতে পারেন। আপনি কালার রিসোর্স অথবা থিম অ্যাট্রিবিউটের মাধ্যমে এগুলোকে টিন্ট করতে পারেন, যা কালার রিসোর্সে রূপান্তরিত হয় (উদাহরণস্বরূপ, ?android:attr/colorPrimary )। সাধারণত, আপনি এই অ্যাসেটগুলো কেবল একবারই তৈরি করেন এবং এগুলো আপনার থিমের সাথে মিলিয়ে স্বয়ংক্রিয়ভাবে রঙিন হয়ে যায়।
আপনি setTint() মেথড ব্যবহার করে BitmapDrawable , NinePatchDrawable বা VectorDrawable অবজেক্টে টিন্ট প্রয়োগ করতে পারেন। এছাড়াও, আপনি android:tint এবং android:tintMode অ্যাট্রিবিউট ব্যবহার করে আপনার লেআউটে টিন্টের রঙ এবং মোড সেট করতে পারেন।
একটি ছবি থেকে প্রধান রঙগুলো বের করুন
অ্যান্ড্রয়েড সাপোর্ট লাইব্রেরিতে Palette ক্লাসটি রয়েছে, যা আপনাকে একটি ছবি থেকে প্রধান রঙগুলো বের করতে দেয়। আপনি আপনার ড্রয়েবলগুলোকে একটি Bitmap হিসেবে লোড করে তার রঙগুলো অ্যাক্সেস করার জন্য Palette এ পাস করতে পারেন। আরও তথ্যের জন্য, Palette API দিয়ে রঙ নির্বাচন করা পড়ুন।
