Wear에서 전체 화면 활동 종료
컬렉션을 사용해 정리하기
내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요.
Compose 사용해 보기
Wear OS용 Jetpack Compose는 Wear OS에 권장되는 UI 도구 키트입니다.
왼쪽에서 오른쪽으로 스와이프하여 Wear OS 활동을 종료할 수 있습니다.
앱에 가로 스크롤이 있는 경우 사용자가 콘텐츠의 가장자리로 이동한 후 왼쪽에서 오른쪽으로 스와이프하여 활동을 종료합니다.
전원 버튼을 누르면 시계 화면으로 돌아갑니다.
스와이프하여 닫기 동작
현재 화면을 닫으려면 사용자는 왼쪽에서 오른쪽으로 스와이프합니다. 따라서 다음을 사용하는 것이 좋습니다.
또한 앱에 가로 스와이프 동작을 포함하지 않는 것이 좋습니다.
활동 닫기
활동은 스와이프하여 닫기 기능을 자동으로 지원합니다. 왼쪽에서 오른쪽으로 활동을 스와이프하면 활동이 닫히고 앱이
백 스택으로 이동합니다.
프래그먼트 닫기
프래그먼트에서 스와이프하여 닫기를 지원하려면 프래그먼트 포함 뷰를
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)
}
}
자바
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.replace
대신 FragmentManager.add
를 사용하세요.
이렇게 하면 이전 프래그먼트가 스와이프되는 동안 상단 프래그먼트 아래에 렌더링됩니다.
패닝을 지원하는 지도가 포함된 뷰에서와 같은 일부 경우에는 사용자 인터페이스가 가로 스와이프를 방해할 수 없습니다. 이 시나리오에는 두 가지 선택 사항이 있습니다.
- 백 스택이 짧으면 사용자는 앱을 닫고 전원 버튼을 눌러 시계 화면 홈 화면으로 돌아갈 수 있습니다.
- 사용자가 백 스택으로 이동하도록 하려면 가장자리 스와이프를 지원하는
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
}
})
}
자바
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가 닫히고 앱으로 돌아갑니다.
- 사용자가 시계 화면에 있는 경우 하드웨어 버튼을 누르면 앱 런처가 열립니다.
전원 버튼을 누르면 Activity
클래스의
isFinishing()
메서드가 true
를 반환하지 않으며 키 이벤트를 가로챌 수 없습니다.
이 페이지에 나와 있는 콘텐츠와 코드 샘플에는 콘텐츠 라이선스에서 설명하는 라이선스가 적용됩니다. 자바 및 OpenJDK는 Oracle 및 Oracle 계열사의 상표 또는 등록 상표입니다.
최종 업데이트: 2025-07-26(UTC)
[null,null,["최종 업데이트: 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)."]]