یک نمای سفارشی با طراحی خوب مانند هر کلاس خوب طراحی شده دیگری است. این کلاس مجموعهای از قابلیتها را با یک رابط کاربری ساده کپسولهسازی میکند، از CPU و حافظه به طور کارآمد استفاده میکند و غیره. علاوه بر اینکه یک کلاس با طراحی خوب است، یک نمای سفارشی باید موارد زیر را نیز انجام دهد:
- مطابق با استانداردهای اندروید
- ویژگیهای قابل تنظیم سفارشی ارائه دهید که با طرحبندیهای XML اندروید کار میکنند.
- ارسال رویدادهای دسترسیپذیری
- با چندین پلتفرم اندروید سازگار باشد.
چارچوب اندروید مجموعهای از کلاسهای پایه و تگهای XML را فراهم میکند تا به شما در ایجاد نمایی که تمام این الزامات را برآورده میکند، کمک کند. این درس نحوه استفاده از چارچوب اندروید برای ایجاد قابلیتهای اصلی یک کلاس نما را مورد بحث قرار میدهد.
میتوانید اطلاعات بیشتر را در Custom view components بیابید.
یک زیرکلاس از یک نما
تمام کلاسهای view تعریف شده در فریمورک اندروید، View را ارثبری میکنند. view سفارشی شما همچنین میتواند مستقیماً View ارثبری کند، یا میتوانید با ارثبری از یکی از زیرکلاسهای view موجود، مانند Button ، در زمان صرفهجویی کنید.
برای اینکه اندروید استودیو بتواند با نمای شما تعامل داشته باشد، حداقل باید یک سازنده (constructor) ارائه دهید که یک Context و یک شیء AttributeSet را به عنوان پارامتر دریافت کند. این سازنده به ویرایشگر طرحبندی (layout editor) اجازه میدهد تا نمونهای از نمای شما را ایجاد و ویرایش کند.
کاتلین
class PieChart(context: Context, attrs: AttributeSet) : View(context, attrs)
جاوا
class PieChart extends View { public PieChart(Context context, AttributeSet attrs) { super(context, attrs); } }
تعریف ویژگیهای سفارشی
برای افزودن یک View داخلی به رابط کاربری خود، آن را در یک عنصر XML مشخص کنید و ظاهر و رفتار آن را با ویژگیهای عنصر کنترل کنید. همچنین میتوانید نماهای سفارشی را با استفاده از XML اضافه و سبکبندی کنید. برای فعال کردن این رفتار در نمای سفارشی خود، موارد زیر را انجام دهید:
- ویژگیهای سفارشی را برای نمای خود در یک عنصر منبع
<declare-styleable>تعریف کنید. - مقادیر مربوط به ویژگیها را در طرح XML خود مشخص کنید.
- بازیابی مقادیر ویژگیها در زمان اجرا.
- مقادیر ویژگی بازیابی شده را به نمای خود اعمال کنید.
این بخش به نحوه تعریف ویژگیهای سفارشی و تعیین مقادیر آنها میپردازد. بخش بعدی بازیابی و اعمال مقادیر در زمان اجرا را پوشش میدهد.
برای تعریف ویژگیهای سفارشی، منابع <declare-styleable> را به پروژه خود اضافه کنید. مرسوم است که این منابع را در فایل res/values/attrs.xml قرار دهید. در اینجا مثالی از فایل attrs.xml آورده شده است:
<resources> <declare-styleable name="PieChart"> <attr name="showText" format="boolean" /> <attr name="labelPosition" format="enum"> <enum name="left" value="0"/> <enum name="right" value="1"/> </attr> </declare-styleable> </resources>
این کد دو ویژگی سفارشی، showText و labelPosition ، را تعریف میکند که متعلق به یک موجودیت قابل استایلدهی به نام PieChart هستند. نام موجودیت قابل استایلدهی، طبق قرارداد، همان نام کلاسی است که نمای سفارشی را تعریف میکند. اگرچه پیروی از این قرارداد ضروری نیست، بسیاری از ویرایشگرهای کد محبوب برای تکمیل دستورات به این قرارداد نامگذاری وابسته هستند.
پس از تعریف ویژگیهای سفارشی، میتوانید از آنها در فایلهای XML طرحبندی درست مانند ویژگیهای داخلی استفاده کنید. تنها تفاوت این است که ویژگیهای سفارشی شما به یک فضای نام متفاوت تعلق دارند. به جای تعلق به فضای نام http://schemas.android.com/apk/res/android ، آنها به http://schemas.android.com/apk/res/[your package name] تعلق دارند. برای مثال، در اینجا نحوه استفاده از ویژگیهای تعریف شده برای PieChart آمده است:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:custom="http://schemas.android.com/apk/res-auto"> <com.example.customviews.charting.PieChart custom:showText="true" custom:labelPosition="left" /> </LinearLayout>
برای جلوگیری از تکرار آدرس اینترنتی فضای نام طولانی، این نمونه از یک دستورالعمل xmlns استفاده میکند. این دستورالعمل، نام مستعار custom را به فضای نام http://schemas.android.com/apk/res/com.example.customviews اختصاص میدهد. شما میتوانید هر نام مستعاری را که میخواهید برای فضای نام خود انتخاب کنید.
به نام تگ XML که نمای سفارشی را به طرحبندی اضافه میکند، توجه کنید. این نام، نام کامل کلاس نمای سفارشی است. اگر کلاس نمای شما یک کلاس داخلی است، آن را با نام کلاس بیرونی نما، توصیف کنید. برای مثال، کلاس PieChart یک کلاس داخلی به نام PieView دارد. برای استفاده از ویژگیهای سفارشی این کلاس، از برچسب com.example.customviews.charting.PieChart$PieView استفاده میکنید.
اعمال ویژگیهای سفارشی
وقتی یک نما (view) از یک طرحبندی XML ایجاد میشود، تمام ویژگیهای موجود در تگ XML از بسته منابع (resource bundle) خوانده شده و به عنوان یک AttributeSet به سازنده نما (view constructor) ارسال میشوند. اگرچه میتوان مقادیر را مستقیماً از AttributeSet خواند، اما انجام این کار معایبی دارد:
- ارجاعات منابع درون مقادیر ویژگیها برطرف نمیشوند.
- استایلها اعمال نمیشوند.
در عوض، AttributeSet به obtainStyledAttributes() ارسال کنید. این متد یک آرایه TypedArray از مقادیری را که از قبل ارجاعزدایی و استایلدهی شدهاند، برمیگرداند.
کامپایلر منابع اندروید کارهای زیادی برای شما انجام میدهد تا فراخوانی تابع obtainStyledAttributes() را آسانتر کند. برای هر منبع <declare-styleable> در دایرکتوری res/ ، R.java تولید شده، هم آرایهای از شناسههای ویژگی و هم مجموعهای از ثابتها را تعریف میکند که اندیس هر ویژگی را در آرایه تعریف میکنند. شما از ثابتهای از پیش تعریف شده برای خواندن ویژگیها از TypedArray استفاده میکنید. در اینجا نحوه خواندن ویژگیهای کلاس PieChart توسط آن آمده است:
کاتلین
init { context.theme.obtainStyledAttributes( attrs, R.styleable.PieChart, 0, 0).apply { try { mShowText = getBoolean(R.styleable.PieChart_showText, false) textPos = getInteger(R.styleable.PieChart_labelPosition, 0) } finally { recycle() } } }
جاوا
public PieChart(Context context, AttributeSet attrs) { super(context, attrs); TypedArray a = context.getTheme().obtainStyledAttributes( attrs, R.styleable.PieChart, 0, 0); try { mShowText = a.getBoolean(R.styleable.PieChart_showText, false); textPos = a.getInteger(R.styleable.PieChart_labelPosition, 0); } finally { a.recycle(); } }
توجه داشته باشید که اشیاء TypedArray یک منبع مشترک هستند و پس از استفاده باید بازیافت شوند.
افزودن ویژگیها و رویدادها
ویژگیها روشی قدرتمند برای کنترل رفتار و ظاهر نماها هستند، اما فقط زمانی قابل خواندن هستند که نما مقداردهی اولیه شده باشد. برای ارائه رفتار پویا، برای هر ویژگی سفارشی، یک جفت getter و setter ویژگی را نمایش دهید. قطعه کد زیر نشان میدهد که چگونه PieChart ویژگیای به نام showText را نمایش میدهد:
کاتلین
fun isShowText(): Boolean { return mShowText } fun setShowText(showText: Boolean) { mShowText = showText invalidate() requestLayout() }
جاوا
public boolean isShowText() { return mShowText; } public void setShowText(boolean showText) { mShowText = showText; invalidate(); requestLayout(); }
توجه داشته باشید که setShowText تابعهای invalidate() و requestLayout() را فراخوانی میکند. این فراخوانیها برای اطمینان از عملکرد قابل اعتماد نما بسیار مهم هستند. شما باید نما را پس از هرگونه تغییر در ویژگیهای آن که ممکن است ظاهر آن را تغییر دهد، نامعتبر کنید تا سیستم بداند که نیاز به ترسیم مجدد دارد. به همین ترتیب، اگر یک ویژگی به گونهای تغییر کند که ممکن است بر اندازه یا شکل نما تأثیر بگذارد، باید طرحبندی جدیدی درخواست کنید. فراموش کردن این فراخوانیهای متد میتواند باعث ایجاد اشکالاتی شود که به سختی میتوان آنها را پیدا کرد.
نماهای سفارشی همچنین باید از شنوندههای رویداد (event listeners) برای برقراری ارتباط بین رویدادهای مهم پشتیبانی کنند. برای مثال، PieChart یک رویداد سفارشی به نام OnCurrentItemChanged را نمایش میدهد تا به شنوندهها اطلاع دهد که کاربر نمودار دایرهای را چرخانده تا روی یک برش جدید دایرهای تمرکز کند.
فراموش کردن افشای ویژگیها و رویدادها، به خصوص زمانی که شما تنها کاربر نمای سفارشی هستید، آسان است. صرف وقت برای تعریف دقیق رابط کاربری نمای خود، هزینههای نگهداری آینده را کاهش میدهد. یک قانون خوب که باید رعایت کنید این است که همیشه هر ویژگیای را که بر ظاهر یا رفتار قابل مشاهده نمای سفارشی شما تأثیر میگذارد، افشا کنید.
طراحی برای دسترسیپذیری
نمای سفارشی شما باید طیف وسیعی از کاربران را پشتیبانی کند. این شامل کاربرانی با معلولیتهایی میشود که مانع از دیدن یا استفاده از صفحه لمسی میشوند. برای پشتیبانی از کاربران دارای معلولیت، موارد زیر را انجام دهید:
- فیلدهای ورودی خود را با استفاده از ویژگی
android:contentDescriptionبرچسبگذاری کنید. - رویدادهای دسترسیپذیری را با فراخوانی
sendAccessibilityEvent()در صورت لزوم ارسال کنید. - از کنترلرهای جایگزین، مانند D-pad یا trackball، پشتیبانی کنید.
برای اطلاعات بیشتر در مورد ایجاد نماهای قابل دسترس، به «دسترسیپذیرتر کردن برنامهها» مراجعه کنید.
