আপনার কাস্টম ভিউ যথাযথভাবে ড্র করার জন্য আপনার জানা প্রয়োজন এর সাইজটা কি রকম। জটিল কাস্টম বিউকে মাঝে মাঝে মাল্টিপল লেআউট ক্যালকুলেশন করতে হয় যা নির্ভর করে স্ক্রিন এলাকায় এর সাইজ এবং কাঠামোর উপর। আপনার কখনই স্ক্রিনে আপনার ভিউয়ের সাইজ অনুমান করা উচিত নয়। এমনকি যদি শুধূমাত্র একটি অ্যাপ আপনার ভিউ ব্যবহার করতে থাকে, ঐ অ্যাপকে ভিন্ন স্ক্রিন সাইজ, মাল্টিপল স্ক্রিন ডেনজিটি এবং ল্যান্ডস্কেপে এবং পোট্রেইট উভয় মোডে বিভিন্ন আসপেক্ট রেশিও চালিত করার প্রয়োজন হয়।
যদিও View'র পরিমাপ করার পদ্ধতি আছে, তার অধিকাংশেরই ওভাররাইড করার কোন প্রয়োজন নেই। যদি আপনার ভিউয়ের এর সাইজের উপর বিশেষ নিয়ন্ত্রণের কোন প্রয়োজন না থাকে, আপনাকে শুধুমাত্র একটি পদ্ধতি ওভাররাইড করতে হবে: onSizeChanged()।
onSizeChanged()কে কল করা হয় যখন আপনার ভিউ একটিসাইজে স্থপিত হয় এবং আরেক কল করা হয় যখন আপনার ভিউ সাইজ কোন কারনে পরিবর্তন হয়। প্রতিবার ড্র করার সময় গুলোকে ক্যালকুলেট করার পরিবর্তে, আপনার ভিউয়ের onSizeChanged()এর সাথে সম্পর্কিত অবস্থান, ডাইমেনশন এবং অন্য কোন ভ্যালু ক্যালকুলেট করুন। PieChart নমুনায়, onSizeChanged()হচ্ছে কোথায় পাইচার্ট ভিউ এর বাউন্ডিং (সীমা নির্ধারিত) রেকটাঙ্গেল (আয়তক্ষেত্র) ক্যালকুলেট করে এবং টেক্সট লেবেলের প্রাসঙ্গিক পজিশন (অবস্থান) এবং অন্য ভিজ্যুয়াল উপাদান কে ক্যালকুলেট করে।
যখন আপনার ভিউ একটি সাইজে আবদ্ধ হয়, লেআউট ম্যানেজার মনে করে যে সাইজটি ভিউয়ের সকল প্যাডিং অন্তর্ভূক্ত করেছে। আপনাকে অবশ্যই প্যাডিং ভ্যালু ব্যবস্থাপনা করতে হবে যখন আপনি আপনার ভিউয়ের সাইজ ক্যালকুলেট করবেন। এখানে PieChart.onSizeChanged()থেকে একটি কোড অংশ দেয়া আছে, যা দেখায় কীভাবে এটাকরতে হয়।
// Account for padding
float xpad = (float)(getPaddingLeft() + getPaddingRight());
float ypad = (float)(getPaddingTop() + getPaddingBottom());
// Account for the label
if (mShowText) xpad += mTextWidth;
float ww = (float)w - xpad;
float hh = (float)h - ypad;
// Figure out how big we can make the pie.
float diameter = Math.min(ww, hh);
আপনার যদি আপনার ভিউয়ের লেআউট প্যারামিটারের উপর ভালো রকম নিয়ন্ত্রন প্রযোজন হয়, onMeasure()বাস্তবায়ন করুন। এই পদ্ধতির প্যারামিটার হচ্ছে View.MeasureSpec ভ্যালু যা আপনাকে জানায় আপনার ভিউয়ের প্যারেন্ট ভিউটিকে কতবড় দেখতে চায়, এবং ঐ সাইজ সর্বোচ্চ কিনা নাকি শুধুমাত্র একটি পরামর্শ। একটি অপটিমাইজেশন হিসাবে এই ভ্যালুগুলো প্যাক করা ইনটিজার হিসাবে স্টোর হয় এবং আপনি প্রতিটা ইনটিজারে প্যাক করা তথ্য আনপ্যাক করতে View.MeasureSpec এর স্ট্যাটিক পদ্ধতি ব্যবহার করেন।
এখানে onMeasure()এর একটি নমুনা বাস্তবায়ন দেখনো হলো। এই বাস্তবায়নে, চরবঈযধৎঃ এর লেবেলের মতো পাইকে বড় করতে এর এলাকাকে ততটুকু বড় করে:
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// Try for a width based on our minimum
int minw = getPaddingLeft() + getPaddingRight() + getSuggestedMinimumWidth();
int w = resolveSizeAndState(minw, widthMeasureSpec, 1);
// Whatever the width ends up being, ask for a height that would let the pie
// get as big as it can
int minh = MeasureSpec.getSize(w) - (int)mTextWidth + getPaddingBottom() + getPaddingTop();
int h = resolveSizeAndState(MeasureSpec.getSize(w) - (int)mTextWidth, heightMeasureSpec, 0);
setMeasuredDimension(w, h);
}
এই কোডে উল্লেখ করার মতো তিনটা গুরুত্বপূর্ন বিষয় আছে:
ভিউয়ের প্যাডিংয়ে ক্যালকুলেশন বিবেচনায় আনা হয়। পূর্বে যেভাবে উল্লেখ করা হয়েছে, এটা ভিউয়ের দায়িত্ব।
হেল্পার পদ্ধতি resolveSizeAndState() চুড়ান্ত প্রস্থ এবং উচ্চতা ভ্যালু তৈরী করতে ব্যবহৃত হয়। এই হেল্পার onMeasure()এর মধ্যে পাস spec এ ভিউয়ের কাঙ্খিত সাইজে এর সাথে তুলনা করার মাধ্যমে একটি যথাযথ Vie.MeasureSpec ভ্যালু ফেরত আনে।
onMeasure()এর কোন রিটার্ন ভ্যালু নেই। পরিবর্তে পদ্ধতি setMeasuredDimension()কল করার মাধ্যমে এর রেজাল্টের সাথে যোগযোগ করে। এই পদ্ধতি কল করা বাধ্যতামূলক। যদি আপনি এই কল বাদ দেন, View ক্লাস একটি রানটাইম এক্সেপশন (বর্জন/বর্জ্য) নির্গত করে।