Add the gesture nav tutorial menu page
- Added the gesture tutorial menu page (launched using an intent extra) - tutorial steps now launch the menu when complete if launched from the menu - the new default set of tutorial steps is home -> back -> overview. this is to handle the case where an intent is launched that is meant to launch the tutorial menu, but ENABLE_NEW_GESTURE_NAV_TUTORIAL is false Flag: ENABLE_NEW_GESTURE_NAV_TUTORIAL Bug: 274463555 Test: Ran the tutorial and menu on a large screen, foldable and phone Change-Id: I2eb5f658115be4d5ecb0233a8f09d22efe6ebadc
This commit is contained in:
parent
afdf2f1020
commit
2851be8cba
|
@ -0,0 +1,23 @@
|
|||
<!-- Copyright (C) 2023 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="84dp"
|
||||
android:height="208dp"
|
||||
android:viewportWidth="84"
|
||||
android:viewportHeight="208">
|
||||
<path
|
||||
android:pathData="M24.53,169.2L32.09,165.56C77.7,143.55 77.7,64.45 32.09,42.35L24.53,38.71C14.55,33.95 6.06,25.56 0,14.92V193.08C6.06,182.44 14.55,174.05 24.53,169.2Z"
|
||||
android:fillColor="#217500"/>
|
||||
</vector>
|
|
@ -0,0 +1,27 @@
|
|||
<!-- Copyright (C) 2023 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="232dp"
|
||||
android:height="67dp"
|
||||
android:viewportWidth="232"
|
||||
android:viewportHeight="67">
|
||||
<group>
|
||||
<clip-path
|
||||
android:pathData="M0,0h232v67h-232z"/>
|
||||
<path
|
||||
android:pathData="M180.9,0.6H51.1C22.9,0.6 0,23.4 0,51.7V67.6H232V51.7C232,23.4 209.1,0.6 180.9,0.6Z"
|
||||
android:fillColor="#4B67AE"/>
|
||||
</group>
|
||||
</vector>
|
|
@ -0,0 +1,27 @@
|
|||
<!-- Copyright (C) 2023 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="194dp"
|
||||
android:height="94dp"
|
||||
android:viewportWidth="194"
|
||||
android:viewportHeight="94">
|
||||
<group>
|
||||
<clip-path
|
||||
android:pathData="M0,0h194v94.09h-194z"/>
|
||||
<path
|
||||
android:pathData="M185.56,76.95C184.79,75.3 184.3,73.56 184.21,71.81L182.85,55.81C182.46,51.34 180.13,47.27 176.45,44.65L163.25,35.44C161.8,34.37 160.54,33.11 159.47,31.65L150.16,18.46C147.54,14.77 143.47,12.45 139,12.06L123,10.6C121.25,10.41 119.51,10.02 117.86,9.24L103.31,2.45C101.27,1.49 99.04,1 96.91,1C94.77,1 92.54,1.49 90.5,2.45L75.95,9.24C74.31,10.02 72.56,10.51 70.81,10.6L54.81,11.96C50.35,12.35 46.27,14.68 43.65,18.36L34.44,31.56C33.37,33.01 32.11,34.27 30.66,35.34L17.27,44.65C13.58,47.27 11.26,51.34 10.87,55.81L9.41,71.81C9.22,73.56 8.83,75.3 8.05,76.95L1.26,91.5C0.78,92.67 0.39,93.83 0.1,94.99H193.52C193.32,93.83 192.94,92.57 192.35,91.5L185.56,76.95Z"
|
||||
android:fillColor="#7E44AD"/>
|
||||
</group>
|
||||
</vector>
|
|
@ -0,0 +1,23 @@
|
|||
<!-- Copyright (C) 2023 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="122dp"
|
||||
android:height="303dp"
|
||||
android:viewportWidth="122"
|
||||
android:viewportHeight="303">
|
||||
<path
|
||||
android:pathData="M35.65,245.9L46.63,240.61C112.92,208.62 112.92,93.67 46.63,61.54L35.65,56.26C21.15,49.34 8.81,37.14 0,21.69V280.6C8.81,265.15 21.15,252.95 35.65,245.9Z"
|
||||
android:fillColor="#217500"/>
|
||||
</vector>
|
|
@ -0,0 +1,27 @@
|
|||
<!-- Copyright (C) 2023 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="362dp"
|
||||
android:height="73dp"
|
||||
android:viewportWidth="362"
|
||||
android:viewportHeight="73">
|
||||
<group>
|
||||
<clip-path
|
||||
android:pathData="M0,0h362v73h-362z"/>
|
||||
<path
|
||||
android:pathData="M282.3,0H79.7C38,0 3.7,32.1 0.3,73H361.7C358.3,32.1 324,0 282.3,0Z"
|
||||
android:fillColor="#4B67AE"/>
|
||||
</group>
|
||||
</vector>
|
|
@ -0,0 +1,27 @@
|
|||
<!-- Copyright (C) 2023 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="297dp"
|
||||
android:height="144dp"
|
||||
android:viewportWidth="297"
|
||||
android:viewportHeight="144">
|
||||
<group>
|
||||
<clip-path
|
||||
android:pathData="M0,0h297v144.04h-297z"/>
|
||||
<path
|
||||
android:pathData="M284.38,116.48C283.19,113.95 282.45,111.28 282.3,108.61L280.22,84.1C279.63,77.27 276.06,71.03 270.42,67.03L250.22,52.92C247.99,51.28 246.06,49.35 244.43,47.13L230.18,26.93C226.16,21.29 219.93,17.72 213.1,17.13L188.6,14.9C185.92,14.6 183.25,14.01 180.72,12.82L158.45,2.43C155.33,0.94 151.91,0.2 148.65,0.2C145.38,0.2 141.97,0.94 138.85,2.43L116.57,12.82C114.05,14.01 111.38,14.75 108.7,14.9L84.2,16.98C77.37,17.57 71.13,21.14 67.12,26.78L53.01,46.98C51.38,49.21 49.45,51.14 47.22,52.77L26.73,67.03C21.09,71.03 17.52,77.27 16.93,84.1L14.7,108.61C14.4,111.28 13.81,113.95 12.62,116.48L2.23,138.75C1.48,140.53 0.89,142.32 0.45,144.1H296.55C296.26,142.32 295.66,140.38 294.77,138.75L284.38,116.48Z"
|
||||
android:fillColor="#7E44AD"/>
|
||||
</group>
|
||||
</vector>
|
|
@ -0,0 +1,27 @@
|
|||
<!-- Copyright (C) 2023 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="83dp"
|
||||
android:height="208dp"
|
||||
android:viewportWidth="83"
|
||||
android:viewportHeight="208">
|
||||
<group>
|
||||
<clip-path
|
||||
android:pathData="M0,0h83.95v208h-83.95z"/>
|
||||
<path
|
||||
android:pathData="M23.53,169.2L31.09,165.56C76.7,143.55 76.7,64.45 31.09,42.35L23.53,38.71C13.55,33.95 5.06,25.56 -1,14.92V193.08C5.06,182.44 13.55,174.05 23.53,169.2Z"
|
||||
android:fillColor="#217500"/>
|
||||
</group>
|
||||
</vector>
|
|
@ -0,0 +1,23 @@
|
|||
<!-- Copyright (C) 2023 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="364dp"
|
||||
android:height="66dp"
|
||||
android:viewportWidth="364"
|
||||
android:viewportHeight="66">
|
||||
<path
|
||||
android:pathData="M283.8,0H80.2C40.7,0 8,28.5 1.3,66H362.8C356,28.5 323.3,0 283.8,0Z"
|
||||
android:fillColor="#4B67AE"/>
|
||||
</vector>
|
|
@ -0,0 +1,19 @@
|
|||
<!-- Copyright (C) 2023 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<shape
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
<corners android:radius="@dimen/gesture_tutorial_menu_button_radius" />
|
||||
</shape>
|
|
@ -0,0 +1,23 @@
|
|||
<!-- Copyright (C) 2023 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="200dp"
|
||||
android:height="76dp"
|
||||
android:viewportWidth="200"
|
||||
android:viewportHeight="76">
|
||||
<path
|
||||
android:pathData="M188.6,56.5C188.2,51.9 185.8,47.7 182,45L168.4,35.5C166.9,34.4 165.6,33.1 164.5,31.6L155,18C152.3,14.2 148.1,11.8 143.5,11.4L127,9.9C125.2,9.7 123.4,9.3 121.7,8.5L106.7,1.5C104.6,0.5 102.3,0 100.1,0C97.8,0 95.6,0.5 93.5,1.5L78.5,8.5C76.8,9.3 75,9.8 73.2,9.9L56.7,11.3C52.1,11.7 47.9,14.1 45.2,17.9L35.7,31.5C34.6,33 33.3,34.3 31.8,35.4L18,45C14.2,47.7 11.8,51.9 11.4,56.5L9.9,73C9.8,74 9.6,75 9.3,76H190.6C190.3,75 190.1,74 190,73L188.6,56.5Z"
|
||||
android:fillColor="#7E44AD"/>
|
||||
</vector>
|
|
@ -0,0 +1,157 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2023 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:paddingTop="@dimen/gesture_tutorial_menu_padding_top"
|
||||
android:paddingBottom="@dimen/gesture_tutorial_menu_padding_bottom"
|
||||
android:paddingHorizontal="@dimen/gesture_tutorial_menu_padding_horizontal"
|
||||
android:background="@color/gesture_tutorial_menu_background">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/gesture_tutorial_menu_home_button"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="@dimen/gesture_tutorial_menu_button_height"
|
||||
android:layout_marginEnd="@dimen/gesture_tutorial_menu_button_spacing"
|
||||
android:background="@drawable/gesture_tutorial_menu_button_background"
|
||||
android:clipToOutline="true"
|
||||
android:backgroundTint="@color/gesture_home_tutorial_background"
|
||||
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@id/gesture_tutorial_menu_back_button">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:src="@drawable/gesture_tutorial_home_step_shape"
|
||||
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"/>
|
||||
|
||||
<TextView
|
||||
style="@style/TextAppearance.GestureTutorial.MenuButton"
|
||||
android:id="@+id/gesture_tutorial_menu_home_button_text"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/home_gesture_tutorial_title"
|
||||
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"/>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/gesture_tutorial_menu_back_button"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="@dimen/gesture_tutorial_menu_button_height"
|
||||
android:layout_marginEnd="@dimen/gesture_tutorial_menu_button_spacing"
|
||||
android:background="@drawable/gesture_tutorial_menu_button_background"
|
||||
android:clipToOutline="true"
|
||||
android:backgroundTint="@color/gesture_back_tutorial_exiting_app"
|
||||
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@id/gesture_tutorial_menu_home_button"
|
||||
app:layout_constraintEnd_toStartOf="@id/gesture_tutorial_menu_overview_button">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:src="@drawable/gesture_tutorial_back_step_shape"
|
||||
android:layout_marginBottom="@dimen/gesture_tutorial_menu_back_shape_bottom_margin"
|
||||
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"/>
|
||||
|
||||
<TextView
|
||||
style="@style/TextAppearance.GestureTutorial.MenuButton"
|
||||
android:id="@+id/gesture_tutorial_menu_back_button_text"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/back_gesture_tutorial_title"
|
||||
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"/>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/gesture_tutorial_menu_overview_button"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="@dimen/gesture_tutorial_menu_button_height"
|
||||
android:background="@drawable/gesture_tutorial_menu_button_background"
|
||||
android:clipToOutline="true"
|
||||
android:backgroundTint="@color/gesture_overview_tutorial_background"
|
||||
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@id/gesture_tutorial_menu_back_button"
|
||||
app:layout_constraintEnd_toEndOf="parent">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:src="@drawable/gesture_tutorial_overview_step_shape"
|
||||
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"/>
|
||||
|
||||
<TextView
|
||||
style="@style/TextAppearance.GestureTutorial.MenuButton"
|
||||
android:id="@+id/gesture_tutorial_menu_overview_button_text"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/overview_gesture_tutorial_title"
|
||||
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"/>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
<androidx.constraintlayout.widget.Guideline
|
||||
android:id="@+id/guideline"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
|
||||
app:layout_constraintGuide_end="@dimen/gesture_tutorial_menu_done_button_spacing"/>
|
||||
|
||||
<Button
|
||||
style="@style/TextAppearance.GestureTutorial.ButtonLabel"
|
||||
android:id="@+id/gesture_tutorial_menu_done_button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingVertical="16dp"
|
||||
android:paddingHorizontal="26dp"
|
||||
android:layout_marginVertical="@dimen/gesture_tutorial_menu_done_button_margin"
|
||||
android:text="@string/gesture_tutorial_action_button_label"
|
||||
android:background="@drawable/gesture_tutorial_action_button_background"
|
||||
android:stateListAnimator="@null"
|
||||
|
||||
app:layout_constraintTop_toBottomOf="@id/guideline"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"/>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -0,0 +1,161 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2023 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:paddingTop="@dimen/gesture_tutorial_menu_padding_top"
|
||||
android:paddingBottom="@dimen/gesture_tutorial_menu_padding_bottom"
|
||||
android:paddingHorizontal="@dimen/gesture_tutorial_menu_padding_horizontal"
|
||||
android:background="@color/gesture_tutorial_menu_background"
|
||||
android:clipToPadding="false">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/gesture_tutorial_menu_home_button"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/gesture_tutorial_menu_button_height"
|
||||
android:background="@drawable/gesture_tutorial_menu_button_background"
|
||||
android:clipToOutline="true"
|
||||
android:backgroundTint="@color/gesture_home_tutorial_background"
|
||||
app:layout_constraintVertical_chainStyle="packed"
|
||||
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toTopOf="@id/gesture_tutorial_menu_back_button"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:src="@drawable/gesture_tutorial_home_step_shape"
|
||||
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"/>
|
||||
|
||||
<TextView
|
||||
style="@style/TextAppearance.GestureTutorial.MenuButton"
|
||||
android:id="@+id/gesture_tutorial_menu_home_button_text"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/home_gesture_tutorial_title"
|
||||
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"/>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/gesture_tutorial_menu_back_button"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/gesture_tutorial_menu_button_height"
|
||||
android:layout_marginTop="@dimen/gesture_tutorial_menu_button_spacing"
|
||||
android:background="@drawable/gesture_tutorial_menu_button_background"
|
||||
android:clipToOutline="true"
|
||||
android:backgroundTint="@color/gesture_back_tutorial_exiting_app"
|
||||
|
||||
app:layout_constraintTop_toBottomOf="@id/gesture_tutorial_menu_home_button"
|
||||
app:layout_constraintBottom_toTopOf="@id/gesture_tutorial_menu_overview_button"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:src="@drawable/gesture_tutorial_back_step_shape"
|
||||
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"/>
|
||||
|
||||
<TextView
|
||||
style="@style/TextAppearance.GestureTutorial.MenuButton"
|
||||
android:id="@+id/gesture_tutorial_menu_back_button_text"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/back_gesture_tutorial_title"
|
||||
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"/>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/gesture_tutorial_menu_overview_button"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/gesture_tutorial_menu_button_height"
|
||||
android:layout_marginTop="@dimen/gesture_tutorial_menu_button_spacing"
|
||||
android:background="@drawable/gesture_tutorial_menu_button_background"
|
||||
android:clipToOutline="true"
|
||||
android:backgroundTint="@color/gesture_overview_tutorial_background"
|
||||
|
||||
app:layout_constraintTop_toBottomOf="@id/gesture_tutorial_menu_back_button"
|
||||
app:layout_constraintBottom_toTopOf="@id/guideline"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:src="@drawable/gesture_tutorial_overview_step_shape"
|
||||
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"/>
|
||||
|
||||
<TextView
|
||||
style="@style/TextAppearance.GestureTutorial.MenuButton"
|
||||
android:id="@+id/gesture_tutorial_menu_overview_button_text"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/overview_gesture_tutorial_title"
|
||||
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"/>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
<androidx.constraintlayout.widget.Guideline
|
||||
android:id="@+id/guideline"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
|
||||
app:layout_constraintGuide_end="@dimen/gesture_tutorial_menu_done_button_spacing"/>
|
||||
|
||||
<Button
|
||||
style="@style/TextAppearance.GestureTutorial.ButtonLabel"
|
||||
android:id="@+id/gesture_tutorial_menu_done_button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingVertical="16dp"
|
||||
android:paddingHorizontal="26dp"
|
||||
android:text="@string/gesture_tutorial_action_button_label"
|
||||
android:background="@drawable/gesture_tutorial_action_button_background"
|
||||
android:stateListAnimator="@null"
|
||||
|
||||
app:layout_constraintTop_toBottomOf="@id/guideline"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"/>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -18,4 +18,14 @@
|
|||
<!-- All Set page -->
|
||||
<dimen name="allset_page_margin_horizontal">48dp</dimen>
|
||||
|
||||
<!-- Gesture Tutorial menu page -->
|
||||
<dimen name="gesture_tutorial_menu_padding_horizontal">48dp</dimen>
|
||||
<dimen name="gesture_tutorial_menu_padding_top">32dp</dimen>
|
||||
<dimen name="gesture_tutorial_menu_padding_bottom">16dp</dimen>
|
||||
<dimen name="gesture_tutorial_menu_button_height">491dp</dimen>
|
||||
<dimen name="gesture_tutorial_menu_button_spacing">24dp</dimen>
|
||||
<dimen name="gesture_tutorial_menu_done_button_top_spacing">40dp</dimen>
|
||||
<dimen name="gesture_tutorial_menu_back_shape_bottom_margin">49dp</dimen>
|
||||
<dimen name="gesture_tutorial_menu_done_button_margin">16dp</dimen>
|
||||
|
||||
</resources>
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
* Copyright (c) 2023, The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
-->
|
||||
<resources>
|
||||
|
||||
<!-- Gesture Tutorial menu page -->
|
||||
<dimen name="gesture_tutorial_menu_button_height">580dp</dimen>
|
||||
<dimen name="gesture_tutorial_menu_button_spacing">49dp</dimen>
|
||||
<dimen name="gesture_tutorial_menu_done_button_top_spacing">24dp</dimen>
|
||||
<dimen name="gesture_tutorial_menu_back_shape_bottom_margin">21dp</dimen>
|
||||
<dimen name="gesture_tutorial_menu_done_button_spacing">80dp</dimen>
|
||||
<dimen name="gesture_tutorial_menu_done_button_margin">0dp</dimen>
|
||||
|
||||
</resources>
|
|
@ -43,13 +43,14 @@
|
|||
<color name="gesture_tutorial_taskbar_color">#E8EAED</color>
|
||||
|
||||
<!-- Redesigned gesture navigation tutorial -->
|
||||
<color name="gesture_home_tutorial_background">#FFB399</color>
|
||||
<color name="gesture_home_tutorial_background">#FFAD91</color>
|
||||
<color name="gesture_home_tutorial_swipe_up_rect">#3857C7</color>
|
||||
<color name="gesture_back_tutorial_exiting_app">#F3A5B9</color>
|
||||
<color name="gesture_back_tutorial_exiting_app">#F9A2B9</color>
|
||||
<color name="gesture_back_tutorial_background">#3857C7</color>
|
||||
<color name="gesture_overview_tutorial_background">#E2F3AF</color>
|
||||
<color name="gesture_overview_tutorial_background">#DFF3AF</color>
|
||||
<color name="gesture_overview_tutorial_swipe_rect">#7E44AD</color>
|
||||
<color name="gesture_overview_background">#BFC8CB</color>
|
||||
<color name="gesture_tutorial_menu_background">#1C1B1F</color>
|
||||
|
||||
<!-- Mock hotseat -->
|
||||
<color name="mock_app_icon">#BDC1C6</color>
|
||||
|
|
|
@ -124,6 +124,18 @@
|
|||
<dimen name="gesture_tutorial_back_gesture_exiting_app_margin">8dp</dimen>
|
||||
<dimen name="gesture_tutorial_back_gesture_end_corner_radius">36dp</dimen>
|
||||
|
||||
<!-- Gesture Tutorial menu page -->
|
||||
<dimen name="gesture_tutorial_menu_padding_horizontal">24dp</dimen>
|
||||
<dimen name="gesture_tutorial_menu_padding_top">31dp</dimen>
|
||||
<dimen name="gesture_tutorial_menu_padding_bottom">24dp</dimen>
|
||||
<dimen name="gesture_tutorial_menu_button_height">0dp</dimen>
|
||||
<dimen name="gesture_tutorial_menu_button_spacing">16dp</dimen>
|
||||
<dimen name="gesture_tutorial_menu_button_radius">28dp</dimen>
|
||||
<dimen name="gesture_tutorial_menu_done_button_top_spacing">0dp</dimen>
|
||||
<dimen name="gesture_tutorial_menu_back_shape_bottom_margin">0dp</dimen>
|
||||
<dimen name="gesture_tutorial_menu_done_button_spacing">72dp</dimen>
|
||||
<dimen name="gesture_tutorial_menu_done_button_margin">0dp</dimen>
|
||||
|
||||
<!-- Gesture Tutorial mock conversations -->
|
||||
<dimen name="gesture_tutorial_message_icon_size">44dp</dimen>
|
||||
<dimen name="gesture_tutorial_message_icon_corner_radius">100dp</dimen>
|
||||
|
|
|
@ -47,6 +47,13 @@
|
|||
<item name="android:lineHeight">44sp</item>
|
||||
</style>
|
||||
|
||||
<style name="TextAppearance.GestureTutorial.MenuButton"
|
||||
parent="TextAppearance.GestureTutorial.Feedback.Title">
|
||||
<item name="android:gravity">center</item>
|
||||
<item name="android:textColor">?android:attr/textColorPrimaryInverse</item>
|
||||
<item name="fontWeight">400</item>
|
||||
</style>
|
||||
|
||||
<style name="TextAppearance.GestureTutorial.Feedback.Title.AllSet"
|
||||
parent="TextAppearance.GestureTutorial.Feedback.Title">
|
||||
<item name="android:letterSpacing">0.03</item>
|
||||
|
|
|
@ -294,17 +294,27 @@ public class DeveloperOptionsFragment extends PreferenceFragmentCompat {
|
|||
}
|
||||
PreferenceCategory sandboxCategory = newCategory("Gesture Navigation Sandbox");
|
||||
sandboxCategory.setSummary("Learn and practice navigation gestures");
|
||||
Preference launchTutorialStepMenuPreference = new Preference(context);
|
||||
launchTutorialStepMenuPreference.setKey("launchTutorialStepMenu");
|
||||
launchTutorialStepMenuPreference.setTitle("Launch Gesture Tutorial Steps menu");
|
||||
launchTutorialStepMenuPreference.setSummary("Select a gesture tutorial step.");
|
||||
launchTutorialStepMenuPreference.setOnPreferenceClickListener(preference -> {
|
||||
startActivity(launchSandboxIntent.putExtra("use_tutorial_menu", true));
|
||||
return true;
|
||||
});
|
||||
sandboxCategory.addPreference(launchTutorialStepMenuPreference);
|
||||
Preference launchOnboardingTutorialPreference = new Preference(context);
|
||||
launchOnboardingTutorialPreference.setKey("launchOnboardingTutorial");
|
||||
launchOnboardingTutorialPreference.setTitle("Launch Onboarding Tutorial");
|
||||
launchOnboardingTutorialPreference.setSummary("Learn the basic navigation gestures.");
|
||||
launchOnboardingTutorialPreference.setOnPreferenceClickListener(preference -> {
|
||||
startActivity(launchSandboxIntent.putExtra(
|
||||
"tutorial_steps",
|
||||
new String[] {
|
||||
"HOME_NAVIGATION",
|
||||
"BACK_NAVIGATION",
|
||||
"OVERVIEW_NAVIGATION"}));
|
||||
startActivity(launchSandboxIntent
|
||||
.putExtra("use_tutorial_menu", false)
|
||||
.putExtra("tutorial_steps",
|
||||
new String[] {
|
||||
"HOME_NAVIGATION",
|
||||
"BACK_NAVIGATION",
|
||||
"OVERVIEW_NAVIGATION"}));
|
||||
return true;
|
||||
});
|
||||
sandboxCategory.addPreference(launchOnboardingTutorialPreference);
|
||||
|
@ -313,9 +323,9 @@ public class DeveloperOptionsFragment extends PreferenceFragmentCompat {
|
|||
launchBackTutorialPreference.setTitle("Launch Back Tutorial");
|
||||
launchBackTutorialPreference.setSummary("Learn how to use the Back gesture");
|
||||
launchBackTutorialPreference.setOnPreferenceClickListener(preference -> {
|
||||
startActivity(launchSandboxIntent.putExtra(
|
||||
"tutorial_steps",
|
||||
new String[] {"BACK_NAVIGATION"}));
|
||||
startActivity(launchSandboxIntent
|
||||
.putExtra("use_tutorial_menu", false)
|
||||
.putExtra("tutorial_steps", new String[] {"BACK_NAVIGATION"}));
|
||||
return true;
|
||||
});
|
||||
sandboxCategory.addPreference(launchBackTutorialPreference);
|
||||
|
@ -324,9 +334,9 @@ public class DeveloperOptionsFragment extends PreferenceFragmentCompat {
|
|||
launchHomeTutorialPreference.setTitle("Launch Home Tutorial");
|
||||
launchHomeTutorialPreference.setSummary("Learn how to use the Home gesture");
|
||||
launchHomeTutorialPreference.setOnPreferenceClickListener(preference -> {
|
||||
startActivity(launchSandboxIntent.putExtra(
|
||||
"tutorial_steps",
|
||||
new String[] {"HOME_NAVIGATION"}));
|
||||
startActivity(launchSandboxIntent
|
||||
.putExtra("use_tutorial_menu", false)
|
||||
.putExtra("tutorial_steps", new String[] {"HOME_NAVIGATION"}));
|
||||
return true;
|
||||
});
|
||||
sandboxCategory.addPreference(launchHomeTutorialPreference);
|
||||
|
@ -335,9 +345,9 @@ public class DeveloperOptionsFragment extends PreferenceFragmentCompat {
|
|||
launchOverviewTutorialPreference.setTitle("Launch Overview Tutorial");
|
||||
launchOverviewTutorialPreference.setSummary("Learn how to use the Overview gesture");
|
||||
launchOverviewTutorialPreference.setOnPreferenceClickListener(preference -> {
|
||||
startActivity(launchSandboxIntent.putExtra(
|
||||
"tutorial_steps",
|
||||
new String[] {"OVERVIEW_NAVIGATION"}));
|
||||
startActivity(launchSandboxIntent
|
||||
.putExtra("use_tutorial_menu", false)
|
||||
.putExtra("tutorial_steps", new String[] {"OVERVIEW_NAVIGATION"}));
|
||||
return true;
|
||||
});
|
||||
sandboxCategory.addPreference(launchOverviewTutorialPreference);
|
||||
|
@ -346,9 +356,9 @@ public class DeveloperOptionsFragment extends PreferenceFragmentCompat {
|
|||
launchAssistantTutorialPreference.setTitle("Launch Assistant Tutorial");
|
||||
launchAssistantTutorialPreference.setSummary("Learn how to use the Assistant gesture");
|
||||
launchAssistantTutorialPreference.setOnPreferenceClickListener(preference -> {
|
||||
startActivity(launchSandboxIntent.putExtra(
|
||||
"tutorial_steps",
|
||||
new String[] {"ASSISTANT"}));
|
||||
startActivity(launchSandboxIntent
|
||||
.putExtra("use_tutorial_menu", false)
|
||||
.putExtra("tutorial_steps", new String[] {"ASSISTANT"}));
|
||||
return true;
|
||||
});
|
||||
sandboxCategory.addPreference(launchAssistantTutorialPreference);
|
||||
|
@ -357,9 +367,9 @@ public class DeveloperOptionsFragment extends PreferenceFragmentCompat {
|
|||
launchSandboxModeTutorialPreference.setTitle("Launch Sandbox Mode");
|
||||
launchSandboxModeTutorialPreference.setSummary("Practice navigation gestures");
|
||||
launchSandboxModeTutorialPreference.setOnPreferenceClickListener(preference -> {
|
||||
startActivity(launchSandboxIntent.putExtra(
|
||||
"tutorial_steps",
|
||||
new String[] {"SANDBOX_MODE"}));
|
||||
startActivity(launchSandboxIntent
|
||||
.putExtra("use_tutorial_menu", false)
|
||||
.putExtra("tutorial_steps", new String[] {"SANDBOX_MODE"}));
|
||||
return true;
|
||||
});
|
||||
sandboxCategory.addPreference(launchSandboxModeTutorialPreference);
|
||||
|
|
|
@ -15,8 +15,6 @@
|
|||
*/
|
||||
package com.android.quickstep.interaction;
|
||||
|
||||
import static com.android.quickstep.interaction.TutorialController.TutorialType.ASSISTANT_COMPLETE;
|
||||
|
||||
import android.graphics.PointF;
|
||||
|
||||
import com.android.launcher3.R;
|
||||
|
@ -47,7 +45,7 @@ final class AssistantGestureTutorialController extends TutorialController {
|
|||
case ASSISTANT_COMPLETE:
|
||||
if (result == BackGestureResult.BACK_COMPLETED_FROM_LEFT
|
||||
|| result == BackGestureResult.BACK_COMPLETED_FROM_RIGHT) {
|
||||
mTutorialFragment.closeTutorial();
|
||||
mTutorialFragment.close();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -81,7 +79,7 @@ final class AssistantGestureTutorialController extends TutorialController {
|
|||
break;
|
||||
case ASSISTANT_COMPLETE:
|
||||
if (result == NavBarGestureResult.HOME_GESTURE_COMPLETED) {
|
||||
mTutorialFragment.closeTutorial();
|
||||
mTutorialFragment.close();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -26,7 +26,9 @@ import com.android.quickstep.interaction.TutorialController.TutorialType;
|
|||
/** Shows the Home gesture interactive tutorial. */
|
||||
public class AssistantGestureTutorialFragment extends TutorialFragment {
|
||||
|
||||
public AssistantGestureTutorialFragment() {}
|
||||
public AssistantGestureTutorialFragment(boolean fromTutorialMenu) {
|
||||
super(fromTutorialMenu);
|
||||
}
|
||||
|
||||
@Override
|
||||
TutorialController createController(TutorialType type) {
|
||||
|
|
|
@ -109,7 +109,7 @@ final class BackGestureTutorialController extends TutorialController {
|
|||
case BACK_NAVIGATION_COMPLETE:
|
||||
if (result == BackGestureResult.BACK_COMPLETED_FROM_LEFT
|
||||
|| result == BackGestureResult.BACK_COMPLETED_FROM_RIGHT) {
|
||||
mTutorialFragment.closeTutorial();
|
||||
mTutorialFragment.close();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -191,7 +191,7 @@ final class BackGestureTutorialController extends TutorialController {
|
|||
}
|
||||
if (mTutorialType == BACK_NAVIGATION_COMPLETE) {
|
||||
if (result == NavBarGestureResult.HOME_GESTURE_COMPLETED) {
|
||||
mTutorialFragment.closeTutorial();
|
||||
mTutorialFragment.close();
|
||||
}
|
||||
} else if (mTutorialType == BACK_NAVIGATION) {
|
||||
switch (result) {
|
||||
|
|
|
@ -34,7 +34,13 @@ import java.util.ArrayList;
|
|||
/** Shows the Back gesture interactive tutorial. */
|
||||
public class BackGestureTutorialFragment extends TutorialFragment {
|
||||
|
||||
public BackGestureTutorialFragment() {}
|
||||
public BackGestureTutorialFragment() {
|
||||
this(false);
|
||||
}
|
||||
|
||||
public BackGestureTutorialFragment(boolean fromTutorialMenu) {
|
||||
super(fromTutorialMenu);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
|
|
|
@ -26,10 +26,12 @@ import android.view.View;
|
|||
import android.view.Window;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.FragmentActivity;
|
||||
|
||||
import com.android.launcher3.LauncherPrefs;
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.config.FeatureFlags;
|
||||
import com.android.launcher3.logging.StatsLogManager;
|
||||
import com.android.quickstep.TouchInteractionService.TISBinder;
|
||||
import com.android.quickstep.interaction.TutorialController.TutorialType;
|
||||
|
@ -42,11 +44,12 @@ public class GestureSandboxActivity extends FragmentActivity {
|
|||
|
||||
private static final String KEY_TUTORIAL_STEPS = "tutorial_steps";
|
||||
private static final String KEY_CURRENT_STEP = "current_step";
|
||||
private static final String KEY_GESTURE_COMPLETE = "gesture_complete";
|
||||
static final String KEY_TUTORIAL_TYPE = "tutorial_type";
|
||||
static final String KEY_GESTURE_COMPLETE = "gesture_complete";
|
||||
static final String KEY_USE_TUTORIAL_MENU = "use_tutorial_menu";
|
||||
|
||||
private TutorialType[] mTutorialSteps;
|
||||
private TutorialType mCurrentTutorialStep;
|
||||
private TutorialFragment mFragment;
|
||||
@Nullable private TutorialType[] mTutorialSteps;
|
||||
private GestureSandboxFragment mFragment;
|
||||
|
||||
private int mCurrentStep;
|
||||
private int mNumSteps;
|
||||
|
@ -67,10 +70,26 @@ public class GestureSandboxActivity extends FragmentActivity {
|
|||
mStatsLogManager = StatsLogManager.newInstance(getApplicationContext());
|
||||
|
||||
Bundle args = savedInstanceState == null ? getIntent().getExtras() : savedInstanceState;
|
||||
mTutorialSteps = getTutorialSteps(args);
|
||||
mCurrentTutorialStep = mTutorialSteps[mCurrentStep - 1];
|
||||
mFragment = TutorialFragment.newInstance(
|
||||
mCurrentTutorialStep, args.getBoolean(KEY_GESTURE_COMPLETE, false));
|
||||
|
||||
boolean gestureComplete = args != null && args.getBoolean(KEY_GESTURE_COMPLETE, false);
|
||||
if (FeatureFlags.ENABLE_NEW_GESTURE_NAV_TUTORIAL.get()
|
||||
&& args != null
|
||||
&& args.getBoolean(KEY_USE_TUTORIAL_MENU, false)) {
|
||||
mTutorialSteps = null;
|
||||
TutorialType tutorialTypeOverride = (TutorialType) args.get(KEY_TUTORIAL_TYPE);
|
||||
mFragment = tutorialTypeOverride == null
|
||||
? new MenuFragment()
|
||||
: makeTutorialFragment(
|
||||
tutorialTypeOverride,
|
||||
gestureComplete,
|
||||
/* fromMenu= */ true);
|
||||
} else {
|
||||
mTutorialSteps = getTutorialSteps(args);
|
||||
mFragment = makeTutorialFragment(
|
||||
mTutorialSteps[mCurrentStep - 1],
|
||||
gestureComplete,
|
||||
/* fromMenu= */ false);
|
||||
}
|
||||
getSupportFragmentManager().beginTransaction()
|
||||
.add(R.id.gesture_tutorial_fragment_container, mFragment)
|
||||
.commit();
|
||||
|
@ -81,7 +100,9 @@ public class GestureSandboxActivity extends FragmentActivity {
|
|||
@Override
|
||||
public void onAttachedToWindow() {
|
||||
super.onAttachedToWindow();
|
||||
disableSystemGestures();
|
||||
if (mFragment.shouldDisableSystemGestures()) {
|
||||
disableSystemGestures();
|
||||
}
|
||||
mFragment.onAttachedToWindow();
|
||||
}
|
||||
|
||||
|
@ -103,7 +124,7 @@ public class GestureSandboxActivity extends FragmentActivity {
|
|||
protected void onSaveInstanceState(@NonNull Bundle savedInstanceState) {
|
||||
savedInstanceState.putStringArray(KEY_TUTORIAL_STEPS, getTutorialStepNames());
|
||||
savedInstanceState.putInt(KEY_CURRENT_STEP, mCurrentStep);
|
||||
savedInstanceState.putBoolean(KEY_GESTURE_COMPLETE, mFragment.isGestureComplete());
|
||||
mFragment.onSaveInstanceState(savedInstanceState);
|
||||
super.onSaveInstanceState(savedInstanceState);
|
||||
}
|
||||
|
||||
|
@ -134,21 +155,45 @@ public class GestureSandboxActivity extends FragmentActivity {
|
|||
* If there is no following step, the tutorial is closed.
|
||||
*/
|
||||
public void continueTutorial() {
|
||||
if (isTutorialComplete()) {
|
||||
mFragment.closeTutorial();
|
||||
if (isTutorialComplete() || mTutorialSteps == null) {
|
||||
mFragment.close();
|
||||
return;
|
||||
}
|
||||
mCurrentTutorialStep = mTutorialSteps[mCurrentStep];
|
||||
mFragment = TutorialFragment.newInstance(
|
||||
mCurrentTutorialStep, /* gestureComplete= */ false);
|
||||
launchTutorialStep(mTutorialSteps[mCurrentStep], false);
|
||||
mCurrentStep++;
|
||||
}
|
||||
|
||||
private TutorialFragment makeTutorialFragment(
|
||||
@NonNull TutorialType tutorialType, boolean gestureComplete, boolean fromMenu) {
|
||||
return TutorialFragment.newInstance(tutorialType, gestureComplete, fromMenu);
|
||||
}
|
||||
|
||||
/**
|
||||
* Launches the given gesture nav tutorial step.
|
||||
*
|
||||
* If the step is being launched from the gesture nav tutorial menu, then that step will launch
|
||||
* the menu when complete.
|
||||
*/
|
||||
public void launchTutorialStep(@NonNull TutorialType tutorialType, boolean fromMenu) {
|
||||
mFragment = makeTutorialFragment(tutorialType, false, fromMenu);
|
||||
getSupportFragmentManager().beginTransaction()
|
||||
.replace(R.id.gesture_tutorial_fragment_container, mFragment)
|
||||
.runOnCommit(() -> mFragment.onAttachedToWindow())
|
||||
.commit();
|
||||
mCurrentStep++;
|
||||
}
|
||||
|
||||
/** Launches the gesture nav tutorial menu page */
|
||||
public void launchTutorialMenu() {
|
||||
mFragment = new MenuFragment();
|
||||
getSupportFragmentManager().beginTransaction()
|
||||
.add(R.id.gesture_tutorial_fragment_container, mFragment)
|
||||
.commit();
|
||||
}
|
||||
|
||||
private String[] getTutorialStepNames() {
|
||||
if (mTutorialSteps == null) {
|
||||
return new String[0];
|
||||
}
|
||||
String[] tutorialStepNames = new String[mTutorialSteps.length];
|
||||
|
||||
int i = 0;
|
||||
|
@ -160,18 +205,19 @@ public class GestureSandboxActivity extends FragmentActivity {
|
|||
}
|
||||
|
||||
private TutorialType[] getTutorialSteps(Bundle extras) {
|
||||
TutorialType[] defaultSteps = new TutorialType[] {TutorialType.BACK_NAVIGATION};
|
||||
TutorialType[] defaultSteps = new TutorialType[] {
|
||||
TutorialType.HOME_NAVIGATION,
|
||||
TutorialType.BACK_NAVIGATION,
|
||||
TutorialType.OVERVIEW_NAVIGATION};
|
||||
mCurrentStep = 1;
|
||||
mNumSteps = 1;
|
||||
mNumSteps = defaultSteps.length;
|
||||
|
||||
if (extras == null || !extras.containsKey(KEY_TUTORIAL_STEPS)) {
|
||||
return defaultSteps;
|
||||
}
|
||||
|
||||
Object savedSteps = extras.get(KEY_TUTORIAL_STEPS);
|
||||
int currentStep = extras.getInt(KEY_CURRENT_STEP, -1);
|
||||
String[] savedStepsNames;
|
||||
|
||||
Object savedSteps = extras.get(KEY_TUTORIAL_STEPS);
|
||||
if (savedSteps instanceof String) {
|
||||
savedStepsNames = TextUtils.isEmpty((String) savedSteps)
|
||||
? null : ((String) savedSteps).split(",");
|
||||
|
@ -181,7 +227,7 @@ public class GestureSandboxActivity extends FragmentActivity {
|
|||
return defaultSteps;
|
||||
}
|
||||
|
||||
if (savedStepsNames == null) {
|
||||
if (savedStepsNames == null || savedStepsNames.length == 0) {
|
||||
return defaultSteps;
|
||||
}
|
||||
|
||||
|
@ -190,7 +236,7 @@ public class GestureSandboxActivity extends FragmentActivity {
|
|||
tutorialSteps[i] = TutorialType.valueOf(savedStepsNames[i]);
|
||||
}
|
||||
|
||||
mCurrentStep = Math.max(currentStep, 1);
|
||||
mCurrentStep = Math.max(extras.getInt(KEY_CURRENT_STEP, -1), 1);
|
||||
mNumSteps = tutorialSteps.length;
|
||||
|
||||
return tutorialSteps;
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* Copyright (C) 2023 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.android.quickstep.interaction;
|
||||
|
||||
import android.app.Activity;
|
||||
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.fragment.app.FragmentActivity;
|
||||
|
||||
/** Displays one page of the gesture nav tutorial. */
|
||||
public abstract class GestureSandboxFragment extends Fragment {
|
||||
|
||||
void onAttachedToWindow() {}
|
||||
|
||||
void onDetachedFromWindow() {}
|
||||
|
||||
boolean shouldDisableSystemGestures() {
|
||||
return true;
|
||||
}
|
||||
|
||||
void close() {
|
||||
FragmentActivity activity = getActivity();
|
||||
if (activity != null) {
|
||||
activity.setResult(Activity.RESULT_OK);
|
||||
activity.finish();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -99,7 +99,7 @@ final class HomeGestureTutorialController extends SwipeUpGestureTutorialControll
|
|||
case HOME_NAVIGATION_COMPLETE:
|
||||
if (result == BackGestureResult.BACK_COMPLETED_FROM_LEFT
|
||||
|| result == BackGestureResult.BACK_COMPLETED_FROM_RIGHT) {
|
||||
mTutorialFragment.closeTutorial();
|
||||
mTutorialFragment.close();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -138,7 +138,7 @@ final class HomeGestureTutorialController extends SwipeUpGestureTutorialControll
|
|||
break;
|
||||
case HOME_NAVIGATION_COMPLETE:
|
||||
if (result == NavBarGestureResult.HOME_GESTURE_COMPLETED) {
|
||||
mTutorialFragment.closeTutorial();
|
||||
mTutorialFragment.close();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -33,7 +33,13 @@ import java.util.ArrayList;
|
|||
/** Shows the Home gesture interactive tutorial. */
|
||||
public class HomeGestureTutorialFragment extends TutorialFragment {
|
||||
|
||||
public HomeGestureTutorialFragment() {}
|
||||
public HomeGestureTutorialFragment() {
|
||||
this(false);
|
||||
}
|
||||
|
||||
public HomeGestureTutorialFragment(boolean fromTutorialMenu) {
|
||||
super(fromTutorialMenu);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
* Copyright (C) 2023 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.android.quickstep.interaction;
|
||||
|
||||
import static com.android.quickstep.interaction.GestureSandboxActivity.KEY_GESTURE_COMPLETE;
|
||||
import static com.android.quickstep.interaction.GestureSandboxActivity.KEY_TUTORIAL_TYPE;
|
||||
import static com.android.quickstep.interaction.GestureSandboxActivity.KEY_USE_TUTORIAL_MENU;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.android.launcher3.R;
|
||||
|
||||
/** Displays the gesture nav tutorial menu. */
|
||||
public final class MenuFragment extends GestureSandboxFragment {
|
||||
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
|
||||
@Nullable Bundle savedInstanceState) {
|
||||
View root = inflater.inflate(
|
||||
R.layout.gesture_tutorial_step_menu, container, false);
|
||||
|
||||
root.findViewById(R.id.gesture_tutorial_menu_home_button).setOnClickListener(
|
||||
v -> launchTutorialStep(TutorialController.TutorialType.HOME_NAVIGATION));
|
||||
root.findViewById(R.id.gesture_tutorial_menu_back_button).setOnClickListener(
|
||||
v -> launchTutorialStep(TutorialController.TutorialType.BACK_NAVIGATION));
|
||||
root.findViewById(R.id.gesture_tutorial_menu_overview_button).setOnClickListener(
|
||||
v -> launchTutorialStep(TutorialController.TutorialType.OVERVIEW_NAVIGATION));
|
||||
root.findViewById(R.id.gesture_tutorial_menu_done_button).setOnClickListener(
|
||||
v -> close());
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
@Override
|
||||
boolean shouldDisableSystemGestures() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSaveInstanceState(Bundle savedInstanceState) {
|
||||
savedInstanceState.putBoolean(KEY_USE_TUTORIAL_MENU, true);
|
||||
savedInstanceState.remove(KEY_TUTORIAL_TYPE);
|
||||
savedInstanceState.remove(KEY_GESTURE_COMPLETE);
|
||||
super.onSaveInstanceState(savedInstanceState);
|
||||
}
|
||||
|
||||
private void launchTutorialStep(@NonNull TutorialController.TutorialType tutorialType) {
|
||||
((GestureSandboxActivity) getActivity()).launchTutorialStep(tutorialType, true);
|
||||
}
|
||||
}
|
|
@ -116,7 +116,7 @@ final class OverviewGestureTutorialController extends SwipeUpGestureTutorialCont
|
|||
case OVERVIEW_NAVIGATION_COMPLETE:
|
||||
if (result == BackGestureResult.BACK_COMPLETED_FROM_LEFT
|
||||
|| result == BackGestureResult.BACK_COMPLETED_FROM_RIGHT) {
|
||||
mTutorialFragment.closeTutorial();
|
||||
mTutorialFragment.close();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -178,7 +178,7 @@ final class OverviewGestureTutorialController extends SwipeUpGestureTutorialCont
|
|||
break;
|
||||
case OVERVIEW_NAVIGATION_COMPLETE:
|
||||
if (result == NavBarGestureResult.HOME_GESTURE_COMPLETED) {
|
||||
mTutorialFragment.closeTutorial();
|
||||
mTutorialFragment.close();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -33,7 +33,13 @@ import java.util.ArrayList;
|
|||
/** Shows the Overview gesture interactive tutorial. */
|
||||
public class OverviewGestureTutorialFragment extends TutorialFragment {
|
||||
|
||||
public OverviewGestureTutorialFragment() {}
|
||||
public OverviewGestureTutorialFragment() {
|
||||
this(false);
|
||||
}
|
||||
|
||||
public OverviewGestureTutorialFragment(boolean fromTutorialMenu) {
|
||||
super(fromTutorialMenu);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
|
|
|
@ -26,7 +26,9 @@ import com.android.quickstep.interaction.TutorialController.TutorialType;
|
|||
/** Shows the general navigation gesture sandbox environment. */
|
||||
public class SandboxModeTutorialFragment extends TutorialFragment {
|
||||
|
||||
public SandboxModeTutorialFragment() {}
|
||||
public SandboxModeTutorialFragment(boolean fromTutorialMenu) {
|
||||
super(fromTutorialMenu);
|
||||
}
|
||||
|
||||
@Override
|
||||
TutorialController createController(TutorialType type) {
|
||||
|
|
|
@ -703,66 +703,65 @@ abstract class TutorialController implements BackGestureAttemptCallback,
|
|||
}
|
||||
|
||||
private AlertDialog createSkipTutorialDialog() {
|
||||
if (mContext instanceof GestureSandboxActivity) {
|
||||
GestureSandboxActivity sandboxActivity = (GestureSandboxActivity) mContext;
|
||||
View contentView = View.inflate(
|
||||
sandboxActivity, R.layout.gesture_tutorial_dialog, null);
|
||||
AlertDialog tutorialDialog = new AlertDialog
|
||||
.Builder(sandboxActivity, R.style.Theme_AppCompat_Dialog_Alert)
|
||||
.setView(contentView)
|
||||
.create();
|
||||
if (!(mContext instanceof GestureSandboxActivity)) {
|
||||
return null;
|
||||
}
|
||||
GestureSandboxActivity sandboxActivity = (GestureSandboxActivity) mContext;
|
||||
View contentView = View.inflate(
|
||||
sandboxActivity, R.layout.gesture_tutorial_dialog, null);
|
||||
AlertDialog tutorialDialog = new AlertDialog
|
||||
.Builder(sandboxActivity, R.style.Theme_AppCompat_Dialog_Alert)
|
||||
.setView(contentView)
|
||||
.create();
|
||||
|
||||
PackageManager packageManager = mContext.getPackageManager();
|
||||
CharSequence tipsAppName = DEFAULT_PIXEL_TIPS_APP_NAME;
|
||||
PackageManager packageManager = mContext.getPackageManager();
|
||||
CharSequence tipsAppName = DEFAULT_PIXEL_TIPS_APP_NAME;
|
||||
|
||||
try {
|
||||
tipsAppName = packageManager.getApplicationLabel(
|
||||
packageManager.getApplicationInfo(
|
||||
PIXEL_TIPS_APP_PACKAGE_NAME, PackageManager.GET_META_DATA));
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
Log.e(LOG_TAG,
|
||||
"Could not find app label for package name: "
|
||||
+ PIXEL_TIPS_APP_PACKAGE_NAME
|
||||
+ ". Defaulting to 'Pixel Tips.'",
|
||||
e);
|
||||
}
|
||||
|
||||
TextView subtitleTextView = (TextView) contentView.findViewById(
|
||||
R.id.gesture_tutorial_dialog_subtitle);
|
||||
if (subtitleTextView != null) {
|
||||
subtitleTextView.setText(
|
||||
mContext.getString(R.string.skip_tutorial_dialog_subtitle, tipsAppName));
|
||||
} else {
|
||||
Log.w(LOG_TAG, "No subtitle view in the skip tutorial dialog to update.");
|
||||
}
|
||||
|
||||
Button cancelButton = (Button) contentView.findViewById(
|
||||
R.id.gesture_tutorial_dialog_cancel_button);
|
||||
if (cancelButton != null) {
|
||||
cancelButton.setOnClickListener(
|
||||
v -> tutorialDialog.dismiss());
|
||||
} else {
|
||||
Log.w(LOG_TAG, "No cancel button in the skip tutorial dialog to update.");
|
||||
}
|
||||
|
||||
Button confirmButton = contentView.findViewById(
|
||||
R.id.gesture_tutorial_dialog_confirm_button);
|
||||
if (confirmButton != null) {
|
||||
confirmButton.setOnClickListener(v -> {
|
||||
mTutorialFragment.closeTutorial(true);
|
||||
tutorialDialog.dismiss();
|
||||
});
|
||||
} else {
|
||||
Log.w(LOG_TAG, "No confirm button in the skip tutorial dialog to update.");
|
||||
}
|
||||
|
||||
tutorialDialog.getWindow().setBackgroundDrawable(
|
||||
new ColorDrawable(sandboxActivity.getColor(android.R.color.transparent)));
|
||||
|
||||
return tutorialDialog;
|
||||
try {
|
||||
tipsAppName = packageManager.getApplicationLabel(
|
||||
packageManager.getApplicationInfo(
|
||||
PIXEL_TIPS_APP_PACKAGE_NAME, PackageManager.GET_META_DATA));
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
Log.e(LOG_TAG,
|
||||
"Could not find app label for package name: "
|
||||
+ PIXEL_TIPS_APP_PACKAGE_NAME
|
||||
+ ". Defaulting to 'Pixel Tips.'",
|
||||
e);
|
||||
}
|
||||
|
||||
return null;
|
||||
TextView subtitleTextView = (TextView) contentView.findViewById(
|
||||
R.id.gesture_tutorial_dialog_subtitle);
|
||||
if (subtitleTextView != null) {
|
||||
subtitleTextView.setText(
|
||||
mContext.getString(R.string.skip_tutorial_dialog_subtitle, tipsAppName));
|
||||
} else {
|
||||
Log.w(LOG_TAG, "No subtitle view in the skip tutorial dialog to update.");
|
||||
}
|
||||
|
||||
Button cancelButton = (Button) contentView.findViewById(
|
||||
R.id.gesture_tutorial_dialog_cancel_button);
|
||||
if (cancelButton != null) {
|
||||
cancelButton.setOnClickListener(
|
||||
v -> tutorialDialog.dismiss());
|
||||
} else {
|
||||
Log.w(LOG_TAG, "No cancel button in the skip tutorial dialog to update.");
|
||||
}
|
||||
|
||||
Button confirmButton = contentView.findViewById(
|
||||
R.id.gesture_tutorial_dialog_confirm_button);
|
||||
if (confirmButton != null) {
|
||||
confirmButton.setOnClickListener(v -> {
|
||||
mTutorialFragment.closeTutorialStep(true);
|
||||
tutorialDialog.dismiss();
|
||||
});
|
||||
} else {
|
||||
Log.w(LOG_TAG, "No confirm button in the skip tutorial dialog to update.");
|
||||
}
|
||||
|
||||
tutorialDialog.getWindow().setBackgroundDrawable(
|
||||
new ColorDrawable(sandboxActivity.getColor(android.R.color.transparent)));
|
||||
|
||||
return tutorialDialog;
|
||||
}
|
||||
|
||||
protected AnimatorSet createFingerDotAppearanceAnimatorSet() {
|
||||
|
|
|
@ -18,11 +18,13 @@ package com.android.quickstep.interaction;
|
|||
import static android.view.View.NO_ID;
|
||||
|
||||
import static com.android.launcher3.config.FeatureFlags.ENABLE_NEW_GESTURE_NAV_TUTORIAL;
|
||||
import static com.android.quickstep.interaction.GestureSandboxActivity.KEY_GESTURE_COMPLETE;
|
||||
import static com.android.quickstep.interaction.GestureSandboxActivity.KEY_TUTORIAL_TYPE;
|
||||
import static com.android.quickstep.interaction.GestureSandboxActivity.KEY_USE_TUTORIAL_MENU;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorListenerAdapter;
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.graphics.Insets;
|
||||
|
@ -43,8 +45,6 @@ import android.widget.ImageView;
|
|||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.fragment.app.FragmentActivity;
|
||||
|
||||
import com.android.launcher3.DeviceProfile;
|
||||
import com.android.launcher3.InvariantDeviceProfile;
|
||||
|
@ -54,16 +54,17 @@ import com.android.quickstep.interaction.TutorialController.TutorialType;
|
|||
|
||||
import java.util.Set;
|
||||
|
||||
abstract class TutorialFragment extends Fragment implements OnTouchListener {
|
||||
/** Displays a gesture nav tutorial step. */
|
||||
abstract class TutorialFragment extends GestureSandboxFragment implements OnTouchListener {
|
||||
|
||||
private static final String LOG_TAG = "TutorialFragment";
|
||||
static final String KEY_TUTORIAL_TYPE = "tutorial_type";
|
||||
static final String KEY_GESTURE_COMPLETE = "gesture_complete";
|
||||
|
||||
private static final String TUTORIAL_SKIPPED_PREFERENCE_KEY = "pref_gestureTutorialSkipped";
|
||||
private static final String COMPLETED_TUTORIAL_STEPS_PREFERENCE_KEY =
|
||||
"pref_completedTutorialSteps";
|
||||
|
||||
private final boolean mFromTutorialMenu;
|
||||
|
||||
TutorialType mTutorialType;
|
||||
boolean mGestureComplete = false;
|
||||
@Nullable TutorialController mTutorialController = null;
|
||||
|
@ -85,10 +86,10 @@ abstract class TutorialFragment extends Fragment implements OnTouchListener {
|
|||
private boolean mIsFoldable;
|
||||
|
||||
public static TutorialFragment newInstance(
|
||||
TutorialType tutorialType, boolean gestureComplete) {
|
||||
TutorialFragment fragment = getFragmentForTutorialType(tutorialType);
|
||||
TutorialType tutorialType, boolean gestureComplete, boolean fromTutorialMenu) {
|
||||
TutorialFragment fragment = getFragmentForTutorialType(tutorialType, fromTutorialMenu);
|
||||
if (fragment == null) {
|
||||
fragment = new BackGestureTutorialFragment();
|
||||
fragment = new BackGestureTutorialFragment(fromTutorialMenu);
|
||||
tutorialType = TutorialType.BACK_NAVIGATION;
|
||||
}
|
||||
|
||||
|
@ -99,23 +100,28 @@ abstract class TutorialFragment extends Fragment implements OnTouchListener {
|
|||
return fragment;
|
||||
}
|
||||
|
||||
TutorialFragment(boolean fromTutorialMenu) {
|
||||
mFromTutorialMenu = fromTutorialMenu;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static TutorialFragment getFragmentForTutorialType(TutorialType tutorialType) {
|
||||
private static TutorialFragment getFragmentForTutorialType(
|
||||
TutorialType tutorialType, boolean fromTutorialMenu) {
|
||||
switch (tutorialType) {
|
||||
case BACK_NAVIGATION:
|
||||
case BACK_NAVIGATION_COMPLETE:
|
||||
return new BackGestureTutorialFragment();
|
||||
return new BackGestureTutorialFragment(fromTutorialMenu);
|
||||
case HOME_NAVIGATION:
|
||||
case HOME_NAVIGATION_COMPLETE:
|
||||
return new HomeGestureTutorialFragment();
|
||||
return new HomeGestureTutorialFragment(fromTutorialMenu);
|
||||
case OVERVIEW_NAVIGATION:
|
||||
case OVERVIEW_NAVIGATION_COMPLETE:
|
||||
return new OverviewGestureTutorialFragment();
|
||||
return new OverviewGestureTutorialFragment(fromTutorialMenu);
|
||||
case ASSISTANT:
|
||||
case ASSISTANT_COMPLETE:
|
||||
return new AssistantGestureTutorialFragment();
|
||||
return new AssistantGestureTutorialFragment(fromTutorialMenu);
|
||||
case SANDBOX_MODE:
|
||||
return new SandboxModeTutorialFragment();
|
||||
return new SandboxModeTutorialFragment(fromTutorialMenu);
|
||||
default:
|
||||
Log.e(LOG_TAG, "Failed to find an appropriate fragment for " + tutorialType.name());
|
||||
}
|
||||
|
@ -202,6 +208,7 @@ abstract class TutorialFragment extends Fragment implements OnTouchListener {
|
|||
mFingerDotView = mRootView.findViewById(R.id.gesture_tutorial_finger_dot);
|
||||
mFakePreviousTaskView = mRootView.findViewById(
|
||||
R.id.gesture_tutorial_fake_previous_task_view);
|
||||
|
||||
return mRootView;
|
||||
}
|
||||
|
||||
|
@ -355,6 +362,7 @@ abstract class TutorialFragment extends Fragment implements OnTouchListener {
|
|||
| mNavBarGestureHandler.onInterceptTouch(motionEvent);
|
||||
}
|
||||
|
||||
@Override
|
||||
void onAttachedToWindow() {
|
||||
StatsLogManager statsLogManager = getStatsLogManager();
|
||||
if (statsLogManager != null) {
|
||||
|
@ -363,6 +371,7 @@ abstract class TutorialFragment extends Fragment implements OnTouchListener {
|
|||
mEdgeBackGestureHandler.setViewGroupParent(getRootView());
|
||||
}
|
||||
|
||||
@Override
|
||||
void onDetachedFromWindow() {
|
||||
mEdgeBackGestureHandler.setViewGroupParent(null);
|
||||
}
|
||||
|
@ -385,6 +394,8 @@ abstract class TutorialFragment extends Fragment implements OnTouchListener {
|
|||
@Override
|
||||
public void onSaveInstanceState(Bundle savedInstanceState) {
|
||||
savedInstanceState.putSerializable(KEY_TUTORIAL_TYPE, mTutorialType);
|
||||
savedInstanceState.putBoolean(KEY_GESTURE_COMPLETE, isGestureComplete());
|
||||
savedInstanceState.putBoolean(KEY_USE_TUTORIAL_MENU, mFromTutorialMenu);
|
||||
super.onSaveInstanceState(savedInstanceState);
|
||||
}
|
||||
|
||||
|
@ -410,17 +421,18 @@ abstract class TutorialFragment extends Fragment implements OnTouchListener {
|
|||
|
||||
GestureSandboxActivity gestureSandboxActivity = getGestureSandboxActivity();
|
||||
if (gestureSandboxActivity == null) {
|
||||
closeTutorial();
|
||||
close();
|
||||
return;
|
||||
}
|
||||
gestureSandboxActivity.continueTutorial();
|
||||
}
|
||||
|
||||
void closeTutorial() {
|
||||
closeTutorial(false);
|
||||
@Override
|
||||
void close() {
|
||||
closeTutorialStep(false);
|
||||
}
|
||||
|
||||
void closeTutorial(boolean tutorialSkipped) {
|
||||
void closeTutorialStep(boolean tutorialSkipped) {
|
||||
if (tutorialSkipped) {
|
||||
SharedPreferences sharedPrefs = getSharedPreferences();
|
||||
if (sharedPrefs != null) {
|
||||
|
@ -432,11 +444,12 @@ abstract class TutorialFragment extends Fragment implements OnTouchListener {
|
|||
StatsLogManager.LauncherEvent.LAUNCHER_GESTURE_TUTORIAL_SKIPPED);
|
||||
}
|
||||
}
|
||||
FragmentActivity activity = getActivity();
|
||||
if (activity != null) {
|
||||
activity.setResult(Activity.RESULT_OK);
|
||||
activity.finish();
|
||||
GestureSandboxActivity gestureSandboxActivity = getGestureSandboxActivity();
|
||||
if (mFromTutorialMenu && gestureSandboxActivity != null) {
|
||||
gestureSandboxActivity.launchTutorialMenu();
|
||||
return;
|
||||
}
|
||||
super.close();
|
||||
}
|
||||
|
||||
void startSystemNavigationSetting() {
|
||||
|
@ -470,9 +483,10 @@ abstract class TutorialFragment extends Fragment implements OnTouchListener {
|
|||
|
||||
@Nullable
|
||||
private GestureSandboxActivity getGestureSandboxActivity() {
|
||||
Context context = getContext();
|
||||
Activity activity = getActivity();
|
||||
|
||||
return context instanceof GestureSandboxActivity ? (GestureSandboxActivity) context : null;
|
||||
return activity instanceof GestureSandboxActivity
|
||||
? (GestureSandboxActivity) activity : null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
|
Loading…
Reference in New Issue