ออกจากกิจกรรมแบบเต็มหน้าจอใน Wear
จัดทุกอย่างให้เป็นระเบียบอยู่เสมอด้วยคอลเล็กชัน
บันทึกและจัดหมวดหมู่เนื้อหาตามค่ากำหนดของคุณ
ลองใช้วิธีเขียน
Jetpack Compose ใน Wear OS เป็นชุดเครื่องมือ UI ที่แนะนำสำหรับ Wear OS
ผู้ใช้สามารถออกจากกิจกรรม Wear OS ได้โดยการปัดจากซ้ายไปขวา
หากแอปมีการเลื่อนแนวนอน ผู้ใช้จะออกโดยไปยังขอบของเนื้อหาแล้วปัดจากซ้ายไปขวา
การกดปุ่มเปิด/ปิดยังจะนำผู้ใช้กลับไปที่หน้าปัดด้วย
ท่าทางสัมผัสด้วยการปัดเพื่อปิด
ผู้ใช้ปัดจากซ้ายไปขวาเพื่อปิดหน้าจอปัจจุบัน เราจึงขอแนะนําให้คุณใช้สิ่งต่อไปนี้
-
เลย์เอาต์แนวตั้ง
-
คอนเทนเนอร์เนื้อหา
นอกจากนี้ เราขอแนะนําว่าแอปของคุณไม่ควรมีท่าทางสัมผัสด้วยการปัดแนวนอน
ปิดกิจกรรม
กิจกรรมรองรับการปัดเพื่อปิดโดยอัตโนมัติ การปัดกิจกรรมจากซ้ายไปขวาจะเป็นการปิดกิจกรรมนั้น และแอปจะไปยัง
กองซ้อนที่ย้อนกลับ
ปิดการ์ด
หากต้องการรองรับการปัดเพื่อปิดในฟragment คุณต้องรวมมุมมองที่มีฟragment ไว้ในคลาส
SwipeDismissFrameLayout
โปรดคำนึงถึงเรื่องนี้เมื่อตัดสินใจว่าจะใช้ข้อมูลโค้ดที่ตัดตอนมาหรือไม่ ใช้คลาส SwipeDismissFrameLayout
ดังที่แสดงในตัวอย่างต่อไปนี้
Kotlin
class SwipeDismissFragment : Fragment() {
private val callback = object : SwipeDismissFrameLayout.Callback() {
override fun onSwipeStarted(layout: SwipeDismissFrameLayout) {
// Optional
}
override fun onSwipeCanceled(layout: SwipeDismissFrameLayout) {
// Optional
}
override fun onDismissed(layout: SwipeDismissFrameLayout) {
// Code here for custom behavior, such as going up the
// back stack and destroying the fragment but staying in the app.
}
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View =
SwipeDismissFrameLayout(activity).apply {
// If the fragment should fill the screen (optional), then in the layout file,
// in the androidx.wear.widget.SwipeDismissFrameLayout element,
// set the android:layout_width and android:layout_height attributes
// to "match_parent".
inflater.inflate(
R.layout.swipe_dismiss_frame_layout,
this,
false
).also { inflatedView ->
addView(inflatedView)
}
addCallback(callback)
}
}
Java
public class SwipeDismissFragment extends Fragment {
private final Callback callback =
new Callback() {
@Override
public void onSwipeStart() {
// Optional
}
@Override
public void onSwipeCancelled() {
// Optional
}
@Override
public void onDismissed(SwipeDismissFrameLayout layout) {
// Code here for custom behavior, such as going up the
// back stack and destroying the fragment but staying in the app.
}
};
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
SwipeDismissFrameLayout swipeLayout = new SwipeDismissFrameLayout(getActivity());
// If the fragment should fill the screen (optional), then in the layout file,
// in the androidx.wear.widget.SwipeDismissFrameLayout element,
// set the android:layout_width and android:layout_height attributes
// to "match_parent".
View inflatedView = inflater.inflate(R.layout.swipe_dismiss_frame_layout, swipeLayout, false);
swipeLayout.addView(inflatedView);
swipeLayout.addCallback(callback);
return swipeLayout;
}
}
หมายเหตุ: เมื่อใช้ข้อมูลโค้ดภายในกิจกรรม ให้ใช้ FragmentManager.add
แทน FragmentManager.replace
เพื่อรองรับท่าทางสัมผัสปัดเพื่อปิด
วิธีนี้ช่วยให้มั่นใจว่าข้อมูลโค้ดที่แสดงผลก่อนหน้าจะแสดงผลใต้ข้อมูลโค้ดที่แสดงผลด้านบนขณะที่ผู้ใช้ปัดออก
ในบางกรณี เช่น ในมุมมองที่มีแผนที่รองรับการเลื่อน อินเทอร์เฟซผู้ใช้จะป้องกันการปัดในแนวนอนไม่ได้ ในสถานการณ์นี้ คุณมี 2 ตัวเลือก ได้แก่
- หากกองซ้อนย้อนกลับมีจำนวนน้อย ผู้ใช้จะปิดแอปและกลับไปที่หน้าจอหลักของหน้าปัดได้โดยกดปุ่มเปิด/ปิด
- หากต้องการให้ผู้ใช้ไปยังกองซ้อนที่ซ้อนกันอยู่ด้านล่าง คุณสามารถรวมมุมมองไว้ในออบเจ็กต์
SwipeDismissFrameLayout
ซึ่งรองรับการปัดขอบ ระบบจะเปิดใช้การปัดขอบเมื่อมุมมองหรือองค์ประกอบย่อยของมุมมองนั้นแสดงผลจาก
การเรียกใช้canScrollHorizontally()
true
การปัดขอบช่วยให้ผู้ใช้ปิดมุมมองได้โดยการปัดจาก 10% ซ้ายสุดของหน้าจอแทนที่จะปัดจากจุดใดก็ได้ในมุมมอง
ตัวอย่างต่อไปนี้แสดงวิธีตัดมุมมุมมองในออบเจ็กต์ SwipeDismissFrameLayout
<androidx.wear.widget.SwipeDismissFrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/swipe_dismiss_root" >
<TextView
android:id="@+id/test_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:text="Swipe me to dismiss me." />
</androidx.wear.widget.SwipeDismissFrameLayout>
Kotlin
activity?.findViewById<SwipeDismissFrameLayout>(R.id.swipe_dismiss_root)?.apply {
addCallback(object : SwipeDismissFrameLayout.Callback() {
override fun onDismissed(layout: SwipeDismissFrameLayout) {
layout.visibility = View.GONE
}
})
}
Java
SwipeDismissFrameLayout testLayout =
(SwipeDismissFrameLayout) activity.findViewById(R.id.swipe_dismiss_root);
testLayout.addCallback(new SwipeDismissFrameLayout.Callback() {
@Override
public void onDismissed(SwipeDismissFrameLayout layout) {
layout.setVisibility(View.GONE);
}
}
);
ไม่แนะนํา: ปิดใช้การปัดเพื่อปิด
โดยทั่วไปแล้ว เราขอแนะนำไม่ให้ปิดใช้การปัดเพื่อปิด เนื่องจากผู้ใช้คาดหวังว่าจะปิดหน้าจอด้วยการปัด ในกรณีที่พิเศษ คุณขยายธีมเริ่มต้นได้ใน
แหล่งข้อมูลสไตล์ และตั้งค่าแอตทริบิวต์ android:windowSwipeToDismiss
เป็น false
ดังที่แสดงในตัวอย่างโค้ดต่อไปนี้
<resources>
<style name="AppTheme" parent="@android:style/Theme.DeviceDefault">
<item name="android:windowSwipeToDismiss">false</item>
</style>
</resources>
จากนั้นคุณสามารถแจ้งให้ผู้ใช้ทราบเมื่อใช้แอปเป็นครั้งแรกว่าสามารถออกจากแอปได้โดยกดปุ่มเปิด/ปิด
การกดปุ่มเปิด/ปิดจริงจะส่งเหตุการณ์ปุ่มเปิด/ปิด คุณจึงใช้ปุ่มเปิด/ปิดเป็นปุ่มย้อนกลับหรือใช้เพื่อไปยังส่วนต่างๆ โดยทั่วไปไม่ได้
เมื่อกดปุ่มเปิด/ปิด ผู้ใช้จะกลับไปที่หน้าจอหลักของหน้าปัด มีข้อยกเว้นสองประการ ได้แก่
- หากผู้ใช้อยู่ในตัวแก้ไขวิธีการป้อนข้อมูล (IME) เช่น หน้าจอการจดจำลายมือ การกดปุ่มจะปิด IME และนําผู้ใช้กลับไปยังแอป
- หากผู้ใช้อยู่ที่หน้าปัด การกดปุ่มฮาร์ดแวร์จะเปิดตัวเปิดแอป
หมายเหตุว่าเมื่อกดปุ่มเปิด/ปิด วิธีการ
isFinishing()
ของคลาส Activity
จะไม่แสดงผล true
และคุณจะขัดจังหวะเหตุการณ์สําคัญไม่ได้
ตัวอย่างเนื้อหาและโค้ดในหน้าเว็บนี้ขึ้นอยู่กับใบอนุญาตที่อธิบายไว้ในใบอนุญาตการใช้เนื้อหา Java และ OpenJDK เป็นเครื่องหมายการค้าหรือเครื่องหมายการค้าจดทะเบียนของ Oracle และ/หรือบริษัทในเครือ
อัปเดตล่าสุด 2025-07-26 UTC
[[["เข้าใจง่าย","easyToUnderstand","thumb-up"],["แก้ปัญหาของฉันได้","solvedMyProblem","thumb-up"],["อื่นๆ","otherUp","thumb-up"]],[["ไม่มีข้อมูลที่ฉันต้องการ","missingTheInformationINeed","thumb-down"],["ซับซ้อนเกินไป/มีหลายขั้นตอนมากเกินไป","tooComplicatedTooManySteps","thumb-down"],["ล้าสมัย","outOfDate","thumb-down"],["ปัญหาเกี่ยวกับการแปล","translationIssue","thumb-down"],["ตัวอย่าง/ปัญหาเกี่ยวกับโค้ด","samplesCodeIssue","thumb-down"],["อื่นๆ","otherDown","thumb-down"]],["อัปเดตล่าสุด 2025-07-26 UTC"],[],[],null,["# Exit full-screen activities on Wear\n\nTry the Compose way \nJetpack Compose on Wear OS is the recommended UI toolkit for Wear OS. \n[Try Compose on Wear OS →](/training/wearables/compose) \n\n\nA user can exit a Wear OS activity by swiping from left to right.\nIf the app has horizontal scrolling, the user exits by navigating to the edge\nof the content and then swiping from left to right.\nPressing the power button also returns the user to the watch face.\n\nThe swipe-to-dismiss gesture\n----------------------------\n\n\nUsers swipe from left to right to close the current screen. Therefore, we\nrecommend that you use the following:\n\n- Vertical layouts\n- Content containers\n\n\nWe also recommend that your app not contain\nhorizontal swiping gestures.\n\n### Dismiss an activity\n\n\nActivities automatically support swipe-to-dismiss. Swiping an activity\nfrom left to right results in dismissal of the activity, and the app\nnavigates down the [back stack](/guide/components/tasks-and-back-stack).\n\n### Dismiss a fragment\n\n\nTo support swipe-to-dismiss in fragments, you must wrap the\nfragment-containing view in the\n[`SwipeDismissFrameLayout`](/reference/androidx/wear/widget/SwipeDismissFrameLayout) class. Take this into consideration\nwhen deciding whether to use fragments. Use the\n`SwipeDismissFrameLayout` class as shown in the following example: \n\n### Kotlin\n\n```kotlin\nclass SwipeDismissFragment : Fragment() {\n private val callback = object : SwipeDismissFrameLayout.Callback() {\n override fun onSwipeStarted(layout: SwipeDismissFrameLayout) {\n // Optional\n }\n\n override fun onSwipeCanceled(layout: SwipeDismissFrameLayout) {\n // Optional\n }\n\n override fun onDismissed(layout: SwipeDismissFrameLayout) {\n // Code here for custom behavior, such as going up the\n // back stack and destroying the fragment but staying in the app.\n }\n }\n\n override fun onCreateView(\n inflater: LayoutInflater,\n container: ViewGroup?,\n savedInstanceState: Bundle?\n ): View =\n SwipeDismissFrameLayout(activity).apply {\n\n // If the fragment should fill the screen (optional), then in the layout file,\n // in the androidx.wear.widget.SwipeDismissFrameLayout element,\n // set the android:layout_width and android:layout_height attributes\n // to \"match_parent\".\n\n inflater.inflate(\n R.layout.swipe_dismiss_frame_layout,\n this,\n false\n ).also { inflatedView -\u003e\n addView(inflatedView)\n }\n addCallback(callback)\n }\n}\n```\n\n### Java\n\n```java\npublic class SwipeDismissFragment extends Fragment {\n private final Callback callback =\n new Callback() {\n @Override\n public void onSwipeStart() {\n // Optional\n }\n\n @Override\n public void onSwipeCancelled() {\n // Optional\n }\n\n @Override\n public void onDismissed(SwipeDismissFrameLayout layout) {\n // Code here for custom behavior, such as going up the\n // back stack and destroying the fragment but staying in the app.\n }\n };\n\n @Override\n public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {\n SwipeDismissFrameLayout swipeLayout = new SwipeDismissFrameLayout(getActivity());\n\n // If the fragment should fill the screen (optional), then in the layout file,\n // in the androidx.wear.widget.SwipeDismissFrameLayout element,\n // set the android:layout_width and android:layout_height attributes\n // to \"match_parent\".\n\n View inflatedView = inflater.inflate(R.layout.swipe_dismiss_frame_layout, swipeLayout, false);\n swipeLayout.addView(inflatedView);\n swipeLayout.addCallback(callback);\n\n return swipeLayout;\n }\n}\n```\n\n\n**Note:** When you use fragments within your activity, use\n[`FragmentManager.add`](/reference/androidx/fragment/app/FragmentTransaction#add(int,%20java.lang.Class\u003c?%20extends%20androidx.fragment.app.Fragment\u003e,%20android.os.Bundle))\nrather than\n[`FragmentManager.replace`](/reference/androidx/fragment/app/FragmentTransaction#replace(int,%20java.lang.Class\u003c?%20extends%20androidx.fragment.app.Fragment\u003e,%20android.os.Bundle))\nto support the swipe-to-dismiss gesture.\nThis helps ensure that your previous fragment renders under the top fragment while it is\nswiped away.\n\n### Horizontal scrollable views\n\n\nIn some cases, such as in a view containing a map that supports panning,\nthe user interface can't prevent horizontal swiping. In this\nscenario, there are two choices:\n\n- If the back stack is short, the user can dismiss the app and return to the watch face home screen by pressing the power button.\n- If you want the user to go down the back stack, you can wrap the view in a `SwipeDismissFrameLayout` object, which supports edge swipe. Edge swipe is enabled when the view or its children returns `true` from a [`canScrollHorizontally()`](/reference/android/view/View#canScrollHorizontally(int)) call. Edge swipe lets the user dismiss the view by swiping from the leftmost 10% of the screen, rather than anywhere in the view.\n\n\nThe following examples show how to wrap a view in a\n`SwipeDismissFrameLayout` object: \n\n```xml\n\u003candroidx.wear.widget.SwipeDismissFrameLayout\n xmlns:android=\"http://schemas.android.com/apk/res/android\"\n xmlns:tools=\"http://schemas.android.com/tools\"\n android:layout_width=\"match_parent\"\n android:layout_height=\"match_parent\"\n android:id=\"@+id/swipe_dismiss_root\" \u003e\n\n \u003cTextView\n android:id=\"@+id/test_content\"\n android:layout_width=\"match_parent\"\n android:layout_height=\"match_parent\"\n android:gravity=\"center\"\n android:text=\"Swipe me to dismiss me.\" /\u003e\n\u003c/androidx.wear.widget.SwipeDismissFrameLayout\u003e\n``` \n\n### Kotlin\n\n```kotlin\nactivity?.findViewById\u003cSwipeDismissFrameLayout\u003e(R.id.swipe_dismiss_root)?.apply {\n addCallback(object : SwipeDismissFrameLayout.Callback() {\n\n override fun onDismissed(layout: SwipeDismissFrameLayout) {\n layout.visibility = View.GONE\n }\n })\n}\n```\n\n### Java\n\n```java\nSwipeDismissFrameLayout testLayout =\n (SwipeDismissFrameLayout) activity.findViewById(R.id.swipe_dismiss_root);\ntestLayout.addCallback(new SwipeDismissFrameLayout.Callback() {\n @Override\n public void onDismissed(SwipeDismissFrameLayout layout) {\n layout.setVisibility(View.GONE);\n }\n }\n);\n```\n\n### Not recommended: Disable swipe-to-dismiss\n\n\nWe don't generally recommend disabling swipe-to-dismiss, because the user\nexpects to dismiss any screen with a swipe. In an exceptional case,\nyou can extend the default theme\nin a [style resource](/guide/topics/resources/style-resource)\nand set the `android:windowSwipeToDismiss` attribute\nto `false`, as shown in the following code sample: \n\n```xml\n\u003cresources\u003e\n \u003cstyle name=\"AppTheme\" parent=\"@android:style/Theme.DeviceDefault\"\u003e\n \u003citem name=\"android:windowSwipeToDismiss\"\u003efalse\u003c/item\u003e\n \u003c/style\u003e\n\u003c/resources\u003e\n```\n\n\nYou can then inform users on their first use of your app\nthat they can exit the app by pressing the power button.\n\nDismissal with the power button\n-------------------------------\n\n\nA press of the physical power button sends a power key\nevent. Therefore, you can't use the power button as a back\nbutton or for navigation in general.\n\n\nWhen pressed, the power button returns the user to the watch face home screen. There are two exceptions:\n\n- If the user is in an Input Method Editor (IME), such as a handwriting recognition screen, pressing the button closes the IME and returns the user to the app.\n- If the user is at the watch face, pressing the hardware button opens the app launcher.\n\n\n**Note** that when the power button is pressed, the\n[isFinishing()](/reference/android/app/Activity#isFinishing()) method of the `Activity` class does\nnot return `true`, and you can't intercept the key event. \n\nFor more information, see\n[Navigation](/training/wearables/design/navigation)."]]