در این پست به مفاهیم کامل پیکسل (Pixel)، واحد dp و sp خواهیم پرداخت. خواندن این مقاله برای توسعهدهندگان اندروید در هر سطحی و همچین طراحان گرافیکی که قصد تولید محتوی برای این پلتفرم دارند توصیه میشود. در هنگام کار با اکثر همکاران عدم درک اولیه از برخی موارد در اندروید برای من بسیار تعجب برانگیز است! به همین دلیل در هر پست هدف من درک موارد مهم و تمرین کردن آن با شما است تا بتوانید با خواندن مقالات رسمی و قدرت ذهنی خود آن را گسترش دهید و پیادهسازی کنید.
نسخه انگلیسی مقاله:
تمامی صفحات نمایش که اطلاعات بر روی آن نمایش داده میشود، از اجزای ریز مربع شکل به نام پیکسل تشکیل شدهاند. بزرگی یا کوچکی این واحدها به تعداد پیکسلها و اندازه صفحه نمایش مرتبط است، اگر غیر این است چگونه صفحه نمایش یک موبایل با رزولوشن 1080x1920 با صفحه نمایش یک کامپیتور خانگی با رزولوشن 1920x1080 هر دو دارای تعداد پیکسلهای یکسانی هستند؟ این دو صفحه دارای اندازه متفاوت پیکسل و در نتیجه غلظتهای مختلف پیکسلی هستند.
منظور از رزولوشن (Resolution) چیست؟
به تصویر زیر توجه کنید:
عرض این مربع 4 پیکسل کشیده و طول آن 4 پیکسل کشیده میباشد و مجموعا دارای 16 پیکسل میباشد، به دو عدد 4x4 میزان رزولوشن آن گفته میشود.
منظور از غلظت (Density) چیست؟
غلظت نمایش دهنده میزان وجود چیزی در فضای مشخص میباشد.
در مبحث کار با صفحههای نمایش ما از واحد پیکسل در هر (یک) اینچ (Pixel Per Inch) استفاده میکنیم.
پیکسل در (یک) اینچ با نماد ppi نمایش داده میشود ولی در پلتفرم اندروید از نماد dpi که به معنای نقطه در هر اینچ (dots per inch) است، استفاده میشود. پیکسل مربع است و نقطه نیست، دلیل استفاده از این نماد کمی عجیب است، دوستانی که Photoshop کار کردن با نماد ppi آشنا هستند.
گوشی خود را برای یافتن مواردی که در بالا گفته شد آماده کنید. در این آموزش من از دستگاه فیزیکی خود با مشخصات زیر استفاده میکنم:
Galaxy A5 2017 Screen Resolution: 1080x1920 Physical Size: 5.2 inch
طبق قوانین فیثاغورث برای محاسبه تعداد پیکسلهای موجود بر روی خط فرضی 5.2 اینچی داریم:
c = ~ 2200 (تعداد پیکسلها بر روی خط 5.2 اینچی) 2200 / 5.2 = ~ 424 dpi (غلظت دستگاه)
در این قسمت میخواهیم دکمهای که را بر روی دو صفحه نمایش مختلف با غلظتهای متفاوت ولی رزولوشن یکسان نمایش دهیم:
حجم دکمه بر روی مربع راست کمتر از دکمه سمت چپ میباشد. اگر مربع ما کوچکتر از قبل شود نتیجه چه خواهد شد؟ آیا کاربر میتواند به راحتی بر روی آن کلیک کند؟ برای حل این مشکل از واحدی برای ثابت نگه داشتن حجم دکمه و هر View دیگری بر روی اندروید استفاده میکنیم که به غلظت پیکسلی توجهی ندارد:
dp/dip = density-independent pixel = پیکسل فارغ از غلظت
sp = scale-independent pixel = پیکسل فارغ از تناسب
واحد dp که برای تمامی View ها استفاده میشود توسط فرمول زیر محاسبه میشود:
dp = px * (160 / dpi)
دلیل وجود عدد 160 در این معادله چیست؟
در اندروید 160 غلظت پیکسلی است که در آن هر یک پیکسل برابر یک dp میباشد. به این عدد غلظت پایه هم گفته میشود.
واحد sp چیست؟
این واحد دقیقا همانند dp میباشد ولی فقط برای سایز نوشتهها در اندروید استفاده میشود، تنها تفاوت آن با dp این است که اگر کاربر در تنظیمات گوشی خود سایز نوشتههای سیستم عامل را تغییر داده باشد در اپلیکیشن شما هم اعمال خواهد شد.
با فرض اینکه مربع راست دارای غلظت پیکسلی 320 و مربع سمت چپ دارای غلظت پیکسلی 160 میباشند با جایگذاری عدد 1dp در معامله میزان پیکسل مورد نیاز بر روی هر صفحه نمایش برای ثابت نگه داشتن سایز دکمه را محاسبه میکنیم:
مربع سمت راست:
1dp = 2px => (2x2) px * 2 = (4x4) px سایز دکمه
مربع سمت چپ:
1dp = 1px => (2x2) px * 1 = (2x2) px سایز دکمه
با توجه به نتیجه به دست آمده متوجه میشویم که با افزایش غلظت پیکسلی بر روی صفحه نمایش تعداد پیکسلهای Image یا View مورد نظر افزایش مییابد تا بر روی همه صفحات نمایش اندازه یکسانی داشته باشیم.
برای نمایش یک عکس با رزولوشن 4x2 با نتیجه زیر رو به رو خواهیم شد:
طراحان همیشه با واحد پیکسل تصاویر را تولید و برای شما ارسال میکنند. برای حل این مشکل اندروید برای ثابت نگه داشتن حجم تصاویر از پوشههایی استفاده میکند که دارای غلظت پیکسلهای متفاوتی هستند:
تصاویر همیشه در پوشه drawable قرار میگیرند، برای ساخت این پوشه با غلظتهای متفاوت موارد بالا را به عنوان پسوند آن اضافه میکنیم، مثلا drawable-xhdpi
معنای این پوشهها چیست؟
با قرار دادن تصویر خود در این پوشهها به اندروید اعلام میکنید من سایز تصویر خودم را با توجه به غلظت مورد نظر تغییر دادهام و لطفا هنگام استفاده از تصویر آن را از نظر اندازه تغییر نده!
اگر من عکسی با سایز 24x24 پیکسل در mdpi قرار دهم پس باید در سایر پوشهها:
اگر فقط تصویر خودم را در پوشه mdpi قرار دهم چه اتفاقی میافتد؟
اگر تصویر خود را در یکی از پوشهها قرار ندهید از نزدیکترین پوشه دریافت و تغییر سایز داده میشود.
فرآیند تغییر سایز شامل عملیات زمانبر و همچنین احتمال کاهش کیفیت عکس میشود، سعی کنید تصاویر خود را برای همه پوشهها آماده کنید.
اگر عکس 24x24 خود را در پوشه mdpi قرار دهم و گوشی کاربری دارای غلظت xhdpi باشد، سیستم عامل با تکنیکهای پردازش تصویر تعداد پیکسلهای آن را به 48x48 میرساند.
پوشه drawable خام نیز همانند drawable-mdpi دارای غلظت پایه (160dpi) میباشد.
اگر تصویر خود را فقط در پوشه nodpi قرار دهم چه اتفاقی خواهد افتاد؟
تصاویری که در این پوشه قرار دارند به همان سایز پیکسلی وارد برنامه خواهند شد، برای جلوگیری از ارور معروف OutOfMemory بهتر است که قبل از وارد کردن تصویر به مموری آن را تغییر اندازه دهید.
در پشت غلظت پیکسلی هر پوشه علامتی با نشان ~ دیده میشود و به این معناست که این اعداد حدودی میباشند، دستگاه شما ممکن است عددی نزدیک به این غلظتها داشته باشد. این که تصویر مورد نظر برای دستگاه شما از کدام پوشه دریافت میشود بستگی به نظر سازنده دستگاه دارد، مثلا اگر غلظت پیکسلی شما برابر 390 باشد ممکن است در زمره پوشه xhdpi یا xxhdpi قرار بگیرید و میزان scale شدن تصویر هم عددی به غیر از اعداد داده شده باشد.
val density = resources.displayMetrics.density val densityDpi = resources.displayMetrics.densityDpi val heightPixels = resources.displayMetrics.heightPixels val widthPixels = resources.displayMetrics.widthPixels val scaledDensity = resources.displayMetrics.scaledDensity