Android و ChromeOS انواع مختلفی از میاناهای برنامهسازی کاربردی را ارائه میدهند تا به شما کمک کنند برنامههایی بسازید که
تجربه استثنایی استفاده از قلم را به کاربران ارائه میدهند. کلاس
MotionEvent
اطلاعات مربوط به تعامل قلم با صفحه را نشان میدهد، ازجمله فشار قلم،
جهت، کج کردن، نگه داشتن، و تشخیص کف دست. کتابخانههای پیشبینی حرکت و گرافیک با تأخیر کم، رندرینگ قلم روی صفحه را بهبود میبخشند تا تجربهای طبیعی مانند قلم و کاغذ ارائه دهند.
MotionEvent
کلاس MotionEvent نشاندهنده تعاملات ورودی کاربر مانند موقعیت
و حرکت اشارهگرهای لمسی روی صفحه است. برای ورودی قلم، MotionEvent
دادههای فشار، جهت، شیب، و نگه داشتن روی صفحه را نیز نشان میدهد.
دادههای رویداد
برای دسترسی به اشیای قلم MotionEvent، اصلاحکننده pointerInteropFilter را به سطح طراحی اضافه کنید. کلاس ViewModel را با روشی پیادهسازی کنید که رویدادهای حرکتی را پردازش میکند؛ روش را بهعنوان لامبدا onTouchEvent اصلاحکننده pointerInteropFilter ارسال کنید:
@Composable @OptIn(ExperimentalComposeUiApi::class) fun DrawArea(modifier: Modifier = Modifier) { Canvas( modifier = modifier .clipToBounds() .pointerInteropFilter { viewModel.processMotionEvent(it) } ) { // Drawing code here. } }
شیء MotionEvent دادههای مربوط به جنبههای زیر از رویداد واسط کاربر را ارائه میدهد:
- کنشها: تعامل فیزیکی با دستگاه—لمس کردن صفحه، حرکت دادن اشارهگر روی سطح صفحه، نگه داشتن اشارهگر روی سطح صفحه
- اشارهگرها: شناسههای اشیایی که با صفحه تعامل دارند—انگشت، قلم، موشواره
- محور: نوع داده—مختصات x و y، فشار، کج کردن، جهت، و نگه داشتن (فاصله)
کنشها
برای پیادهسازی پشتیبانی از قلم، باید بدانید کاربر چه کنشی را انجام میدهد.
MotionEvent طیف گستردهای از ثابتهای ACTION را ارائه میدهد که رویدادهای حرکتی را تعریف میکنند. مهمترین کنشهای قلم شامل موارد زیر است:
| کنش | شرح |
|---|---|
| ACTION_DOWN ACTION_POINTER_DOWN |
اشارهگر با صفحه تماس برقرار کرده است. |
| ACTION_MOVE | اشارهگر در صفحه حرکت میکند. |
| ACTION_UP ACTION_POINTER_UP |
اشارهگر دیگر با صفحهنمایش در تماس نیست |
| ACTION_CANCEL | وقتی مجموعه حرکت قبلی یا فعلی باید لغو شود. |
برنامه شما میتواند کارهایی مثل شروع کردن خط جدید هنگام رخ دادن ACTION_DOWN،
کشیدن خط با ACTION_MOVE,، و تمام کردن خط هنگام راهاندازی شدن ACTION_UP را انجام دهد.
مجموعه کنشهای MotionEvent از ACTION_DOWN تا ACTION_UP برای یک اشارهگر مشخص، مجموعه حرکتی نامیده میشود.
اشارهگرها
اکثر صفحهنمایشها چندلمسی هستند: سیستم برای هر انگشت، قلم، موشواره، یا شیء اشارهگر دیگری که با صفحهنمایش تعامل دارد، یک اشارهگر اختصاص میدهد. نمایه اشارهگر به شما امکان میدهد اطلاعات محور را برای اشارهگر خاصی دریافت کنید، مثلاً موقعیت اولین یا دومین انگشتی که صفحهنمایش را لمس میکند.
محدوده نمایههای اشارهگر از صفر تا تعداد اشارهگرهای برگرداندهشده توسط
MotionEvent#pointerCount()
منهای ۱ است.
مقادیر محور اشارهگرها را میتوان با روش getAxisValue(axis,
pointerIndex) دریافت کرد.
وقتی نمایه اشارهگر حذف شود، سیستم مقدار اولین اشارهگر، یعنی اشارهگر صفر (۰)، را برمیگرداند.
اشیاء MotionEvent حاوی اطلاعاتی درباره نوع اشارهگر مورداستفاده هستند. میتوانید
نوع اشارهگر را با تکرار کردن در نمایههای اشارهگر و فراخوانی
روش
getToolType(pointerIndex)
دریافت کنید.
برای آشنایی بیشتر با اشارهگرها، مدیریت اشارههای چندلمسی را ببینید.
ورودیهای قلم
میتوانید ورودیهای قلم را با
TOOL_TYPE_STYLUS فیلتر کنید:
val isStylus = TOOL_TYPE_STYLUS == event.getToolType(pointerIndex)
قلم همچنین میتواند گزارش دهد که بهعنوان پاککن با
TOOL_TYPE_ERASER استفاده میشود:
val isEraser = TOOL_TYPE_ERASER == event.getToolType(pointerIndex)
دادههای محور قلم
ACTION_DOWN و ACTION_MOVE دادههای محور را درباره قلم ارائه میدهند، یعنی مختصات x و y، فشار، جهت، کج کردن، و نگه داشتن.
برای فعال کردن دسترسی به این دادهها، MotionEvent API
getAxisValue(int) را ارائه میدهد،
که در آن پارامتر یکی از شناسههای محور زیر است:
| Axis | برگرداندن مقدار getAxisValue() |
|---|---|
AXIS_X |
مختصات X رویداد حرکتی. |
AXIS_Y |
مختصات Y رویداد حرکتی. |
AXIS_PRESSURE |
برای صفحه لمسی یا پد لمسی، فشاری که توسط انگشت، قلم، یا اشارهگر دیگر اعمال میشود. برای موشواره یا گوی پیمایش، اگر دکمه اصلی فشار داده شود، ۱ و درغیراینصورت، ۰. |
AXIS_ORIENTATION |
برای صفحه لمسی یا صفحه لمسی، جهت انگشت، قلم، یا اشارهگر دیگر نسبت به صفحه عمودی دستگاه. |
AXIS_TILT |
زاویه شیب قلم برحسب رادیان. |
AXIS_DISTANCE |
فاصله قلم از صفحه. |
برای مثال، MotionEvent.getAxisValue(AXIS_X) مختصات x را برای
نشانگر اول برمیگرداند.
همچنین به مدیریت اشارههای چندلمسی مراجعه کنید.
موقعیت
میتوانید مختصات x و y اشارهگر را با فراخوانیهای زیر بازیابی کنید:
MotionEvent#getAxisValue(AXIS_X)یاMotionEvent#getX()MotionEvent#getAxisValue(AXIS_Y)یاMotionEvent#getY()
فشار
میتوانید فشار اشارهگر را با
MotionEvent#getAxisValue(AXIS_PRESSURE) یا، برای اشارهگر اول،
MotionEvent#getPressure() بازیابی کنید.
مقدار فشار برای صفحههای لمسی یا صفحههای لمسی مقداری بین ۰ (بدون فشار) و ۱ است، اما بسته به کالیبراسیون صفحه، مقادیر بالاتری نیز میتواند برگردانده شود.
جهت
جهت نشان میدهد که قلم بهسمت کدام جهت است.
جهت اشارهگر را میتوان بااستفاده از getAxisValue(AXIS_ORIENTATION) یا
getOrientation()
(برای اشارهگر اول) بازیابی کرد.
برای قلم، جهت بهعنوان مقدار رادیان بین ۰ تا pi (𝛑) در جهت عقربههای ساعت یا ۰ تا pi- در خلاف جهت عقربههای ساعت برگردانده میشود.
جهتگیری به شما امکان میدهد قلمموی واقعی را پیادهسازی کنید. برای مثال، اگر قلم نوری نشاندهنده قلمموی تخت باشد، عرض قلمموی تخت به جهت قلم نوری بستگی دارد.
شیب
شیب، میزان کج شدن قلم نسبت به صفحه را اندازهگیری میکند.
«شیب» زاویه مثبت قلم را برحسب رادیان برمیگرداند، که در آن صفر عمود بر صفحهنمایش است و 𝛑/۲ روی سطح صاف است.
زاویه کجی را میتوان بااستفاده از getAxisValue(AXIS_TILT) بازیابی کرد (میانبری برای
نشانگر اول وجود ندارد).
از «کج کردن» میتوان برای بازتولید ابزارهای واقعی تا حد امکان استفاده کرد، مثلاً تقلید سایهزنی با مداد کجشده.
نگه داشتن موشواره روی یک مورد
فاصله قلم از صفحه را میتوان با
getAxisValue(AXIS_DISTANCE) بهدست آورد. این روش مقداری از ۰٫۰ (تماس با
صفحه) تا مقادیر بالاتر را با دور شدن قلم از صفحه برمیگرداند. فاصله شناور بین صفحهنمایش و نوک قلم به سازنده صفحهنمایش و قلم بستگی دارد. ازآنجاییکه پیادهسازیها میتوانند
متفاوت باشند، برای عملکردهای حیاتی برنامه به مقادیر دقیق تکیه نکنید.
از نگه داشتن قلم روی صفحه میتوان برای پیشدید اندازه قلممو یا نشان دادن اینکه دکمهای قرار است انتخاب شود استفاده کرد.
توجه: Compose اصلاحگرهایی ارائه میدهد که بر حالت تعاملی عناصر میانای کاربر تأثیر میگذارند:
hoverable: پیکربندی مؤلفه برای شناور شدن بااستفاده از رویدادهای ورود و خروج اشارهگر.indication: جلوههای دیداری را برای این مؤلفه هنگام وقوع تعاملات ترسیم میکند.
رد کردن لمس کف دست، پیمایش، و ورودیهای ناخواسته
گاهیاوقات صفحهنمایشهای چندلمسی ممکن است لمسهای ناخواسته را ثبت کنند، برای مثال، وقتی
کاربر بهطور طبیعی دستش را برای تکیه دادن روی صفحهنمایش میگذارد تا بتواند بنویسد.
رد کردن لمس کف دست مکانیزمی است که این رفتار را شناسایی میکند و به شما اطلاع میدهد که
آخرین مجموعه MotionEvent باید لغو شود.
درنتیجه، باید سابقهای از ورودیهای کاربر را نگه دارید تا لمسهای ناخواسته از صفحه برداشته شود و ورودیهای قانونی کاربر بتواند دوباره ارائه شود.
ACTION_CANCEL و FLAG_CANCELED
ACTION_CANCEL و
FLAG_CANCELED هر دو
طراحی شدهاند تا به شما اطلاع دهند که مجموعه MotionEvent قبلی باید
از آخرین ACTION_DOWN لغو شود، بنابراین میتوانید، برای مثال، آخرین
حرکت قلم را برای برنامه طراحی برای اشارهگر دادهشده واگرد کنید.
ACTION_CANCEL
در Android 1.0 (سطح میانای برنامهسازی کاربردی ۱) اضافه شد
ACTION_CANCEL نشان میدهد که مجموعه قبلی رویدادهای حرکتی باید لغو شود.
ACTION_CANCEL زمانی فعال میشود که هریک از موارد زیر شناسایی شود:
- اشارههای پیمایش
- رد کردن کف دست
وقتی ACTION_CANCEL راهاندازی شد، باید اشارهگر فعال را با
getPointerId(getActionIndex()) شناسایی کنید. سپس خط ایجادشده با آن اشارهگر را از سابقه ورودی بردارید و صحنه را دوباره رندر کنید.
FLAG_CANCELED
در Android 13 (سطح میانای برنامهسازی کاربردی ۳۳) اضافه شده است
FLAG_CANCELED
نشان میدهد که بالا رفتن اشارهگر بهدلیل لمس غیرعمدی کاربر بوده است. این پرچم معمولاً زمانی تنظیم میشود که کاربر بهطور تصادفی صفحه را لمس کند، مثلاً هنگام گرفتن دستگاه یا قرار دادن کف دست روی صفحه.
بهصورت زیر به مقدار پرچم دسترسی پیدا میکنید:
val cancel = (event.flags and FLAG_CANCELED) == FLAG_CANCELED
اگر پرچم تنظیم شده است، باید آخرین مجموعه MotionEvent را از آخرین
ACTION_DOWN از این اشارهگر واگرد کنید.
مانند ACTION_CANCEL، اشارهگر را میتوان با getPointerId(actionIndex) پیدا کرد.
MotionEvent مجموعه ایجاد میکند. لمس کف دست لغو شد و نمایشگر دوباره رندر شد.
تمامصفحه، لبهتالبه، و اشارههای پیمایش
اگر برنامهای تمامصفحه باشد و عناصر کنشپذیر در نزدیکی لبه داشته باشد، مثل بوم نقاشی یا برنامه یادداشتبرداری، تند کشیدن از پایین صفحه برای نمایش پیمایش یا انتقال برنامه به پسزمینه ممکن است منجر به لمس ناخواسته بوم شود.
برای جلوگیری از اینکه اشارهها باعث لمسهای ناخواسته در برنامهتان شود، میتوانید از
درجها و
ACTION_CANCEL استفاده کنید.
همچنین بخش رد کردن لمس کف دست، پیمایش، و ورودیهای ناخواسته را ببینید.
برای جلوگیری از ایجاد رویدادهای لمسی ناخواسته توسط اشارههای پیمایش، از روش
setSystemBarsBehavior()
و
BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
WindowInsetsController
استفاده کنید:
// Configure the behavior of the hidden system bars.
windowInsetsController.systemBarsBehavior =
WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
برای کسب اطلاعات بیشتر درباره مدیریت تورفتگی و اشاره، به موارد زیر مراجعه کنید:
- پنهان کردن نوارهای سیستم برای حالت فراگیر
- اطمینان از سازگاری با پیمایش اشارهای
- نمایش محتوا بهصورت لبهبهلبه در برنامه
تأخیر پایین
تأخیر زمانی است که سختافزار، سیستم، و برنامه برای پردازش و ارائه ورودی کاربر نیاز دارند.
تأخیر = پردازش ورودی سختافزار و سیستمعامل + پردازش برنامه + ترکیببندی سیستم
- پرداز زدن سختافزاری
منبع تأخیر
- ثبت قلم با صفحه لمسی (سختافزار): اتصال بیسیم اولیه وقتی قلم و سیستمعامل برای ثبت و همگامسازی با یکدیگر ارتباط برقرار میکنند.
- نرخ نمونهبرداری لمسی (سختافزار): تعداد دفعاتی در ثانیه که صفحه لمسی بررسی میکند آیا اشارهگر سطح را لمس میکند یا نه، از ۶۰ تا ۱۰۰۰ هرتز.
- پردازش ورودی (برنامه): اعمال رنگ، جلوههای گرافیکی، و تبدیل روی ورودی کاربر.
- پرداخت گرافیکی (سیستمعامل + سختافزار): تعویض میانگیر، پردازش سختافزاری.
گرافیک با تأخیر کم
کتابخانه گرافیک با تأخیر کم Jetpack زمان پردازش بین ورودی کاربر و بازپرداخت روی صفحه را کاهش میدهد.
این کتابخانه با اجتناب از پردازاندن چندمیانگیری و بهرهبرداری از تکنیک پردازاندن میانگیر جلو، که بهمعنای نوشتن مستقیم روی صفحهنمایش است، زمان پردازش را کاهش میدهد.
پرداز کردن میانگیر جلو
میانگیر جلو حافظهای است که صفحهنمایش برای پردازش استفاده میکند. این نزدیکترین حالتی است که برنامهها میتوانند مستقیماً روی صفحهنمایش طراحی کنند. کتابخانه با تأخیر کم به برنامهها امکان میدهد مستقیماً در میانگیر جلو رندر کنند. این کار با جلوگیری از تعویض میانگیر، که میتواند برای پرداز چندمیانگیر معمولی یا پرداز میانگیر دوگانه (رایجترین مورد) اتفاق بیفتد، عملکرد را بهبود میبخشد.
درحالیکه پرداز میانگیر جلو تکنیک فوقالعادهای برای پرداز ناحیه کوچکی از صفحهنمایش است، برای استفاده جهت بازآوری کل صفحهنمایش طراحی نشده است. با پرداز بافر جلو، برنامه محتوا را در بافری پرداز میکند که نمایشگر از آن میخواند. درنتیجه، احتمال ایجاد آرتیفکتهای پردازشی یا پارگی تصویر (به زیر مراجعه کنید) وجود دارد.
کتابخانه با تأخیر کم از Android 10 (سطح API ۲۹) و بالاتر و در دستگاههای ChromeOS با Android 10 (سطح API ۲۹) و بالاتر دردسترس است.
وابستگیها
کتابخانه با تأخیر کم مؤلفههایی را برای پیادهسازی رندر میانگیر جلو ارائه میدهد. کتابخانه بهعنوان وابستگی در فایل build.gradle
ماژول برنامه اضافه شده است:
dependencies {
implementation "androidx.graphics:graphics-core:1.0.0-alpha03"
}
پاسخهای تماس GLFrontBufferRenderer
کتابخانه با تأخیر کم شامل میانای
GLFrontBufferRenderer.Callback
است که روشهای زیر را تعریف میکند:
کتابخانه با تأخیر کم درباره نوع دادهای که با
GLFrontBufferRenderer استفاده میکنید نظری ندارد.
بااینحال، کتابخانه دادهها را بهصورت جریانی از صدها نقطه داده پردازش میکند؛ بنابراین، دادههایتان را بهگونهای طراحی کنید که استفاده از حافظه و تخصیص آن بهینه شود.
بازخوانیها
برای فعال کردن بازخوانیهای پردازشی، GLFrontBufferedRenderer.Callback را اجرا کنید و
onDrawFrontBufferedLayer() و onDrawDoubleBufferedLayer() را لغو کنید.
GLFrontBufferedRenderer از فراخوانیهای برگشتی برای ارائه دادههای شما به بهینهترین شکل ممکن استفاده میکند.
val callback = object: GLFrontBufferedRenderer.Callback<DATA_TYPE> {
override fun onDrawFrontBufferedLayer(
eglManager: EGLManager,
bufferInfo: BufferInfo,
transform: FloatArray,
param: DATA_TYPE
) {
// OpenGL for front buffer, short, affecting small area of the screen.
}
override fun onDrawMultiDoubleBufferedLayer(
eglManager: EGLManager,
bufferInfo: BufferInfo,
transform: FloatArray,
params: Collection<DATA_TYPE>
) {
// OpenGL full scene rendering.
}
}
یک نمونه از GLFrontBufferedRenderer را اعلام کنید
GLFrontBufferedRenderer را با ارائه SurfaceView و
برگشتهای تماسی که قبلاً ایجاد کردهاید آماده کنید. GLFrontBufferedRenderer بااستفاده از فراخوانهای برگشتی شما،
پرداخت را برای میانگیر جلو و دوگانه بهینه میکند:
var glFrontBufferRenderer = GLFrontBufferedRenderer<DATA_TYPE>(surfaceView, callbacks)
درحال پرداز زدن
وقتی روش renderFrontBufferedLayer() را فراخوانی میکنید، رندر کردن میانگیر جلو شروع میشود و این کار باعث راهاندازی فراخوانی onDrawFrontBufferedLayer() میشود.
وقتی تابع
commit()
را فراخوانی میکنید، پرداز با میانگیر دوگانه ازسر گرفته میشود و این کار باعث راهاندازی فراخوان برگشتی onDrawMultiDoubleBufferedLayer() میشود.
در مثال زیر، وقتی کاربر شروع به طراحی روی صفحه میکند (ACTION_DOWN) و اشارهگر را حرکت میدهد (ACTION_MOVE)، فرایند در میانگیر جلو (پرداخت سریع) پرداخت میشود. وقتی اشارهگر سطح صفحه را ترک میکند (ACTION_UP)، فرایند در میانگیر دوگانه پرداخت میشود.
میتوانید از
requestUnbufferedDispatch()
استفاده کنید تا درخواست کنید سیستم ورودی رویدادهای حرکتی را دستهبندی نکند، بلکه آنها را بهمحض دردسترس قرار گرفتن ارائه دهد:
when (motionEvent.action) {
MotionEvent.ACTION_DOWN -> {
// Deliver input events as soon as they arrive.
view.requestUnbufferedDispatch(motionEvent)
// Pointer is in contact with the screen.
glFrontBufferRenderer.renderFrontBufferedLayer(DATA_TYPE)
}
MotionEvent.ACTION_MOVE -> {
// Pointer is moving.
glFrontBufferRenderer.renderFrontBufferedLayer(DATA_TYPE)
}
MotionEvent.ACTION_UP -> {
// Pointer is not in contact in the screen.
glFrontBufferRenderer.commit()
}
MotionEvent.CANCEL -> {
// Cancel front buffer; remove last motion set from the screen.
glFrontBufferRenderer.cancel()
}
}
بایدها و نبایدهای پرداز زدن
بخشهای کوچکی از صفحهنمایش، دستنویسی، نقاشی، طراحی.
بهروزرسانی تمامصفحه، حرکت افقی، بزرگنمایی. میتواند باعث پارگی شود.
پارگی
پارگی زمانی اتفاق میافتد که صفحه بازآوری میشود درحالیکه میانگیر صفحه همزمان درحال اصلاح است. بخشی از صفحه دادههای جدید را نشان میدهد، درحالیکه بخش دیگر دادههای قدیمی را نشان میدهد.
پیشبینی حرکت
کتابخانه پیشبینی حرکت Jetpack با تخمین زدن مسیر ضربه کاربر و ارائه نقاط مصنوعی موقت به رندرکننده، تأخیر درکشده را کاهش میدهد.
کتابخانه پیشبینی حرکت، ورودیهای واقعی کاربر را بهعنوان اشیاء MotionEvent دریافت میکند.
این اشیا حاوی اطلاعاتی درباره مختصات x و y، فشار، و زمان هستند
که پیشبینیکننده حرکت از آنها برای پیشبینی اشیای MotionEvent آینده استفاده میکند.
MotionEvent شیء پیشبینیشده فقط تخمینی هستند. رویدادهای پیشبینیشده میتوانند
تأخیر درکشده را کاهش دهند، اما دادههای پیشبینیشده باید با دادههای واقعی MotionEvent
پساز دریافت جایگزین شوند.
کتابخانه پیشبینی حرکت از Android 4.4 (سطح API ۱۹) و بالاتر و در دستگاههای ChromeOS دارای Android 9 (سطح API ۲۸) و بالاتر دردسترس است.
وابستگیها
کتابخانه پیشبینی حرکت، پیادهسازی پیشبینی را ارائه میدهد. کتابخانه
بهعنوان وابستگی در فایل build.gradle ماژول برنامه اضافه شده است:
dependencies {
implementation "androidx.input:input-motionprediction:1.0.0-beta01"
}
پیادهسازی
کتابخانه پیشبینی حرکت شامل میانای
MotionEventPredictor
است که روشهای زیر را تعریف میکند:
record():MotionEventشیء را بهعنوان سابقهای از کنشهای کاربر ذخیره میکندpredict():MotionEventپیشبینیشده را برمیگرداند
نمونهای از MotionEventPredictor را اعلام کنید
var motionEventPredictor = MotionEventPredictor.newInstance(view)
تغذیه پیشبینیکننده با دادهها
motionEventPredictor.record(motionEvent)
پیشبینی کردن
when (motionEvent.action) {
MotionEvent.ACTION_MOVE -> {
val predictedMotionEvent = motionEventPredictor?.predict()
if(predictedMotionEvent != null) {
// use predicted MotionEvent to inject a new artificial point
}
}
}
بایدها و نبایدهای پیشبینی حرکت
وقتی نقطه پیشبینیشده جدیدی اضافه میشود، نقاط پیشبینی را بردارید.
از نقاط پیشبینی برای پرداخت نهایی استفاده نکنید.
برنامههای یادداشتبرداری
ChromeOS به برنامه شما امکان میدهد برخیاز کنشهای یادداشتبرداری را اعلام کند.
برای ثبت برنامه بهعنوان برنامه یادداشتبرداری در ChromeOS، به سازگاری ورودی مراجعه کنید.
برای ثبت برنامه بهعنوان برنامه یادداشتبرداری در Android، به ایجاد برنامه یادداشتبرداری مراجعه کنید.
Android 14 (سطح میانای برنامهسازی کاربردی ۳۴)
ACTION_CREATE_NOTE
را معرفی کرد که به برنامه شما امکان میدهد فعالیت یادداشتبرداری را در صفحه قفل
شروع کند.
تشخیص جوهر دیجیتال با ML Kit
با تشخیص جوهر دیجیتال ML Kit، برنامه شما میتواند نوشتار دستنویس را روی سطح دیجیتال به صدها زبان تشخیص دهد. همچنین میتوانید طرحها را طبقهبندی کنید.
«کیت یادگیری ماشین» کلاس
Ink.Stroke.Builder
را برای ایجاد اشیاء Ink ارائه میدهد که میتوانند توسط مدلهای یادگیری ماشین پردازش شوند تا دستنوشته را به نوشتار تبدیل کنند.
علاوهبر تشخیص دستنویس، این مدل میتواند اشارهها مثل حذف و دایره کشیدن را تشخیص دهد.
برای کسب اطلاعات بیشتر، به تشخیص جوهر دیجیتال مراجعه کنید.
منابع بیشتر
راهنمای توسعهدهندگان
Codelabs
،Android و ChromeOS انواع مختلفی از میاناهای برنامهسازی کاربردی را ارائه میدهند تا به شما کمک کنند برنامههایی بسازید که
تجربه استثنایی استفاده از قلم را به کاربران ارائه میدهند. کلاس
MotionEvent
اطلاعات مربوط به تعامل قلم با صفحه را نشان میدهد، ازجمله فشار قلم،
جهت، کج کردن، نگه داشتن، و تشخیص کف دست. کتابخانههای پیشبینی حرکت و گرافیک با تأخیر کم، رندرینگ قلم روی صفحه را بهبود میبخشند تا تجربهای طبیعی مانند قلم و کاغذ ارائه دهند.
MotionEvent
کلاس MotionEvent نشاندهنده تعاملات ورودی کاربر مانند موقعیت
و حرکت اشارهگرهای لمسی روی صفحه است. برای ورودی قلم، MotionEvent
دادههای فشار، جهت، شیب، و نگه داشتن روی صفحه را نیز نشان میدهد.
دادههای رویداد
برای دسترسی به اشیای قلم MotionEvent، اصلاحکننده pointerInteropFilter را به سطح طراحی اضافه کنید. کلاس ViewModel را با روشی پیادهسازی کنید که رویدادهای حرکتی را پردازش میکند؛ روش را بهعنوان لامبدا onTouchEvent اصلاحکننده pointerInteropFilter ارسال کنید:
@Composable @OptIn(ExperimentalComposeUiApi::class) fun DrawArea(modifier: Modifier = Modifier) { Canvas( modifier = modifier .clipToBounds() .pointerInteropFilter { viewModel.processMotionEvent(it) } ) { // Drawing code here. } }
شیء MotionEvent دادههای مربوط به جنبههای زیر از رویداد واسط کاربر را ارائه میدهد:
- کنشها: تعامل فیزیکی با دستگاه—لمس کردن صفحه، حرکت دادن اشارهگر روی سطح صفحه، نگه داشتن اشارهگر روی سطح صفحه
- اشارهگرها: شناسههای اشیایی که با صفحه تعامل دارند—انگشت، قلم، موشواره
- محور: نوع داده—مختصات x و y، فشار، کج کردن، جهت، و نگه داشتن (فاصله)
کنشها
برای پیادهسازی پشتیبانی از قلم، باید بدانید کاربر چه کنشی را انجام میدهد.
MotionEvent طیف گستردهای از ثابتهای ACTION را ارائه میدهد که رویدادهای حرکتی را تعریف میکنند. مهمترین کنشهای قلم شامل موارد زیر است:
| کنش | شرح |
|---|---|
| ACTION_DOWN ACTION_POINTER_DOWN |
اشارهگر با صفحه تماس برقرار کرده است. |
| ACTION_MOVE | اشارهگر در صفحه حرکت میکند. |
| ACTION_UP ACTION_POINTER_UP |
اشارهگر دیگر با صفحهنمایش در تماس نیست |
| ACTION_CANCEL | وقتی مجموعه حرکت قبلی یا فعلی باید لغو شود. |
برنامه شما میتواند کارهایی مثل شروع کردن خط جدید هنگام رخ دادن ACTION_DOWN،
کشیدن خط با ACTION_MOVE,، و تمام کردن خط هنگام راهاندازی شدن ACTION_UP را انجام دهد.
مجموعه کنشهای MotionEvent از ACTION_DOWN تا ACTION_UP برای یک اشارهگر مشخص، مجموعه حرکتی نامیده میشود.
اشارهگرها
اکثر صفحهنمایشها چندلمسی هستند: سیستم برای هر انگشت، قلم، موشواره، یا شیء اشارهگر دیگری که با صفحهنمایش تعامل دارد، یک اشارهگر اختصاص میدهد. نمایه اشارهگر به شما امکان میدهد اطلاعات محور را برای اشارهگر خاصی دریافت کنید، مثلاً موقعیت اولین یا دومین انگشتی که صفحهنمایش را لمس میکند.
محدوده نمایههای اشارهگر از صفر تا تعداد اشارهگرهای برگرداندهشده توسط
MotionEvent#pointerCount()
منهای ۱ است.
مقادیر محور اشارهگرها را میتوان با روش getAxisValue(axis,
pointerIndex) دریافت کرد.
وقتی نمایه اشارهگر حذف شود، سیستم مقدار اولین اشارهگر، یعنی اشارهگر صفر (۰)، را برمیگرداند.
اشیاء MotionEvent حاوی اطلاعاتی درباره نوع اشارهگر مورداستفاده هستند. میتوانید
نوع اشارهگر را با تکرار کردن در نمایههای اشارهگر و فراخوانی
روش
getToolType(pointerIndex)
دریافت کنید.
برای آشنایی بیشتر با اشارهگرها، مدیریت اشارههای چندلمسی را ببینید.
ورودیهای قلم
میتوانید ورودیهای قلم را با
TOOL_TYPE_STYLUS فیلتر کنید:
val isStylus = TOOL_TYPE_STYLUS == event.getToolType(pointerIndex)
قلم همچنین میتواند گزارش دهد که بهعنوان پاککن با
TOOL_TYPE_ERASER استفاده میشود:
val isEraser = TOOL_TYPE_ERASER == event.getToolType(pointerIndex)
دادههای محور قلم
ACTION_DOWN و ACTION_MOVE دادههای محور را درباره قلم ارائه میدهند، یعنی مختصات x و y، فشار، جهت، کج کردن، و نگه داشتن.
برای فعال کردن دسترسی به این دادهها، MotionEvent API
getAxisValue(int) را ارائه میدهد،
که در آن پارامتر یکی از شناسههای محور زیر است:
| Axis | برگرداندن مقدار getAxisValue() |
|---|---|
AXIS_X |
مختصات X رویداد حرکتی. |
AXIS_Y |
مختصات Y رویداد حرکتی. |
AXIS_PRESSURE |
برای صفحه لمسی یا پد لمسی، فشاری که توسط انگشت، قلم، یا اشارهگر دیگر اعمال میشود. برای موشواره یا گوی پیمایش، اگر دکمه اصلی فشار داده شود، ۱ و درغیراینصورت، ۰. |
AXIS_ORIENTATION |
برای صفحه لمسی یا صفحه لمسی، جهت انگشت، قلم، یا اشارهگر دیگر نسبت به صفحه عمودی دستگاه. |
AXIS_TILT |
زاویه شیب قلم برحسب رادیان. |
AXIS_DISTANCE |
فاصله قلم از صفحه. |
برای مثال، MotionEvent.getAxisValue(AXIS_X) مختصات x را برای
نشانگر اول برمیگرداند.
همچنین به مدیریت اشارههای چندلمسی مراجعه کنید.
موقعیت
میتوانید مختصات x و y اشارهگر را با فراخوانیهای زیر بازیابی کنید:
MotionEvent#getAxisValue(AXIS_X)یاMotionEvent#getX()MotionEvent#getAxisValue(AXIS_Y)یاMotionEvent#getY()
فشار
میتوانید فشار اشارهگر را با
MotionEvent#getAxisValue(AXIS_PRESSURE) یا، برای اشارهگر اول،
MotionEvent#getPressure() بازیابی کنید.
مقدار فشار برای صفحههای لمسی یا صفحههای لمسی مقداری بین ۰ (بدون فشار) و ۱ است، اما بسته به کالیبراسیون صفحه، مقادیر بالاتری نیز میتواند برگردانده شود.
جهت
جهت نشان میدهد که قلم بهسمت کدام جهت است.
جهت اشارهگر را میتوان بااستفاده از getAxisValue(AXIS_ORIENTATION) یا
getOrientation()
(برای اشارهگر اول) بازیابی کرد.
برای قلم، جهت بهعنوان مقدار رادیان بین ۰ تا pi (𝛑) در جهت عقربههای ساعت یا ۰ تا pi- در خلاف جهت عقربههای ساعت برگردانده میشود.
جهتگیری به شما امکان میدهد قلمموی واقعی را پیادهسازی کنید. برای مثال، اگر قلم نوری نشاندهنده قلمموی تخت باشد، عرض قلمموی تخت به جهت قلم نوری بستگی دارد.
شیب
شیب، میزان کج شدن قلم نسبت به صفحه را اندازهگیری میکند.
«شیب» زاویه مثبت قلم را برحسب رادیان برمیگرداند، که در آن صفر عمود بر صفحهنمایش است و 𝛑/۲ روی سطح صاف است.
زاویه کجی را میتوان بااستفاده از getAxisValue(AXIS_TILT) بازیابی کرد (میانبری برای
نشانگر اول وجود ندارد).
از «کج کردن» میتوان برای بازتولید ابزارهای واقعی تا حد امکان استفاده کرد، مثلاً تقلید سایهزنی با مداد کجشده.
نگه داشتن موشواره روی یک مورد
فاصله قلم از صفحه را میتوان با
getAxisValue(AXIS_DISTANCE) بهدست آورد. این روش مقداری از ۰٫۰ (تماس با
صفحه) تا مقادیر بالاتر را با دور شدن قلم از صفحه برمیگرداند. فاصله شناور بین صفحهنمایش و نوک قلم به سازنده صفحهنمایش و قلم بستگی دارد. ازآنجاییکه پیادهسازیها میتوانند
متفاوت باشند، برای عملکردهای حیاتی برنامه به مقادیر دقیق تکیه نکنید.
از نگه داشتن قلم روی صفحه میتوان برای پیشدید اندازه قلممو یا نشان دادن اینکه دکمهای قرار است انتخاب شود استفاده کرد.
توجه: Compose اصلاحگرهایی ارائه میدهد که بر حالت تعاملی عناصر میانای کاربر تأثیر میگذارند:
hoverable: پیکربندی مؤلفه برای شناور شدن بااستفاده از رویدادهای ورود و خروج اشارهگر.indication: جلوههای دیداری را برای این مؤلفه هنگام وقوع تعاملات ترسیم میکند.
رد کردن لمس کف دست، پیمایش، و ورودیهای ناخواسته
گاهیاوقات صفحهنمایشهای چندلمسی ممکن است لمسهای ناخواسته را ثبت کنند، برای مثال، وقتی
کاربر بهطور طبیعی دستش را برای تکیه دادن روی صفحهنمایش میگذارد تا بتواند بنویسد.
رد کردن لمس کف دست مکانیزمی است که این رفتار را شناسایی میکند و به شما اطلاع میدهد که
آخرین مجموعه MotionEvent باید لغو شود.
درنتیجه، باید سابقهای از ورودیهای کاربر را نگه دارید تا لمسهای ناخواسته از صفحه برداشته شود و ورودیهای قانونی کاربر بتواند دوباره ارائه شود.
ACTION_CANCEL و FLAG_CANCELED
ACTION_CANCEL و
FLAG_CANCELED هر دو
طراحی شدهاند تا به شما اطلاع دهند که مجموعه MotionEvent قبلی باید
از آخرین ACTION_DOWN لغو شود، بنابراین میتوانید، برای مثال، آخرین
حرکت قلم را برای برنامه طراحی برای اشارهگر دادهشده واگرد کنید.
ACTION_CANCEL
در Android 1.0 (سطح میانای برنامهسازی کاربردی ۱) اضافه شد
ACTION_CANCEL نشان میدهد که مجموعه قبلی رویدادهای حرکتی باید لغو شود.
ACTION_CANCEL زمانی فعال میشود که هریک از موارد زیر شناسایی شود:
- اشارههای پیمایش
- رد کردن کف دست
وقتی ACTION_CANCEL راهاندازی شد، باید اشارهگر فعال را با
getPointerId(getActionIndex()) شناسایی کنید. سپس خط ایجادشده با آن اشارهگر را از سابقه ورودی بردارید و صحنه را دوباره رندر کنید.
FLAG_CANCELED
در Android 13 (سطح میانای برنامهسازی کاربردی ۳۳) اضافه شده است
FLAG_CANCELED
نشان میدهد که بالا رفتن اشارهگر بهدلیل لمس غیرعمدی کاربر بوده است. این پرچم معمولاً زمانی تنظیم میشود که کاربر بهطور تصادفی صفحه را لمس کند، مثلاً هنگام گرفتن دستگاه یا قرار دادن کف دست روی صفحه.
بهصورت زیر به مقدار پرچم دسترسی پیدا میکنید:
val cancel = (event.flags and FLAG_CANCELED) == FLAG_CANCELED
اگر پرچم تنظیم شده است، باید آخرین مجموعه MotionEvent را از آخرین
ACTION_DOWN از این اشارهگر واگرد کنید.
مانند ACTION_CANCEL، اشارهگر را میتوان با getPointerId(actionIndex) پیدا کرد.
MotionEvent مجموعه ایجاد میکند. لمس کف دست لغو شد و نمایشگر دوباره رندر شد.
تمامصفحه، لبهتالبه، و اشارههای پیمایش
اگر برنامهای تمامصفحه باشد و عناصر کنشپذیر در نزدیکی لبه داشته باشد، مثل بوم نقاشی یا برنامه یادداشتبرداری، تند کشیدن از پایین صفحه برای نمایش پیمایش یا انتقال برنامه به پسزمینه ممکن است منجر به لمس ناخواسته بوم شود.
برای جلوگیری از اینکه اشارهها باعث لمسهای ناخواسته در برنامهتان شود، میتوانید از
درجها و
ACTION_CANCEL استفاده کنید.
همچنین بخش رد کردن لمس کف دست، پیمایش، و ورودیهای ناخواسته را ببینید.
برای جلوگیری از ایجاد رویدادهای لمسی ناخواسته توسط اشارههای پیمایش، از روش
setSystemBarsBehavior()
و
BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
WindowInsetsController
استفاده کنید:
// Configure the behavior of the hidden system bars.
windowInsetsController.systemBarsBehavior =
WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
برای کسب اطلاعات بیشتر درباره مدیریت تورفتگی و اشاره، به موارد زیر مراجعه کنید:
- پنهان کردن نوارهای سیستم برای حالت فراگیر
- اطمینان از سازگاری با پیمایش اشارهای
- نمایش محتوا بهصورت لبهبهلبه در برنامه
تأخیر پایین
تأخیر زمانی است که سختافزار، سیستم، و برنامه برای پردازش و ارائه ورودی کاربر نیاز دارند.
تأخیر = پردازش ورودی سختافزار و سیستمعامل + پردازش برنامه + ترکیببندی سیستم
- پرداز زدن سختافزاری
منبع تأخیر
- ثبت قلم با صفحه لمسی (سختافزار): اتصال بیسیم اولیه وقتی قلم و سیستمعامل برای ثبت و همگامسازی با یکدیگر ارتباط برقرار میکنند.
- نرخ نمونهبرداری لمسی (سختافزار): تعداد دفعاتی در ثانیه که صفحه لمسی بررسی میکند آیا اشارهگر سطح را لمس میکند یا نه، از ۶۰ تا ۱۰۰۰ هرتز.
- پردازش ورودی (برنامه): اعمال رنگ، جلوههای گرافیکی، و تبدیل روی ورودی کاربر.
- پرداخت گرافیکی (سیستمعامل + سختافزار): تعویض میانگیر، پردازش سختافزاری.
گرافیک با تأخیر کم
کتابخانه گرافیک با تأخیر کم Jetpack زمان پردازش بین ورودی کاربر و بازپرداخت روی صفحه را کاهش میدهد.
این کتابخانه با اجتناب از پردازاندن چندمیانگیری و بهرهبرداری از تکنیک پردازاندن میانگیر جلو، که بهمعنای نوشتن مستقیم روی صفحهنمایش است، زمان پردازش را کاهش میدهد.
پرداز کردن میانگیر جلو
میانگیر جلو حافظهای است که صفحهنمایش برای پردازش استفاده میکند. این نزدیکترین حالتی است که برنامهها میتوانند مستقیماً روی صفحهنمایش طراحی کنند. کتابخانه با تأخیر کم به برنامهها امکان میدهد مستقیماً در میانگیر جلو رندر کنند. این کار با جلوگیری از تعویض میانگیر، که میتواند برای پرداز چندمیانگیر معمولی یا پرداز میانگیر دوگانه (رایجترین مورد) اتفاق بیفتد، عملکرد را بهبود میبخشد.
درحالیکه پرداز میانگیر جلو تکنیک فوقالعادهای برای پرداز ناحیه کوچکی از صفحهنمایش است، برای استفاده جهت بازآوری کل صفحهنمایش طراحی نشده است. با پرداز بافر جلو، برنامه محتوا را در بافری پرداز میکند که نمایشگر از آن میخواند. درنتیجه، احتمال ایجاد آرتیفکتهای پردازشی یا پارگی تصویر (به زیر مراجعه کنید) وجود دارد.
کتابخانه با تأخیر کم از Android 10 (سطح API ۲۹) و بالاتر و در دستگاههای ChromeOS با Android 10 (سطح API ۲۹) و بالاتر دردسترس است.
وابستگیها
کتابخانه با تأخیر کم مؤلفههایی را برای پیادهسازی رندر میانگیر جلو ارائه میدهد. کتابخانه بهعنوان وابستگی در فایل build.gradle
ماژول برنامه اضافه شده است:
dependencies {
implementation "androidx.graphics:graphics-core:1.0.0-alpha03"
}
پاسخهای تماس GLFrontBufferRenderer
کتابخانه با تأخیر کم شامل میانای
GLFrontBufferRenderer.Callback
است که روشهای زیر را تعریف میکند:
کتابخانه با تأخیر کم درباره نوع دادهای که با
GLFrontBufferRenderer استفاده میکنید نظری ندارد.
بااینحال، کتابخانه دادهها را بهصورت جریانی از صدها نقطه داده پردازش میکند؛ بنابراین، دادههایتان را بهگونهای طراحی کنید که استفاده از حافظه و تخصیص آن بهینه شود.
بازخوانیها
برای فعال کردن بازخوانیهای پردازشی، GLFrontBufferedRenderer.Callback را اجرا کنید و
onDrawFrontBufferedLayer() و onDrawDoubleBufferedLayer() را لغو کنید.
GLFrontBufferedRenderer از فراخوانیهای برگشتی برای ارائه دادههای شما به بهینهترین شکل ممکن استفاده میکند.
val callback = object: GLFrontBufferedRenderer.Callback<DATA_TYPE> {
override fun onDrawFrontBufferedLayer(
eglManager: EGLManager,
bufferInfo: BufferInfo,
transform: FloatArray,
param: DATA_TYPE
) {
// OpenGL for front buffer, short, affecting small area of the screen.
}
override fun onDrawMultiDoubleBufferedLayer(
eglManager: EGLManager,
bufferInfo: BufferInfo,
transform: FloatArray,
params: Collection<DATA_TYPE>
) {
// OpenGL full scene rendering.
}
}
یک نمونه از GLFrontBufferedRenderer را اعلام کنید
GLFrontBufferedRenderer را با ارائه SurfaceView و
برگشتهای تماسی که قبلاً ایجاد کردهاید آماده کنید. GLFrontBufferedRenderer بااستفاده از فراخوانهای برگشتی شما،
پرداخت را برای میانگیر جلو و دوگانه بهینه میکند:
var glFrontBufferRenderer = GLFrontBufferedRenderer<DATA_TYPE>(surfaceView, callbacks)
درحال پرداز زدن
وقتی روش renderFrontBufferedLayer() را فراخوانی میکنید، رندر کردن میانگیر جلو شروع میشود و این کار باعث راهاندازی فراخوانی onDrawFrontBufferedLayer() میشود.
وقتی تابع
commit()
را فراخوانی میکنید، پرداز با میانگیر دوگانه ازسر گرفته میشود و این کار باعث راهاندازی فراخوان برگشتی onDrawMultiDoubleBufferedLayer() میشود.
در مثال زیر، وقتی کاربر شروع به طراحی روی صفحه میکند (ACTION_DOWN) و اشارهگر را حرکت میدهد (ACTION_MOVE)، فرایند در میانگیر جلو (پرداخت سریع) پرداخت میشود. وقتی اشارهگر سطح صفحه را ترک میکند (ACTION_UP)، فرایند در میانگیر دوگانه پرداخت میشود.
میتوانید از
requestUnbufferedDispatch()
استفاده کنید تا درخواست کنید سیستم ورودی رویدادهای حرکتی را دستهبندی نکند، بلکه آنها را بهمحض دردسترس قرار گرفتن ارائه دهد:
when (motionEvent.action) {
MotionEvent.ACTION_DOWN -> {
// Deliver input events as soon as they arrive.
view.requestUnbufferedDispatch(motionEvent)
// Pointer is in contact with the screen.
glFrontBufferRenderer.renderFrontBufferedLayer(DATA_TYPE)
}
MotionEvent.ACTION_MOVE -> {
// Pointer is moving.
glFrontBufferRenderer.renderFrontBufferedLayer(DATA_TYPE)
}
MotionEvent.ACTION_UP -> {
// Pointer is not in contact in the screen.
glFrontBufferRenderer.commit()
}
MotionEvent.CANCEL -> {
// Cancel front buffer; remove last motion set from the screen.
glFrontBufferRenderer.cancel()
}
}
بایدها و نبایدهای پرداز زدن
بخشهای کوچکی از صفحهنمایش، دستنویسی، نقاشی، طراحی.
بهروزرسانی تمامصفحه، حرکت افقی، بزرگنمایی. میتواند باعث پارگی شود.
پارگی
پارگی زمانی اتفاق میافتد که صفحه بازآوری میشود درحالیکه میانگیر صفحه همزمان درحال اصلاح است. بخشی از صفحه دادههای جدید را نشان میدهد، درحالیکه بخش دیگر دادههای قدیمی را نشان میدهد.
پیشبینی حرکت
کتابخانه پیشبینی حرکت Jetpack با تخمین زدن مسیر ضربه کاربر و ارائه نقاط مصنوعی موقت به رندرکننده، تأخیر درکشده را کاهش میدهد.
کتابخانه پیشبینی حرکت، ورودیهای واقعی کاربر را بهعنوان اشیاء MotionEvent دریافت میکند.
این اشیا حاوی اطلاعاتی درباره مختصات x و y، فشار، و زمان هستند
که پیشبینیکننده حرکت از آنها برای پیشبینی اشیای MotionEvent آینده استفاده میکند.
MotionEvent شیء پیشبینیشده فقط تخمینی هستند. رویدادهای پیشبینیشده میتوانند
تأخیر درکشده را کاهش دهند، اما دادههای پیشبینیشده باید با دادههای واقعی MotionEvent
پساز دریافت جایگزین شوند.
کتابخانه پیشبینی حرکت از Android 4.4 (سطح API ۱۹) و بالاتر و در دستگاههای ChromeOS دارای Android 9 (سطح API ۲۸) و بالاتر دردسترس است.
وابستگیها
کتابخانه پیشبینی حرکت، پیادهسازی پیشبینی را ارائه میدهد. کتابخانه
بهعنوان وابستگی در فایل build.gradle ماژول برنامه اضافه شده است:
dependencies {
implementation "androidx.input:input-motionprediction:1.0.0-beta01"
}
پیادهسازی
کتابخانه پیشبینی حرکت شامل میانای
MotionEventPredictor
است که روشهای زیر را تعریف میکند:
record():MotionEventشیء را بهعنوان سابقهای از کنشهای کاربر ذخیره میکندpredict():MotionEventپیشبینیشده را برمیگرداند
نمونهای از MotionEventPredictor را اعلام کنید
var motionEventPredictor = MotionEventPredictor.newInstance(view)
تغذیه پیشبینیکننده با دادهها
motionEventPredictor.record(motionEvent)
پیشبینی کردن
when (motionEvent.action) {
MotionEvent.ACTION_MOVE -> {
val predictedMotionEvent = motionEventPredictor?.predict()
if(predictedMotionEvent != null) {
// use predicted MotionEvent to inject a new artificial point
}
}
}
بایدها و نبایدهای پیشبینی حرکت
وقتی نقطه پیشبینیشده جدیدی اضافه میشود، نقاط پیشبینی را بردارید.
از نقاط پیشبینی برای پرداخت نهایی استفاده نکنید.
برنامههای یادداشتبرداری
ChromeOS به برنامه شما امکان میدهد برخیاز کنشهای یادداشتبرداری را اعلام کند.
برای ثبت برنامه بهعنوان برنامه یادداشتبرداری در ChromeOS، به سازگاری ورودی مراجعه کنید.
برای ثبت برنامه بهعنوان برنامه یادداشتبرداری در Android، به ایجاد برنامه یادداشتبرداری مراجعه کنید.
Android 14 (سطح میانای برنامهسازی کاربردی ۳۴)
ACTION_CREATE_NOTE
را معرفی کرد که به برنامه شما امکان میدهد فعالیت یادداشتبرداری را در صفحه قفل
شروع کند.
تشخیص جوهر دیجیتال با ML Kit
با تشخیص جوهر دیجیتال ML Kit، برنامه شما میتواند نوشتار دستنویس را روی سطح دیجیتال به صدها زبان تشخیص دهد. همچنین میتوانید طرحها را طبقهبندی کنید.
«کیت یادگیری ماشین» کلاس
Ink.Stroke.Builder
را برای ایجاد اشیاء Ink ارائه میدهد که میتوانند توسط مدلهای یادگیری ماشین پردازش شوند تا دستنوشته را به نوشتار تبدیل کنند.
علاوهبر تشخیص دستنویس، این مدل میتواند اشارهها مثل حذف و دایره کشیدن را تشخیص دهد.
برای کسب اطلاعات بیشتر، به تشخیص جوهر دیجیتال مراجعه کنید.