1. مقدمه
برای اندروید نسخه 10 یا بالاتر، حرکات ناوبری به عنوان یک حالت جدید پشتیبانی می شود. این به برنامه شما امکان میدهد از کل صفحه استفاده کند و تجربه نمایشی همهجانبهتری ارائه دهد. هنگامی که کاربر از لبه پایین صفحه به بالا سوایپ می کند، او را به صفحه اصلی اندروید می برد. هنگامی که آنها از لبه های چپ یا راست به داخل سوایپ می کنند، کاربر را به صفحه قبلی می برد.
با این دو حرکت، برنامه شما میتواند از ویژگیهای واقعی صفحه در پایین صفحه استفاده کند. با این حال، اگر برنامه شما از اشارهها استفاده میکند یا کنترلهایی در قسمتهای اشارهای سیستم دارد، ممکن است با حرکات در سراسر سیستم تضاد ایجاد کند.
این کد لبه قصد دارد به شما یاد دهد که چگونه از inset ها برای جلوگیری از تضاد ژست ها استفاده کنید. علاوه بر این، این کد لبه قصد دارد به شما نحوه استفاده از Gesture Exclusion API را برای کنترلهایی مانند دستگیرههای کشیدن که باید در مناطق اشارهای قرار گیرند، به شما آموزش دهد.
چیزی که یاد خواهید گرفت
- نحوه استفاده از شنوندگان داخلی در نماها
- نحوه استفاده از Gesture Exclusion API
- هنگام فعال بودن حرکات، حالت همهجانبه چگونه رفتار می کند
این کد لبه قصد دارد برنامه شما را با حرکات سیستم سازگار کند. مفاهیم و بلوکهای کد نامربوط محو میشوند و برای کپی و پیست کردن در اختیار شما قرار میگیرند.
چیزی که خواهی ساخت
پخش کننده موسیقی جهانی اندروید (UAMP) یک نمونه برنامه پخش موسیقی برای اندروید است که در Kotlin نوشته شده است. UAMP را برای پیمایش حرکتی راهاندازی خواهید کرد.
- برای دور کردن کنترلها از قسمتهای اشارهای، از ورودیها استفاده کنید
- از Gesture Exclusion API برای انصراف از اشاره عقب برای کنترلهایی که تداخل دارند استفاده کنید
- از ساختهای خود برای کاوش تغییرات رفتاری حالت همهجانبه با ناوبری اشاره استفاده کنید
آنچه شما نیاز دارید
- دستگاه یا شبیهسازی که اندروید 10 یا بالاتر را اجرا میکند
- اندروید استودیو
2. نمای کلی برنامه
پخش کننده موسیقی جهانی اندروید (UAMP) یک نمونه برنامه پخش موسیقی برای اندروید است که به زبان Kotlin نوشته شده است. از ویژگیهایی پشتیبانی میکند که شامل پخش پسزمینه، کنترل فوکوس صوتی، ادغام دستیار، و پلتفرمهای متعددی مانند Wear، TV و Auto میشود.
شکل 1 : یک جریان در UAMP
UAMP یک کاتالوگ موسیقی را از یک سرور راه دور بارگیری می کند و به کاربر امکان می دهد آلبوم ها و آهنگ ها را مرور کند. کاربر روی یک آهنگ ضربه می زند و از طریق بلندگوها یا هدفون های متصل پخش می شود. برنامه برای کار با حرکات سیستم طراحی نشده است. بنابراین، وقتی UAMP را روی دستگاهی اجرا میکنید که اندروید 10 یا بالاتر را اجرا میکند، در ابتدا با مشکلاتی مواجه میشوید.
3. راه اندازی شوید
برای دریافت نمونه برنامه، مخزن را از GitHub کلون کنید و به شاخه شروع کننده بروید:
$ git clone https://github.com/googlecodelabs/android-gestural-navigation/
همچنین میتوانید مخزن را بهصورت فایل فشرده دانلود کنید، آن را از حالت فشرده خارج کنید و در Android Studio باز کنید.
مراحل زیر را کامل کنید:
- برنامه را در Android Studio باز کرده و بسازید.
- یک دستگاه مجازی جدید ایجاد کنید و سطح API 29 را انتخاب کنید. از طرف دیگر، می توانید یک دستگاه واقعی که سطح API 29 یا بالاتر را اجرا می کند، متصل کنید.
- برنامه را اجرا کنید. فهرستی که مشاهده می کنید آهنگ ها را در قسمت های انتخابی توصیه شده و آلبوم ها گروه بندی می کند.
- روی Recommended کلیک کنید و یک آهنگ را از لیست آهنگ ها انتخاب کنید.
- برنامه پخش آهنگ را شروع می کند.
ژست پیمایش را فعال کنید
اگر یک نمونه شبیهساز جدید را با سطح API 29 اجرا میکنید، ممکن است Gesture Navigation بهطور پیشفرض روشن نباشد. برای فعال کردن پیمایش حرکتی، تنظیمات سیستم > سیستم > پیمایش سیستم > پیمایش اشاره ای را انتخاب کنید.
برنامه را با Gesture Navigation اجرا کنید
اگر برنامه را با فعال کردن Gesture Navigation اجرا کنید و پخش یک آهنگ را شروع کنید، ممکن است متوجه شوید که کنترلهای پخشکننده بسیار نزدیک به صفحه اصلی و قسمتهای اشارهای پشتی هستند.
4. لبه به لبه بروید
لبه به لبه چیست؟
برنامههایی که روی Android 10 یا بالاتر اجرا میشوند، میتوانند یک تجربه کامل از لبه به لبه صفحه نمایش را ارائه دهند، صرف نظر از اینکه حرکتها یا دکمهها برای پیمایش فعال هستند یا خیر. برای ارائه یک تجربه لبه به لبه، برنامههای شما باید پشت نوارهای ناوبری و وضعیت شفاف ترسیم کنند.
پشت نوار ناوبری بکشید
برای اینکه برنامه شما بتواند محتوا را در زیر نوار پیمایش ارائه کند، ابتدا باید پسزمینه نوار پیمایش را شفاف کنید. سپس باید نوار وضعیت را شفاف کنید. این به برنامه شما اجازه می دهد تا برنامه شما را در تمام ارتفاع صفحه نمایش دهد.
برای تغییر رنگ نوار ناوبری و نوار وضعیت، مراحل زیر را انجام دهید:
- نوار پیمایش:
res/values-29/styles.xml
را باز کنید وnavigationBarColor
را رویcolor/transparent
تنظیم کنید. - نوار وضعیت: به طور مشابه
statusBarColor
را رویcolor/transparent
تنظیم کنید.
نمونه کد زیر را از res/values-29/styles.xml
مرور کنید:
<!-- change navigation bar color -->
<item name="android:navigationBarColor">
@android:color/transparent
</item>
<!-- change status bar color -->
<item name="android:statusBarColor">
@android:color/transparent
</item>
پرچمهای نمایان بودن رابط کاربری سیستم
همچنین باید پرچمهای مشاهده رابط کاربری سیستم را تنظیم کنید تا به سیستم بگویید برنامه را در زیر نوارهای سیستم قرار دهد. API های systemUiVisibility
در کلاس View
به شما اجازه می دهد تا انواع پرچم ها را تنظیم کنید. مراحل زیر را انجام دهید:
- کلاس
MainActivity.kt
را باز کنید و متدonCreate()
را پیدا کنید. نمونه ای ازfragmentContainer
را دریافت کنید. - موارد زیر را روی
content.systemUiVisibility
تنظیم کنید:
-
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
-
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
-
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
نمونه کد زیر MainActivity.kt
را مرور کنید:
val content: FrameLayout = findViewById(R.id.fragmentContainer)
content.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_STABLE or
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
وقتی این پرچم ها را با هم تنظیم می کنید، به سیستم می گویید که می خواهید برنامه شما تمام صفحه نمایش داده شود، گویی نوارهای ناوبری و وضعیت در آنجا نیستند. مراحل زیر را انجام دهید:
- برنامه را اجرا کنید و برای رفتن به صفحه پخش کننده، آهنگی را برای پخش انتخاب کنید.
- بررسی کنید که کنترلهای پخشکننده زیر نوار پیمایش کشیده شدهاند و دسترسی به آنها را دشوار میکند:
- به تنظیمات سیستم بروید، به حالت ناوبری سه دکمه ای برگردید و به برنامه برگردید.
- بررسی کنید که استفاده از کنترل ها با نوار پیمایش سه دکمه حتی دشوارتر است: توجه داشته باشید که
SeekBar
پشت نوار پیمایش پنهان است و پخش/مکث بیشتر توسط نوار پیمایش پوشانده شده است. - کمی کاوش و آزمایش کنید. پس از اتمام کار، به تنظیمات سیستم بروید و به پیمایش اشاره ای برگردید:
اکنون برنامه در حال ترسیم لبه به لبه است، اما مسائل مربوط به قابلیت استفاده، کنترلهای برنامه وجود دارد که تداخل و همپوشانی دارند، و اینها باید حل شوند.
5. درونی
WindowInsets
به برنامه میگوید که در کجا رابط کاربری سیستم در بالای محتوای شما ظاهر میشود، همراه با کدام مناطق از صفحه، اشارههای سیستم نسبت به حرکات درون برنامه اولویت دارند. Inset ها با کلاس WindowInsets
و کلاس WindowInsetsCompat
در Jetpack نشان داده می شوند. ما قویاً توصیه می کنیم که از WindowInsetsCompat
برای داشتن رفتار ثابت در تمام سطوح API استفاده کنید.
ورودی های سیستم و درج های سیستم اجباری
API های داخلی زیر متداول ترین انواع درونی مورد استفاده هستند:
- ورودی های پنجره سیستم: آنها به شما می گویند که رابط کاربری سیستم در کجا روی برنامه شما نمایش داده می شود. ما در مورد اینکه چگونه میتوانید از ورودیهای سیستم برای دور کردن کنترلهای خود از نوارهای سیستم استفاده کنید، بحث میکنیم.
- درجهای اشارهای سیستم: همه قسمتهای اشاره را برمیگردانند. هر گونه کنترل تند کشیدن داخل برنامه در این مناطق میتواند بهطور تصادفی حرکات سیستم را فعال کند.
- درجهای اشارهای اجباری: زیرمجموعهای از درجهای اشارهای سیستم هستند و نمیتوان آنها را نادیده گرفت. آنها مناطقی از صفحه را به شما می گویند که رفتار حرکات سیستم همیشه بر حرکات درون برنامه اولویت دارد.
برای جابجایی کنترلهای برنامه از insets استفاده کنید
اکنون که درباره API های داخلی اطلاعات بیشتری دارید، می توانید کنترل های برنامه را همانطور که در مراحل زیر توضیح داده شده است، اصلاح کنید:
- نمونه ای از
playerLayout
را از نمونه شیview
دریافت کنید. - یک
OnApplyWindowInsetsListener
بهplayerView
اضافه کنید. - نما را از ناحیه اشاره دور کنید: مقدار درج شده سیستم را برای پایین بیابید و بالشتک نما را تا آن مقدار افزایش دهید. برای بهروزرسانی صفحه نمایش بر این اساس، به [مقدار مرتبط با لایه پایین برنامه]، [مقدار مرتبط با مقدار پایینی درج شده سیستم] را اضافه کنید.
نمونه کد زیر را در NowPlayingFragment.kt
مرور کنید:
playerView = view.findViewById(R.id.playerLayout)
playerView.setOnApplyWindowInsetsListener { view, insets ->
view.updatePadding(
bottom = insets.systemWindowInsetBottom + view.paddingBottom
)
insets
}
- برنامه را اجرا کنید و یک آهنگ را انتخاب کنید. توجه داشته باشید که به نظر می رسد چیزی در کنترل های پخش کننده تغییر نمی کند. اگر نقطه شکست اضافه کنید و برنامه را در اشکال زدایی اجرا کنید، می بینید که شنونده فراخوانی نشده است.
- برای رفع این مشکل، به
FragmentContainerView
بروید، که این مشکل را به طور خودکار کنترل می کند.activity_main.xml
را باز کنید وFrameLayout
بهFragmentContainerView
تغییر دهید.
نمونه کد زیر activity_main.xml
را مرور کنید:
<androidx.fragment.app.FragmentContainerView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/fragmentContainer"
tools:context="com.example.android.uamp.MainActivity"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
- دوباره برنامه را اجرا کنید و به صفحه پخش کننده بروید. کنترلهای پخشکننده پایین از قسمت اشارهای پایینی دور میشوند.
اکنون کنترلهای برنامه با Gesture Navigation کار میکنند، اما کنترلها بیش از حد انتظار حرکت میکنند. شما باید این را حل کنید.
بالشتک ها و حاشیه های فعلی را حفظ کنید
اگر به برنامههای دیگر جابهجا میشوید یا به صفحه اصلی میروید و بدون بستن برنامه به برنامه باز میگردید، متوجه شوید که کنترلهای پخشکننده هر بار به بالا میروند.
این به این دلیل است که برنامه هر بار که فعالیت شروع میشود requestApplyInsets()
را راهاندازی میکند. حتی بدون این تماس، WindowInsets
میتواند چندین بار در هر زمان در طول چرخه حیات یک View ارسال شود.
InsetListener
فعلی در playerView
اولین باری که مقدار پایینی ورودی را به مقدار padding پایین برنامه اعلام شده در activity_main.xml
اضافه میکنید، کاملاً کار میکند. با این حال، تماسهای بعدی به افزودن مقدار پایینی درج شده به صفحه پایین نمای از قبل بهروزرسانی شده ادامه میدهند.
برای رفع این مشکل مراحل زیر را انجام دهید:
- مقدار صفحه نمایش اولیه را ثبت کنید. یک val جدید ایجاد کنید و مقدار نمای اولیه
playerView
را درست قبل از کد شنونده ذخیره کنید.
نمونه کد زیر را در NowPlayingFragment.kt
مرور کنید:
val initialPadding = playerView.paddingBottom
- از این مقدار اولیه برای بهروزرسانی لایه پایینی نما استفاده کنید، که به شما امکان میدهد از استفاده از مقدار لایه پایین فعلی برنامه اجتناب کنید.
نمونه کد زیر را در NowPlayingFragment.kt
مرور کنید:
playerView.setOnApplyWindowInsetsListener { view, insets ->
view.updatePadding(bottom = insets.systemWindowInsetBottom + initialPadding)
insets
}
- دوباره برنامه را اجرا کنید. بین برنامه ها حرکت کنید و به صفحه اصلی بروید. وقتی برنامه را برمیگردانید، کنترلهای پخشکننده درست بالای ناحیه اشارهها قرار دارند.
طراحی مجدد کنترل های برنامه
نوار جستجوی پخشکننده خیلی نزدیک به قسمت اشارهای پایینی است، به این معنی که کاربر میتواند بهطور تصادفی ژست خانه را هنگامی که تند کشیدن افقی را انجام میدهد فعال کند. اگر بالشتک را حتی بیشتر افزایش دهید، می تواند مشکل را برطرف کند، اما همچنین ممکن است پخش کننده را بالاتر از حد دلخواه حرکت دهد.
استفاده از insets به شما امکان میدهد تضاد ژستها را برطرف کنید، اما گاهی اوقات با تغییرات کوچک در طراحی، میتوانید به طور کامل از تضاد ژستها جلوگیری کنید. برای طراحی مجدد کنترلهای پخش کننده برای جلوگیری از تداخل حرکات، مراحل زیر را انجام دهید:
-
fragment_nowplaying.xml
را باز کنید. به نمای طراحی بروید وSeekBar
در پایین صفحه انتخاب کنید:
- به نمای کد بروید.
- برای انتقال
SeekBar
به بالایplayerLayout
،layout_constraintTop_toBottomOf
از SeekBar را بهparent
تغییر دهید. - برای محدود کردن سایر موارد موجود در
playerView
به پایینSeekBar
،layout_constraintTop_toTopOf
از والد به@+id/seekBar
درmedia_button
،title
وposition
تغییر دهید.
نمونه کد زیر را از fragment_nowplaying.xml
مرور کنید:
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="8dp"
android:layout_gravity="bottom"
android:background="@drawable/media_overlay_background"
android:id="@+id/playerLayout">
<ImageButton
android:id="@+id/media_button"
android:layout_width="@dimen/exo_media_button_width"
android:layout_height="@dimen/exo_media_button_height"
android:background="?attr/selectableItemBackground"
android:scaleType="centerInside"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="@+id/seekBar"
app:srcCompat="@drawable/ic_play_arrow_black_24dp"
tools:ignore="ContentDescription" />
<TextView
android:id="@+id/title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginStart="@dimen/text_margin"
android:layout_marginEnd="@dimen/text_margin"
android:ellipsize="end"
android:maxLines="1"
android:textAppearance="@style/TextAppearance.Uamp.Title"
app:layout_constraintTop_toTopOf="@+id/seekBar"
app:layout_constraintLeft_toRightOf="@id/media_button"
app:layout_constraintRight_toLeftOf="@id/position"
tools:text="Song Title" />
<TextView
android:id="@+id/subtitle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/text_margin"
android:layout_marginEnd="@dimen/text_margin"
android:ellipsize="end"
android:maxLines="1"
android:textAppearance="@style/TextAppearance.Uamp.Subtitle"
app:layout_constraintTop_toBottomOf="@+id/title"
app:layout_constraintLeft_toRightOf="@id/media_button"
app:layout_constraintRight_toLeftOf="@id/position"
tools:text="Artist" />
<TextView
android:id="@+id/position"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginStart="@dimen/text_margin"
android:layout_marginEnd="@dimen/text_margin"
android:ellipsize="end"
android:maxLines="1"
android:textAppearance="@style/TextAppearance.Uamp.Title"
app:layout_constraintTop_toTopOf="@+id/seekBar"
app:layout_constraintRight_toRightOf="parent"
tools:text="0:00" />
<TextView
android:id="@+id/duration"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/text_margin"
android:layout_marginEnd="@dimen/text_margin"
android:ellipsize="end"
android:maxLines="1"
android:textAppearance="@style/TextAppearance.Uamp.Subtitle"
app:layout_constraintTop_toBottomOf="@id/position"
app:layout_constraintRight_toRightOf="parent"
tools:text="0:00" />
<SeekBar
android:id="@+id/seekBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
- برنامه را اجرا کنید و با پخش کننده و نوار جستجو تعامل داشته باشید.
این تغییرات حداقلی طراحی به طور قابل توجهی برنامه را بهبود می بخشد.
6. Gesture Exclusion API
کنترلهای پخش کننده برای تداخل ژستها در ناحیه اشاره خانه ثابت هستند. ناحیه ژستهای پشتی نیز میتواند با کنترلهای برنامه تداخل ایجاد کند. اسکرین شات زیر نشان می دهد که نوار جستجوی بازیکن در حال حاضر در هر دو ناحیه اشاره سمت راست و چپ قرار دارد:
SeekBar
به طور خودکار تضادهای اشاره را کنترل می کند. با این حال، ممکن است لازم باشد از سایر مؤلفههای رابط کاربری استفاده کنید که تداخل حرکتی را ایجاد میکنند. در این موارد، میتوانید از Gesture Exclusion API
برای انصراف جزئی از ژست برگشتی استفاده کنید.
از Gesture Exclusion API استفاده کنید
برای ایجاد یک منطقه حذف ژست، setSystemGestureExclusionRects()
را در نمای خود با لیستی از اشیاء rect
فراخوانی کنید. این اشیاء rect
به مختصات مناطق مستطیل مستثنی شده نگاشت می شوند. این فراخوانی باید در متدهای onLayout()
یا onDraw()
view انجام شود. برای این کار مراحل زیر را انجام دهید:
- یک بسته جدید با نام
view
ایجاد کنید. - برای فراخوانی این API، یک کلاس جدید به نام
MySeekBar
ایجاد کنید وAppCompatSeekBar
گسترش دهید.
نمونه کد زیر MySeekBar.kt
را مرور کنید:
class MySeekBar @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyle: Int = android.R.attr.seekBarStyle
) : androidx.appcompat.widget.AppCompatSeekBar(context, attrs, defStyle) {
}
- یک متد جدید به نام
updateGestureExclusion()
ایجاد کنید.
نمونه کد زیر MySeekBar.kt
را مرور کنید:
private fun updateGestureExclusion() {
}
- برای رد شدن از این تماس در سطح API 28 یا پایینتر، یک بررسی اضافه کنید.
نمونه کد زیر MySeekBar.kt
را مرور کنید:
private fun updateGestureExclusion() {
// Skip this call if we're not running on Android 10+
if (Build.VERSION.SDK_INT < 29) return
}
- از آنجایی که Gesture Exclusion API دارای محدودیت 200 dp است، فقط انگشت شست نوار جستجو را حذف کنید. یک کپی از کران های seekbar دریافت کنید و هر شی را به یک لیست قابل تغییر اضافه کنید.
نمونه کد زیر MySeekBar.kt
را مرور کنید:
private val gestureExclusionRects = mutableListOf<Rect>()
private fun updateGestureExclusion() {
// Skip this call if we're not running on Android 10+
if (Build.VERSION.SDK_INT < 29) return
thumb?.also { t ->
gestureExclusionRects += t.copyBounds()
}
}
- با لیستهای
gestureExclusionRects
که ایجاد میکنیدsystemGestureExclusionRects()
را فراخوانی کنید.
نمونه کد زیر MySeekBar.kt
را مرور کنید:
private val gestureExclusionRects = mutableListOf<Rect>()
private fun updateGestureExclusion() {
// Skip this call if we're not running on Android 10+
if (Build.VERSION.SDK_INT < 29) return
thumb?.also { t ->
gestureExclusionRects += t.copyBounds()
}
// Finally pass our updated list of rectangles to the system
systemGestureExclusionRects = gestureExclusionRects
}
- متد
updateGestureExclusion()
را ازonDraw()
یاonLayout()
فراخوانی کنید.onDraw()
را لغو کنید و یک فراخوان بهupdateGestureExclusion
اضافه کنید.
نمونه کد زیر MySeekBar.kt
را مرور کنید:
override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
updateGestureExclusion()
}
- شما باید مراجع
SeekBar
به روز کنید. برای شروع،fragment_nowplaying.xml
را باز کنید. -
SeekBar
بهcom.example.android.uamp.view.MySeekBar
تغییر دهید.
نمونه کد زیر را از fragment_nowplaying.xml
مرور کنید:
<com.example.android.uamp.view.MySeekBar
android:id="@+id/seekBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="parent" />
- برای بهروزرسانی مراجع
SeekBar
درNowPlayingFragment.kt
،NowPlayingFragment.kt
را باز کنید و نوعpositionSeekBar
را بهMySeekBar
تغییر دهید. برای مطابقت با نوع متغیر، ژنریکSeekBar
برای فراخوانfindViewById
بهMySeekBar
تغییر دهید.
نمونه کد زیر را در NowPlayingFragment.kt
مرور کنید:
val positionSeekBar: MySeekBar = view.findViewById<MySeekBar>(
R.id.seekBar
).apply { progress = 0 }
- برنامه را اجرا کنید و با
SeekBar
تعامل کنید. اگر همچنان تداخل حرکتی را تجربه میکنید، میتوانید مرزهای انگشت شست را درMySeekBar
آزمایش کرده و تغییر دهید. مراقب باشید که یک منطقه حذف اشاره بزرگتر از حد لازم ایجاد نکنید، زیرا این امر دیگر تماسهای بالقوه حذف اشاره را محدود میکند و رفتار ناسازگاری برای کاربر ایجاد میکند.
7. تبریک می گویم
تبریک می گویم! شما یاد گرفته اید که چگونه از تضادها اجتناب کنید و با حرکات سیستم آن را حل کنید!
هنگامی که لبه به لبه را گسترش دادید و از ورودیها برای دور کردن کنترلهای برنامه از مناطق اشارهای استفاده کردید، برنامهتان را مجبور کردید از تمام صفحه استفاده کند. همچنین یاد گرفتید که چگونه ژست برگشتی سیستم را در کنترل های برنامه غیرفعال کنید.
اکنون مراحل کلیدی مورد نیاز برای کارکرد برنامه های خود با حرکات سیستم را می دانید!
مواد اضافی
- WindowInsets - شنوندگان طرحبندیها
- پیمایش حرکتی: لبه به لبه
- ناوبری اشاره: مدیریت همپوشانی های بصری
- پیمایش ژستها: مدیریت درگیریهای ژستها
- از سازگاری با ناوبری اشاره ای اطمینان حاصل کنید