در دستگاههای صفحهنمایش بزرگ، کاربران اغلب با استفاده از صفحهکلید، ماوس، ترکپد، قلم، یا گیمپد با برنامهها تعامل دارند. برای فعال کردن برنامه خود برای پذیرش ورودی از دستگاه های خارجی، موارد زیر را انجام دهید:
- پشتیبانی اولیه از صفحه کلید را آزمایش کنید ، مانند Ctrl+Z برای لغو، Ctrl+C برای کپی و Ctrl+S برای ذخیره. برای فهرستی از میانبرهای پیشفرض صفحه کلید ، به کنترل عملکردهای صفحهکلید مراجعه کنید.
- پشتیبانی پیشرفته صفحهکلید را آزمایش کنید ، بهعنوان مثال، پیمایش صفحهکلید کلید Tab و پیکان، تأیید ورود متن کلید را وارد کنید ، و Spacebar پخش و مکث در برنامههای رسانهای.
- فعل و انفعالات اساسی ماوس را آزمایش کنید ، از جمله کلیک راست برای منوی زمینه، تغییرات نماد در شناور، و رویدادهای اسکرول چرخ ماوس یا صفحه لمسی در اجزای سفارشی.
- دستگاههای ورودی مخصوص برنامه مانند قلم، کنترلکنندههای بازی، و کنترلکنندههای MIDI برنامه موسیقی را آزمایش کنید .
- پشتیبانی ورودی پیشرفته را در نظر بگیرید که میتواند برنامه را در محیطهای دسکتاپ متمایز کند، بهعنوان مثال، پد لمسی بهعنوان یک فیدر متقاطع برای برنامههای دیجی، ضبط ماوس برای بازیها، و میانبرهای صفحهکلید برای کاربران صفحهکلید محور.
صفحه کلید
روشی که برنامه شما به ورودی صفحهکلید پاسخ میدهد به تجربه کاربر صفحه بزرگ کمک میکند. سه نوع ورودی صفحه کلید وجود دارد: ناوبری ، فشار دادن کلید ، و میانبر .
ناوبری
پیمایش صفحهکلید به ندرت در برنامههای لمس محور اجرا میشود، اما کاربران زمانی که از یک برنامه استفاده میکنند و دستشان روی صفحهکلید است، انتظار آن را دارند. ناوبری صفحهکلید میتواند در تلفنها، تبلتها، تاشوها و دستگاههای رومیزی برای کاربرانی که نیازهای دسترسی دارند ضروری باشد.
برای بسیاری از برنامهها، کلید پیکان و پیمایش کلید Tab به طور خودکار توسط چارچوب Android مدیریت میشوند. به عنوان مثال، برخی از composable ها به طور پیش فرض قابل فوکوس هستند، مانند یک Button
یا یک Composable با تغییر دهنده clickable
. پیمایش صفحه کلید معمولاً باید بدون کد اضافی کار کند. برای فعال کردن پیمایش صفحهکلید برای کامپوزیشنهای سفارشی که بهطور پیشفرض قابل فوکوس نیستند، اصلاحکننده focusable
را اضافه کنید:
var color by remember { mutableStateOf(Green) } Box( Modifier .background(color) .onFocusChanged { color = if (it.isFocused) Blue else Green } .focusable() ) { Text("Focusable 1") }
برای اطلاعات بیشتر، به ساختن یک فوکوس پذیر قابل ترکیب مراجعه کنید.
هنگامی که فوکوس فعال است، چارچوب Android یک نقشه ناوبری برای همه اجزای قابل فوکوس بر اساس موقعیت آنها ایجاد می کند. این معمولاً مطابق انتظار عمل می کند و نیازی به توسعه بیشتر نیست.
با این حال، Compose همیشه مورد بعدی صحیح را برای پیمایش زبانهها برای ترکیبپذیرهای پیچیده مانند برگهها و فهرستها تعیین نمیکند، به عنوان مثال، زمانی که یکی از قابلیتهای composable یک اسکرول افقی است که به طور کامل قابل مشاهده نیست.
برای کنترل رفتار فوکوس، اصلاحکننده focusGroup
را به والد قابل ترکیب مجموعهای از ترکیبپذیرها اضافه کنید. فوکوس به گروه منتقل می شود، سپس از طریق گروه قبل از حرکت به مؤلفه قابل تمرکز بعدی، به عنوان مثال:
Row {
Column(Modifier.focusGroup()) {
Button({}) { Text("Row1 Col1") }
Button({}) { Text("Row2 Col1") }
Button({}) { Text("Row3 Col1") }
}
Column(Modifier.focusGroup()) {
Button({}) { Text("Row1 Col2") }
Button({}) { Text("Row2 Col2") }
Button({}) { Text("Row3 Col2") }
}
}
برای اطلاعات بیشتر، به ارائه پیمایش منسجم با گروههای کانونی مراجعه کنید.
فقط با استفاده از صفحه کلید دسترسی به هر عنصر رابط کاربری برنامه خود را آزمایش کنید. عناصری که اغلب استفاده می شوند باید بدون ورودی ماوس یا لمسی در دسترس باشند.
به یاد داشته باشید، پشتیبانی از صفحه کلید ممکن است برای کاربرانی که نیازهای دسترسی دارند ضروری باشد.
ضربات کلید
برای ورودی متنی که توسط یک صفحه کلید مجازی روی صفحه ( IME ) مدیریت می شود، مانند براییک TextField
، برنامه ها باید همانطور که انتظار می رود در دستگاه های صفحه نمایش بزرگ بدون کار توسعه اضافی رفتار کنند. برای کلیدهایی که توسط چارچوب قابل پیش بینی نیست، برنامه ها باید خودشان رفتار را مدیریت کنند. این امر به ویژه برای برنامه هایی با نمای سفارشی صادق است.
برخی از نمونهها برنامههای چت هستند که از کلید Enter برای ارسال پیام استفاده میکنند، برنامههای رسانهای که پخش را با Spacebar شروع و متوقف میکنند و بازیهایی که حرکت را با کلیدهای w ، a ، s و d کنترل میکنند.
میتوانید ضربههای کلیدی جداگانه را با اصلاحکننده onKeyEvent
انجام دهید، که لامبدا را میپذیرد که وقتی مؤلفه اصلاحشده یک رویداد کلیدی را دریافت میکند، فراخوانی میشود. ویژگی KeyEvent#type
شما را قادر میسازد تا تعیین کنید که آیا رویداد فشار دادن کلید ( KeyDown
) یا انتشار کلید ( KeyUp
) است:
Box(
modifier = Modifier.focusable().onKeyEvent {
if(
it.type == KeyEventType.KeyUp &&
it.key == Key.S
) {
doSomething()
true
} else {
false
}
}
) {
Text("Press S key")
}
همچنین، میتوانید فراخوانی onKeyUp()
را لغو کنید و رفتار مورد انتظار را برای هر کد کلید دریافتی اضافه کنید:
override fun onKeyUp(keyCode: Int, event: KeyEvent): Boolean { return when (keyCode) { KeyEvent.KEYCODE_ENTER -> { sendChatMessage() true } KeyEvent.KEYCODE_SPACE -> { playOrPauseMedia() true } else -> super.onKeyUp(keyCode, event) } }
یک رویداد onKeyUp
زمانی رخ می دهد که یک کلید آزاد شود. اگر کلیدی به آرامی نگه داشته شود یا به آرامی رها شود، استفاده از پاسخ به تماس، از نیاز برنامهها به پردازش چندین رویداد onKeyDown
جلوگیری میکند. بازیها و برنامههایی که باید لحظه فشار دادن یک کلید را تشخیص دهند یا اینکه کاربر کلیدی را پایین نگه داشته است، میتوانند به رویداد onKeyDown
گوش دهند و رویدادهای تکراری onKeyDown
خودشان مدیریت کنند.
برای اطلاعات بیشتر، به کنترل عملکردهای صفحه کلید مراجعه کنید.
میانبرها
هنگام استفاده از صفحه کلید سختافزاری، میانبرهای رایج صفحه کلید که شامل کلیدهای Ctrl ، Alt ، Shift و Meta میشوند، انتظار میرود. اگر یک برنامه میانبرها را پیاده سازی نکند، تجربه می تواند برای کاربران خسته کننده باشد. کاربران پیشرفته همچنین از میانبرها برای کارهای خاص برنامه که اغلب استفاده می شوند قدردانی می کنند. میانبرها استفاده از برنامه را آسان تر می کند و آن را از برنامه هایی که میانبر ندارند متمایز می کند.
برخی از میانبرهای رایج عبارتند از Ctrl+S (ذخیره)، Ctrl+Z (لغو) و Ctrl+Shift+Z (دوباره). برای فهرستی از میانبرهای پیش فرض، به کنترل عملکردهای صفحه کلید مراجعه کنید.
یک شی KeyEvent
دارای ویژگی های زیر است که نشان می دهد آیا کلیدهای اصلاح کننده فشرده شده اند یا خیر:
به عنوان مثال:
Box(
Modifier.onKeyEvent {
if (it.isAltPressed && it.key == Key.A) {
println("Alt + A is pressed")
true
} else {
false
}
}
.focusable()
)
برای اطلاعات بیشتر به ادامه مطلب مراجعه کنید:
قلم
بسیاری از دستگاه های صفحه نمایش بزرگ دارای قلم هستند. برنامههای اندروید قلمها را به عنوان ورودی صفحه لمسی کنترل میکنند. ممکن است برخی از دستگاهها مانند Wacom Intuos دارای یک میز طراحی USB یا بلوتوث باشند. برنامههای اندروید میتوانند ورودی بلوتوث را دریافت کنند اما ورودی USB را دریافت نمیکنند.
برای دسترسی به اشیاء استایلوس MotionEvent
، مدیفایر pointerInteropFilter
را به سطح طراحی اضافه کنید. یک کلاس ViewModel
را با روشی که رویدادهای حرکت را پردازش می کند، پیاده سازی کنید. متد را به عنوان onTouchEvent
lambda اصلاح کننده pointerInteropFilter
ارسال کنید:
@Composable
@OptIn(ExperimentalComposeUiApi::class)
fun DrawArea(modifier: Modifier = Modifier) {
Canvas(modifier = modifier
.clipToBounds()
.pointerInteropFilter {
viewModel.processMotionEvent(it)
}
) {
// Drawing code here.
}
}
شی MotionEvent
حاوی اطلاعاتی در مورد رویداد است:
-
MotionEvent#getToolType()
بسته به ابزاری که با نمایشگر تماس برقرار کرده است،TOOL_TYPE_FINGER
،TOOL_TYPE_STYLUS
، یاTOOL_TYPE_ERASER
را برمی گرداند. -
MotionEvent#getPressure()
فشار فیزیکی اعمال شده به قلم استایلوس را گزارش میکند (در صورت پشتیبانی) -
MotionEvent#getAxisValue()
باMotionEvent.AXIS_TILT
وMotionEvent.AXIS_ORIENTATION
شیب فیزیکی و جهتگیری قلم را ارائه میکند (در صورت پشتیبانی)
نکات تاریخی
Android رویدادهای ورودی را دستهبندی میکند و آنها را یک بار در هر فریم ارائه میکند. یک قلم می تواند رویدادها را با فرکانس های بسیار بالاتر از نمایشگر گزارش دهد. هنگام ایجاد برنامه های طراحی، با استفاده از getHistorical
API ها، رویدادهایی را که ممکن است در گذشته نزدیک باشند بررسی کنید:
-
MotionEvent#getHistoricalX()
-
MotionEvent#getHistoricalY()
-
MotionEvent#getHistoricalPressure()
-
MotionEvent#getHistoricalAxisValue()
رد کف دست
هنگامی که کاربران با استفاده از قلم طراحی می کنند، می نویسند یا با برنامه شما تعامل می کنند، گاهی اوقات صفحه را با کف دست لمس می کنند. رویداد لمسی (روی ACTION_DOWN
یا ACTION_POINTER_DOWN
تنظیم شده است) را می توان قبل از اینکه سیستم لمس ناخواسته کف دست را تشخیص دهد و نادیده بگیرد، به برنامه شما گزارش شود.
Android رویدادهای لمس کف دست را با ارسال MotionEvent
لغو میکند. اگر برنامه شما ACTION_CANCEL
را دریافت کرد، حرکت را لغو کنید. اگر برنامه شما ACTION_POINTER_UP
دریافت کرد، بررسی کنید که آیا FLAG_CANCELED
تنظیم شده است یا خیر. اگر چنین است، ژست را لغو کنید.
فقط FLAG_CANCELED
را بررسی نکنید. در Android 13 (سطح API 33) و بالاتر، سیستم FLAG_CANCELED
برای رویدادهای ACTION_CANCEL
تنظیم میکند، اما سیستم پرچم را در نسخههای پایینتر Android تنظیم نمیکند.
اندروید 12
در Android 12 (سطح API 32) و پایینتر، تشخیص رد کف دست فقط برای رویدادهای لمسی تک اشارهای امکانپذیر است. اگر لمس کف دست تنها نشانگر باشد، سیستم با تنظیم ACTION_CANCEL
روی شی رویداد حرکتی، رویداد را لغو میکند. اگر سایر نشانگرها پایین باشند، سیستم ACTION_POINTER_UP
را تنظیم می کند که برای تشخیص رد کف دست کافی نیست.
اندروید 13
در Android 13 (سطح API 33) و بالاتر، اگر تنها اشارهگر لمس کف دست باشد، سیستم با تنظیم ACTION_CANCEL
و FLAG_CANCELED
روی شی رویداد حرکتی، رویداد را لغو میکند. اگر سایر نشانگرها پایین باشند، سیستم ACTION_POINTER_UP
و FLAG_CANCELED
تنظیم میکند.
هر زمان که برنامه شما یک رویداد حرکتی با ACTION_POINTER_UP
دریافت کرد، FLAG_CANCELED
را بررسی کنید تا مشخص شود آیا رویداد نشان دهنده رد کف دست (یا لغو رویداد دیگر) است.
برنامه های یادداشت برداری
ChromeOS هدف خاصی دارد که برنامههای ثبتشده یادداشتبرداری را در اختیار کاربران قرار میدهد. برای ثبت یک برنامه به عنوان یک برنامه یادداشت برداری، موارد زیر را به مانیفست برنامه خود اضافه کنید:
<intent-filter>
<action android:name="org.chromium.arc.intent.action.CREATE_NOTE" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
وقتی یک برنامه در سیستم ثبت می شود، کاربر می تواند آن را به عنوان برنامه پیش فرض یادداشت برداری انتخاب کند. وقتی یادداشت جدیدی درخواست میشود، برنامه باید یک یادداشت خالی آماده برای ورودی قلم ایجاد کند. هنگامی که کاربر می خواهد یک تصویر را حاشیه نویسی کند (مانند یک اسکرین شات یا تصویر بارگیری شده)، برنامه با ClipData
شامل یک یا چند مورد با content://
URI راه اندازی می شود. برنامه باید یادداشتی ایجاد کند که از اولین تصویر پیوست شده به عنوان تصویر پسزمینه استفاده کند و حالتی را وارد کند که کاربر بتواند با یک قلم روی صفحه نمایش بکشد.
اهداف یادداشت برداری را بدون قلم تست کنید
[بخش حذف TBD.]
برای آزمایش اینکه آیا یک برنامه بدون قلم فعال به اهداف یادداشتبرداری به درستی پاسخ میدهد، از روش زیر برای نمایش گزینههای یادداشتبرداری در ChromeOS استفاده کنید:
- به حالت توسعه دهنده بروید و دستگاه را قابل نوشتن کنید
- Ctrl+Alt+F2 را فشار دهید تا ترمینال باز شود
- دستور
sudo vi /etc/chrome_dev.conf
را اجرا کنید -
i
برای ویرایش فشار دهید و--ash-enable-palette
به خط جدیدی در انتهای فایل اضافه کنید - با فشار دادن Esc و سپس تایپ کردن : , w , q و فشردن Enter ذخیره کنید
- برای بازگشت به رابط کاربری عادی ChromeOS ، Ctrl+Alt+F1 را فشار دهید
- از سیستم خارج شوید، سپس دوباره وارد شوید
یک منوی قلم اکنون باید در قفسه باشد:
- روی دکمه قلم در قفسه ضربه بزنید و یادداشت جدید را انتخاب کنید. این باید یک یادداشت نقاشی خالی را باز کند.
- اسکرین شات بگیرید از قفسه، دکمه قلم > ضبط صفحه را انتخاب کنید یا یک تصویر را دانلود کنید. باید گزینه Annotate image در اعلان وجود داشته باشد. این باید برنامه را با تصویر آماده برای حاشیه نویسی راه اندازی کند.
پشتیبانی از ماوس و تاچ پد
اکثر برنامهها معمولاً فقط به سه رویداد بزرگ صفحهنمایش نیاز دارند: کلیک راست ، شناور ، و کشیدن و رها کردن .
کلیک راست کنید
هر اقدامی که باعث میشود برنامه منوی زمینه را نشان دهد، مانند لمس و نگهداشتن یک مورد فهرست، باید به رویدادهای کلیک راست نیز واکنش نشان دهد.
برای مدیریت رویدادهای کلیک راست، برنامهها باید یک View.OnContextClickListener
ثبت کنند.OnContextClickListener:
Box(modifier = Modifier.fillMaxSize()) {
AndroidView(
modifier = Modifier.fillMaxSize(),
factory = { context ->
val rootView = FrameLayout(context)
val onContextClickListener =
View.OnContextClickListener { view ->
showContextMenu()
true
}
rootView.setOnContextClickListener(onContextClickListener)
rootView
},
)
}
برای جزئیات در مورد ساخت منوهای زمینه، به ایجاد یک منوی متنی مراجعه کنید.
شناور
میتوانید با مدیریت رویدادهای شناور، چیدمانهای برنامهتان را صیقلیتر و آسانتر کنید. این به ویژه در مورد عرف صادق استاجزاء:
دو نمونه رایج در این مورد عبارتند از:
- با تغییر نماد اشاره گر ماوس به کاربران نشان می دهد که آیا یک عنصر رفتار تعاملی دارد، مانند قابل کلیک یا قابل ویرایش بودن
- افزودن بازخورد بصری به موارد موجود در یک لیست یا شبکه بزرگ هنگامی که نشانگر روی آنها قرار دارد
بکشید و رها کنید
در یک محیط چند پنجره ای، کاربران انتظار دارند که بتوانند آیتم ها را بین برنامه ها بکشند و رها کنند. این امر برای دستگاههای رومیزی و همچنین تبلتها، تلفنها، و تاشوها در حالت تقسیم صفحه صادق است.
در نظر بگیرید که آیا کاربران ممکن است موارد را به برنامه شما بکشند یا خیر. به عنوان مثال، ویرایشگرهای عکس باید انتظار دریافت عکس، پخش کننده های صوتی را برای دریافت فایل های صوتی و برنامه های طراحی باید انتظار دریافت عکس داشته باشند.
برای افزودن پشتیبانی کشیدن و رها کردن، رجوع کنیدبکشید و رها کنیدو نگاهی به Android در ChromeOS بیاندازید — پیاده سازی پست وبلاگ Drag & Drop .
ملاحظات ویژه برای ChromeOS
- به خاطر داشته باشید که برای دسترسی به مواردی که از خارج از برنامه به داخل کشیده شده اند، با
requestDragAndDropPermissions()
مجوز درخواست کنید. یک مورد باید دارای پرچم
View.DRAG_FLAG_GLOBAL
باشد تا به برنامه های دیگر کشیده شودبه شروع یک رویداد کشیدن مراجعه کنید
پشتیبانی از اشاره گر پیشرفته
برنامههایی که کنترل پیشرفتهای از ورودی ماوس و صفحه لمسی را انجام میدهند باید aتغییر دهنده pointerInput
برای به دست آوردن PointerEvent
:
@Composable private fun LogPointerEvents(filter: PointerEventType? = null) { var log by remember { mutableStateOf("") } Column { Text(log) Box( Modifier .size(100.dp) .background(Color.Red) .pointerInput(filter) { awaitPointerEventScope { while (true) { val event = awaitPointerEvent() // handle pointer event if (filter == null || event.type == filter) { log = "${event.type}, ${event.changes.first().position}" } } } } ) } }
شی PointerEvent
را برای تعیین موارد زیر بررسی کنید:
-
PointerType
: ماوس، قلم، لمس و غیره ازPointerEvent#changes
-
PointerEventType
: اقدامات اشاره گر، مانند فشار دادن، حرکت، اسکرول و رها کردن
کنترلرهای بازی
برخی از دستگاه های اندرویدی با صفحه نمایش بزرگ تا چهار کنترلر بازی را پشتیبانی می کنند. از APIهای استاندارد کنترلر بازی اندروید برای کنترل کنترلرهای بازی استفاده کنید ( به پشتیبانی از کنترلرهای بازی مراجعه کنید).
دکمههای کنترلکننده بازی به دنبال یک نقشهبرداری مشترک به مقادیر رایج نگاشت میشوند. اما همه سازندگان کنترلرهای بازی از قوانین نقشه برداری یکسانی پیروی نمی کنند. اگر به کاربران اجازه دهید تا نگاشت های مختلف کنترلر محبوب را انتخاب کنند، می توانید تجربه بسیار بهتری ارائه دهید. برای اطلاعات بیشتر به فرآیند فشار دادن دکمه گیم پد مراجعه کنید.
حالت ترجمه ورودی
ChromeOS حالت ترجمه ورودی را به طور پیشفرض فعال میکند. برای اکثر برنامههای اندروید، این حالت به برنامهها کمک میکند تا همانطور که انتظار میرود در محیط دسکتاپ کار کنند. برخی از نمونهها عبارتند از فعال کردن خودکار پیمایش با دو انگشت روی صفحه لمسی، پیمایش چرخ ماوس، و نگاشت مختصات صفحه نمایش خام به مختصات پنجره. به طور کلی، توسعه دهندگان اپلیکیشن نیازی به پیاده سازی هیچ یک از این رفتارها ندارند.
اگر برنامهای رفتار ورودی سفارشی را پیادهسازی کند، بهعنوان مثال، یک عمل چسباندن صفحه لمسی با دو انگشت سفارشی را تعریف کند، یا این ترجمههای ورودی رویدادهای ورودی مورد انتظار برنامه را ارائه نمیکنند، میتوانید حالت ترجمه ورودی را با افزودن برچسب زیر به آن غیرفعال کنید. مانیفست اندروید:
<uses-feature
android:name="android.hardware.type.pc"
android:required="false" />