Path — کلاس android.graphics برای ایجاد و ذخیره خطوط وکتوری با شکل دلخواه است. این کلاس دنبالهای از نقاط، خطوط و منحنیهای هندسی را توصیف میکند که Canvas آنها را به پیکسلهای قابل مشاهده تبدیل میکند. Path از خطوط مستقیم، منحنیهای درجه دوم و مکعب Bézier، کمانها و اشکال بسته پشتیبانی میکند. به گفته Google Developers, 2026، Path در 78% از Viewهای سفارشی برای ساخت گرافیک غیرپیشفرض استفاده میشود.
نکات اصلی
Path — کلاسی از بسته android.graphics است که دنبالهای از بخشهای مسیر را نشان میدهد: خطوط مستقیم، منحنیهای درجه دوم و مکعب Bézier، کمانهای دایره و بیضی. برخلاف تصاویر شطرنجی، Path فقط توصیف ریاضی خط را ذخیره میکند که امکان مقیاسپذیری بدون افت کیفیت را فراهم میکند. اندازه شیء Path در حافظه متناسب با تعداد بخشها است، نه با وضوح صفحه.
Path در ارتباط نزدیک با Canvas و Paint کار میکند. Canvas.drawPath(path, paint) خط آماده را میگیرد و آن را مطابق با سبکهای Paint نمایش میدهد. این جداسازی امکان ساخت یک بار خط پیچیده و رسم مکرر آن با سبکهای مختلف — رنگ، ضخامت خط یا گرادیان — را فراهم میکند. به گفته Google I/O 2023، استفاده مجدد از Path زمان رسم Viewهای سفارشی را 25-40% کاهش میدهد.
هر Path از دنبالهای از نقاط و انواع بخشها تشکیل شده است. نقاط در سیستم مختصات Canvas تعیین میشوند، جایی که محور X به سمت راست و محور Y به سمت پایین است. نقطه شروع خط با روش moveTo تنظیم میشود، پس از آن هر بخش بعدی نسبت به نقطه قبلی اضافه میشود. تمام عملیات ساخت روی CPU انجام میشود و تا لحظه رسم به GPU نیاز ندارد.
روش moveTo قلم را بدون رسم خط به نقطه مشخص شده منتقل میکند. این روش موقعیت شروع را برای بخش بعدی تعیین میکند. بدون moveTo، نقطه شروع Path به طور پیشفرض در (0, 0) است. برای هر خط پیوسته جدید یک moveTo جداگانه لازم است — این رویکرد استاندارد برای رسم چندین خط مستقل در یک Path است.
lineTo یک بخش مستقیم از موقعیت فعلی قلم تا نقطه مشخص شده اضافه میکند. پس از فراخوانی lineTo، موقعیت فعلی به نقطه پایان بخش منتقل میشود. دنبالهای از فراخوانیهای lineTo یک خط شکسته — چندخطی — ایجاد میکند. برای بستن خط از روش close استفاده میشود که یک خط مستقیم از آخرین نقطه به نقطه شروع آخرین moveTo میکشد.
rLineTo و rMoveTo — نسخههای نسبی روشها هستند. آنها به جای مختصات مطلق، جابهجاییهای dx و dy را از موقعیت فعلی میپذیرند. rLineTo برای ساخت اشکال با مراحل تکراری، مانند شبکهها و گریدها، راحت است. روشهای نسبی هنگام جابهجایی کل خط نیازی به محاسبه مجدد مختصات مطلق ندارند.
val path = Path().apply {
moveTo(100f, 100f) // نقطه شروع A
lineTo(300f, 100f) // A ← B
lineTo(200f, 250f) // B ← C
close() // C ← A (بسته شدن)
}
quadTo یک منحنی درجه دوم Bézier با یک نقطه کنترل اضافه میکند. منحنی درجه دوم با سه نقطه تعیین میشود: شروع (موقعیت فعلی)، کنترل (خمیدگی را تعیین میکند) و پایان. نقطه کنترل روی منحنی قرار ندارد، اما جهت مماسها را در نقاط شروع و پایان تعیین میکند. این نوع منحنی برای گردسازیهای ساده و انتقالهای نرم استفاده میشود.
cubicTo یک منحنی مکعب Bézier با دو نقطه کنترل اضافه میکند که انعطاف بیشتری در شکلدهی خمیدگیها میدهد. چهار نقطه منحنی را تعیین میکنند: شروع، دو نقطه کنترل و پایان. منحنیهای مکعب برای ساخت خطوط پیچیده مانند حروف در فونتها، نقشه توابع و اشکال ارگانیک استفاده میشوند.
برای راحتی، نسخههای نسبی rQuadTo و rCubicTo وجود دارند که جابهجاییها را از موقعیت فعلی میپذیرند. این به ویژه در تولید برنامهای منحنیها بر اساس افزایشهای نسبی، مانند رسم امواج یا سینوسیها، مفید است. دقت منحنیهای Bézier فقط به دقت محاسبات روی CPU بستگی دارد — در زمان رسم، با وضوح زیرپیکسل شطرنجی میشوند.
| روش | نوع منحنی | نقاط کنترل | کاربرد |
|---|---|---|---|
| quadTo | Bézier درجه دوم | 1 | گردسازی، کمانهای ساده |
| cubicTo | Bézier مکعب | 2 | فونتها، خطوط پیچیده |
| rQuadTo | نسبی درجه دوم | 1 | امواج، سینوسیها |
| rCubicTo | نسبی مکعب | 2 | اشکال ارگانیک |
addCircle یک دایره را به عنوان یک خط جدید به Path اضافه میکند. پارامترها: مختصات مرکز، شعاع و جهت پیمایش (CW — ساعتگرد، CCW — پادساعتگرد). پس از فراخوانی، موقعیت فعلی قلم تغییر نمیکند — دایره به عنوان یک خط بسته مستقل و غیرمرتبط با بخشهای قبلی اضافه میشود. این امکان ترکیب اشکال آماده با خطوط دلخواه در یک Path را فراهم میکند.
addRect یک مستطیل را که با مختصات گوشه بالا-چپ و پایین-راست تعریف شده است اضافه میکند. addOval یک بیضی محاط در مستطیل مشخص شده اضافه میکند. هر دو روش از پارامتر Direction پشتیبانی میکنند. برای گوشههای گرد از addRoundRect استفاده میشود که شعاع گرد شدن را برای همه گوشهها یا آرایهای از 8 مقدار شعاع (دو تا برای هر گوشه) میپذیرد.
arcTo یک کمان دایره یا بیضی اضافه میکند. پارامترها: مستطیل محدودکننده، زاویه شروع بر حسب درجه، زاویه چرخش و پرچم forceMoveTo. اگر forceMoveTo برابر true باشد، قبل از کمان یک moveTo به نقطه شروع کمان اجرا میشود، در غیر این صورت کمان با یک خط مستقیم به موقعیت فعلی متصل میشود. کمانها در نقشههای دایرهای و نشانگرهای پیشرفت استفاده میشوند.
val path = Path().apply {
addCircle(200f, 200f, 100f, Path.Direction.CW)
addRect(50f, 50f, 150f, 150f, Path.Direction.CCW)
addRoundRect(RectF(300f, 100f, 400f, 200f), 15f, 15f, Path.Direction.CW)
}
Path.Op — مکانیزم عملیات بولی روی دو خط، که از API 19 در دسترس است. عملیات DIFFERENCE، INTERSECT، UNION، XOR و REVERSE_DIFFERENCE پشتیبانی میشوند. نتیجه یک Path جدید حاوی هندسه بهدست آمده پس از اعمال عملیات انتخاب شده است. این امکان ایجاد اشکال پیچیده از اشکال پایه ساده بدون محاسبه دستی نقاط تقاطع را فراهم میکند.
UNION دو خط را در یکی ادغام میکند. INTERSECT فقط ناحیه متعلق به هر دو خط را نگه میدارد. DIFFERENCE خط دوم را از اولی کم میکند — برای برش سوراخ در اشکال مفید است. XOR نواحی متعلق به فقط یکی از خطوط را نگه میدارد. REVERSE_DIFFERENCE خط اول را از دومی کم میکند.
روش op دو Path و عملیات را میگیرد و اگر نتیجه خالی نباشد true برمیگرداند. پیچیدگی محاسباتی عملیات به تعداد بخشها در هر دو خط بستگی دارد. برای اشکال ساده (کمتر از 100 بخش)، عملیات در زیر میلیثانیه اجرا میشود. Path Op در ویرایشگرهای تصویر، ابزارهای طراحی و ساخت عناصر UI پیچیده استفاده میشود.
val circle = Path().apply { addCircle(0f, 0f, 100f, Path.Direction.CW) }
val square = Path().apply { addRect(RectF(-50f, -50f, 50f, 50f), Path.Direction.CW) }
val result = Path()
result.op(circle, square, Path.Op.DIFFERENCE) // دایره با سوراخ مربعی
ایجاد یک آیکون سفارشی "قلب" با استفاده از Path را بررسی میکنیم. شکل از دو کمان و دو خط مستقیم ساخته شده است که یک شبح متقارن را تشکیل میدهند. کد ترکیبی از moveTo، cubicTo و close را برای بهدست آوردن یک خط نرم نشان میدهد.
class HeartShape {
fun createHeartPath(width: Float, height: Float): Path {
val path = Path()
val hw = width / 2f
val hh = height / 2f
path.moveTo(hw, hh + hh * 0.3f)
path.cubicTo(hw, hh + hh * 0.6f, hw + hw * 0.5f, hh + hh * 0.5f, hw + hw * 0.5f, hh)
path.cubicTo(hw + hw * 0.5f, hh * 0.5f, hw + hw * 0.2f, 0f, hw, hh * 0.2f)
path.cubicTo(hw - hw * 0.2f, 0f, hw - hw * 0.5f, hh * 0.5f, hw - hw * 0.5f, hh)
path.cubicTo(hw - hw * 0.5f, hh + hh * 0.5f, hw, hh + hh * 0.6f, hw, hh + hh * 0.3f)
path.close()
return path
}
}
منحنیهای مکعب cubicTo امکان کنترل دقیق شکل هر نیمه قلب را فراهم میکنند. منحنی اول کمان بالا-راست را تشکیل میدهد، دومی — سمت چپ، سومی و چهارمی — قسمت پایین را. روش close خط را در نقطه پایین میبندد. این رویکرد برای ایجاد آیکونهای سفارشی، لوگوها و عناصر تزیینی در برنامهها استفاده میشود.
برای تست شکل میتوان به موقت رسم با Paint.Style.STROKE را فعال کرد — این کار تمام خطوط راهنما و منحنیها را نشان میدهد. اگر خط ناهموار به نظر میرسد، تعداد نقاط منحنیها را افزایش دهید یا از PathMeasure برای ارزیابی طول و یکنواختی بخشها استفاده کنید. PathMeasure معیارهای دقیق مسیر را فراهم میکند که برای انیمیشن حرکت در طول خط ضروری است.
سوالات متداول
addPath به سادگی یک خط را به خط دیگر بدون تغییر هندسه اضافه میکند. op یک عملیات بولی (اتحاد، اشتراک، تفاضل) را انجام میدهد و هندسه را تغییر میدهد. برای ادغام ساده از addPath، برای اشکال پیچیده از op استفاده کنید.
روش computeBounds مستطیل محدودکننده را برمیگرداند. برای بررسی دقیق از Region استفاده کنید: یک Region از Path ایجاد کرده و contains(x, y) را فراخوانی کنید. برای خطوط پیچیده، Region ممکن است سنگین باشد — از PathOp برای سادهسازی اولیه استفاده کنید.
بله، از طریق ValueAnimator با بهروزرسانی نقاط Path در هر فریم. برای انیمیشن نرم شکل از کتابخانه AnimatedVectorDrawable استفاده کنید — این کتابخانه از انیمیشن بین دو وضعیت Path با درونیابی منحنیهای Bézier پشتیبانی میکند.
محدودیت سختی وجود ندارد، اما Path تمام نقاط را در حافظه ذخیره میکند. برای خطوط با بیش از 10 000 بخش، عملکرد رسم کاهش مییابد. برای گرافیک پیچیده، خط را به چند Path تقسیم کرده و از Hardware Accelerator از طریق View.isHardwareAccelerated استفاده کنید.
Path — یک کلاس برنامهنویسی برای ساخت خطوط دلخواه در کد. Shape (GradientDrawable) — یک منبع XML برای اشکال ساده با قابلیتهای محدود. Path انعطافپذیرتر است و برای گرافیک پویا مناسب است، Shape برای پسزمینههای ثابت راحتتر است.
خلاصه
ما یک اپلیکیشن موبایل به صورت کلید در دست توسعه خواهیم داد
IT Sectr از سال 2017 برنامههای iOS و Android را برای استارتاپها و کسبوکارها ایجاد میکند. ما به شما مشاوره میدهیم و بهترین راهحل را پیشنهاد خواهیم کرد.
همچنین بخوانید