آموزش برنامه نویسی اندروید با اندروید استودیو (بخش پنجم: دسترسی و ساماندهی منابع در اندروید)

استاندارد

در این بخش از آموزش اندروید، می خواهیم به بررسی موضوعی با نام سازماندهی منابع (Resource) ها در اندروید بپردازیم؛

اما منظور از دسترسی و ساماندهی منابع چیست؟

دسترسی و ساماندهی منابع یعنی نوشتن یک برنامه کارآمدتر و مفید تر با استفاده از منابعی که در اختیار ما گذاشته شده است. درست است که کد یک برنامه خود عاملی مهم در کارآمد بودن برنامه است ولی استفاده از این منابع نیز به طرز چشمگیری این خاصیت را بهبود می بخشد.

اما منظور از این منابع چیست؟

این برنامه در واقع می توانند محتوای استاتیک مانند Bitmap، تعریف قالب ها، رنگ ها، انیمیشن ها، طراحی رابط کاربری و… می باشند.

این منابع همیشه جدا از بقیه و در زیرپوشه res/ از یک پروژه می باشند. در این آموزش قصد داریم تا نحوه استفاده از این منابع را به شما آموزش دهیم.

برای مثال شما در این کد، یک نوع ساختار و سازماندهی منابع را مشاهده می نمایید.

MyProject/
   app/
      manifest/
         AndroidManifest.xml
   java/
      MyActivity.java  
      res/
         drawable/  
            icon.png  
         layout/  
            activity_main.xml
            info.xml
         values/  
            strings.xml

در این پروژه ما در پوشه app و manifest یک فایل با نام androidmanifest.xml داریم. همچنین در پوشه منابع نیز، پوشه طراحی، پوشه قالب و.. وجود دارد که هرکدام فایلی را خود نگه داری می کنند.

پس این سوال پیش می آید که این پوشه ها چی هستند و چه چیزی در آن ها نگه داری میشود. جدول زیر به این سوال پاسخی مناسب می دهد.

anim/ فایل های xmlی در این پوشه وجود دارند که خاصیت انیمیشن ها را مشخص می کنند. این فایل ها توسط کلاس R.anime قابل دسترسی هستند.
color/ فایل های xmlی که در این پوشه وجود دارند ویژگی های رنگ ها را مشخص می کنند. این فایل ها توسط کلاس R.Color قابل دسترسی هستند.
drawable/ تصاویری با پسوند PNG , .JPG, .GIF یا فایل های xml ای که به bitmap ها ، state لیست ها ، شکل ها و انیمیشن های قابل ترسیم  (animation drawable) کامپایل میشن.این فایل ها در پوشه res/drawable ذخیره میشن و توسط کلاس R.drawable قابل دسترسی هستند.
layout/ فایل های xmlی که در این پوشه وجود دارند مربوط به ظاهر و طرحی بندی برنامه هستند و توسط کلاس R.Layout قابل دسترسی هستند.
menu/
فایل‌های XML از قبیل منوی گزینه‌ها، منوی متن یا منو فرعی که منوهای نرم‌افزار را مشخص می‌کنند در پوشه در پوشه res/menu/  ذخیره هستند و از طریق دسته R.menu قابلیت دسترسی دارند.
raw/
فایل های دلخواه برای ذخیره به شکل خام. برای این که به این فایل ها دسترسی داشته باشیم، باید تابع ()R.OpenRawResource را به همراه آرگومان شناسه منبع آن، که R.raw.filename است، فراخوانی نماییم.
values/ فایل های xmlی وجود دارند که در خود مقادیر ساده ای را ذخیره می کنند. این مقادیر ممکن است رشته ها، اعداد صحیح و رنگ باشند. این فایل ها باید در این پوشه نگه داری شوند.

بعضی از این منابع عبارت اند از:

array.xml: برای منابع آرایه ای بکار میره و توسط کلاس R.array میتونیم دسترسی بهش داشته باشیم.

integers.xml: برای ذخیره سازی منابع نوع عدد صحیح بکار میره و توسط کلاس R.integer قابل دسترسی هستند.

bools.xml: برای ذخیره منابع نوع بولین هست ، توسط کلاس R.bool میتونیم بهش دسترسی داشته باشیم.

color.xml: برای ذخیره مقادیر رنگی است که توسط کلاس R.color قابل دسترسی هست.

dimens.xml: برای ذخیره اندازه  و ابعادها به کار می رود که توسط کلاس R.dimen قابل دسترسی هست.

string.xml: برای داده های رشته ای هست و توسط کلاس R.string قابل دسترسی هست.

style.xml: برای ذخیره سازی استایل ها یا شیوه نامه ها هست که توسط کلاس R.xml قابل دسترسی هست.

xml/
فایل‌های دلخواه  XML که می‌توانند در زمان اجرا با فراخوانی Resources.getXML() خوانده شوند. می توان فایل‌های پیکربندی مختلفی را در این پوشه ذخیره کرد که در زمان اجرا استفاده خواهند شد.

منابع جایگزین (Alternative Resource)

اپلیکیشن شما باید منابع قابل جایگزین شدن داشته باشد. این منابع برای دستگاه های مختلف به کار می رود. برای مثال باید عکس هایی با قابلیت جایگزین شدن برای صفحاتی که رزولوشن آن ها متفاوت است داشته  باشیم.

همچنین منابع رشته ای جایگزین نیز میتوان داشت که این منابع برای مواقعی که بخواهیم اپلیکیشن ما از چند زبان پشتیبانی نماید، به کار می روند. در زمان اجرای برنامه، سیستم عامل اندروید، مشخصات کنونی دستگاه را شناسایی می کند تا منابع مناسب و درخور با آن را بارگذاری نماید.

چگونه منابع قابل جایگزین را تعریف نماییم؟

برای تعریف منابع قابل جایگزین، مراحل زیر را دنبال نمایید.

قدم اول:

یک پوشه ی جدید با نام <resources_name>-<config_qualifier> در داخل پوشه res/ می سازیم.

resources_name نام یکی از منابعی که در جدول بالا ذکر شد می باشد. مانند drawable, layout و…

qualifier نیز وظیفه ی پیکربندی هر کدام از این منابع را به عهده دارد.

شما میتونید اسناد رسمی که مربوط به لیست qualifier های مرتبط با منابع مختلف هست را بررسی کنید.

قدم دوم: 

منابع قابل جایگزینی که انتخاب نموده ایم را در این پوشه ذخیره می کنیم. اسم این منابع باید با هم یکسان باشند.  ولی محتوای این منابع با یکدیگر تفاوت دارند که همانطور که ذکر شد، سیستم عامل بسته به شرایط، یکی از این منابع را انتخاب می کند.

با یک مثال این روند را توضیح می دهیم. اگر دو عکس را به عنوان منابع قابل جایگزینی انتخاب کرده باشیم و تفاوت این دو عکس در رزولوشن آن ها باشد، سیستم عامل اندروید در دستگاهی که رزولوشن آن بالاست عکس با رزولوشن بالاتر را انتخاب و در دستگاهی که رزولوشن آن پایین است، عکس با رزولوشن پایین تر را انتخاب می نماید.

می توانید ساختار این مثال را در این جا مشاهده نمایید.

MyProject/
   app/
      manifest/
         AndroidManifest.xml
   java/
      MyActivity.java   
         res/
            drawable/  
               icon.png
               background.png
         drawable-hdpi/  
            icon.png
            background.png  
         layout/  
            activity_main.xml
            info.xml
         values/  
            strings.xml

همان طور که در ساختار بالا مشاهده می نمایید، دو نوع پوشه با منبع drawable وجود دارد که hdpi توصیف کننده پوشه ی دوم است. در هر پوشه دو عکس به نام های icon.png و background.png وجود دارد. از پوشه ی دوم می توان فهمید که عکس های آن برای رزولوشن بالاتر انتخاب شده است. همچنین با کمی دقت می توان دریافت که نام هر دو عکس متناظر در پوشه ها کاملا یکسان است.

در زیر مثال دیگری آورده شده است. در این مثال یک Layout بعنوان پیش فرض برای ما تعریف می شود. یک Layout هم برای این تعریف کردیم که اگر زبان گوشی کاربر عربی بود بجای Layout پیش فرض، بارگذاری شود.

MyProject/
   app/
      manifest/
         AndroidManifest.xml
   java/
      MyActivity.java   
      res/
         drawable/  
            icon.png
            background.png
         drawable-hdpi/  
            icon.png
            background.png  
         layout/  
            activity_main.xml
            info.xml
         layout-ar/
            main.xml
         values/  
            strings.xml

دسترسی به منابع

هنگامی که در حال توسعه اپلیکیشن اندرویدی خود می باشیم، نیاز داریم که منابعی که می خواهیم را در کدهایمان تعریف نماییم.

مثال های زیر به شما نشان خواهد داد که چگونه این کار را انجام دهید.

1- دسترسی به منابع در نوشتن کدها

زمانی که اپلیکیشن اندروید کامپایل می شود، یک کلاس R به طور خودکار تولید می شود. این کلاس همه ی شناسه (ID) های منابع را که در پوشه ی res/ می باشد، شامل می باشد.

حال شما می توانید با استفاده از این کلاس به سه روش به منبع مورد نظر، در کد ها دسترسی داشته باشیم.

این سه مورد عبارت اند از:

  1. به کار بردن کلاس R به همراه نام منبع مورد نظر ( شبیه چیزی که در جدول توضیح داده شد)
  2. به کار بردن کلاس R به همراه ID منبع مورد نظر
  3. به کار بردن کلاس R به همراه نام پوشه دلخواه

ابتدا در مورد روش اول، یعنی به کاربردن کلاس R به همراه نام منبع مورد نظر صحبت می کنیم.

فرض کنید که یک فایل رشته ای Strings.xml در مسیر دایرکتوری res/values/strings.xml و با محتویات زیر داریم.

<?xml version="1.0" encoding="utf-8"?>
<resources>
   <string  name="hello">Hello, World!</string>
</resources>

حال شما می توانید با استفاده از کد زیر منبعی که id اون msg هست را از فایل srting.xml بگیرید و اون رو بعنوان خاصیت Text یک TextView ست می کنیم

TextView msgTextView = (TextView) findViewById(R.id.msg);
msgTextView.setText(R.string.hello);

حال در مورد روش دوم یعنی به کار بردن کلاس R با استفاده از ID مورد نظر صحبت می کنیم.

برای دسترسی به عکس  myimage که در داخل دایرکتوری res/drawable/myimage.png می باشد و ست کردن آن به یک ImageView مثال زیر را مشاهده کنید.

ImageView imageView = (ImageView) findViewById(R.id.myimageview);
ImageView.setImageResource(R.drawable.myimage);

در  خط اول با استفاده از  R.id.myimageview به یک المنت imageview با آیدی myimageview را از فایل  layout اشاره می کنیم.
در خط دوم از R.drawable.myimage برای تنظیم کردن یک عکس با نام myimage که مکانش در زیرپوشه /res هست استفاده کرده ایم.

و در آخر در مورد به کاربردن کلاس R به همراه نام پوشه مورد نظر صحبت می کنیم.

فرض کنید یک Layout با محتویات زیر در مسیر دایرکتوری res/layout/activity_main.xml داریم:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
   android:layout_width="fill_parent" 
   android:layout_height="fill_parent" 
   android:orientation="vertical" >

   <TextView android:id="@+id/text"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:text="Hello, I am a TextView" />

   <Button android:id="@+id/button"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:text="Hello, I am a Button" />

</LinearLayout>

کد برنامه ای که در زیر مشاهده می نمایید، یک Layout که در بالا مشاهده نمودیم را برای یک Activity در متد ()onCreate باز می کند.

public void onCreate(Bundle savedInstanceState){
   super.onCreate(savedInstanceState);
   setContentView(R.layout.main_activity);
}

2- دسترسی به منابع در XML

فرض کنید که یک فایل رشته ای Strings.xml در مسیر دایرکتوری res/values/strings.xml که شامل منابع رنگ و رشته ای است و با محتویات زیر داریم:

<?xml version="1.0" encoding="utf-8"?>
<resources>
   <color name="opaque_red">#f00</color>
   <string name="hello">Hello!</string>
</resources>

حال با استفاده از کد های زیر می توانیم رنگ و رشته ی یک متن را تنظیم نماییم:

<?xml version="1.0" encoding="utf-8"?>
<EditText xmlns:android="http://schemas.android.com/apk/res/android"
   android:layout_width="fill_parent"
   android:layout_height="fill_parent"
   android:textColor="@color/opaque_red"
   android:text="@string/hello" />

اگر به بخش سوم رفته و مثال سلام GSM را مشاهده نمایید، با بررسی آن چیزهای بیشتری را متوجه خواهید شد. پس توصیه می کنیم که حتما به آن بخش رفته و کد های آن را بررسی نمایید.