Implement trackpad gestures education UI.
1. Use BottomSheetDialogFragment. 2. Use LottieAnimationView for animation 3. Add 5 animation assets Demo: go/trackpad_education_demo Bug: 247080509 Test: manual Change-Id: Icac7a6cd51763ca20b7661d6f1d4cc95af5292e9
This commit is contained in:
committed by
Daniel Huang
parent
4525cfb462
commit
40cab1692d
24
res/drawable/trackpad_gesture_dialog_bg.xml
Normal file
24
res/drawable/trackpad_gesture_dialog_bg.xml
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
Copyright (C) 2022 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">
|
||||||
|
<solid android:color="?android:attr/colorBackground"/>
|
||||||
|
<corners android:topLeftRadius="16dp"
|
||||||
|
android:topRightRadius="16dp"
|
||||||
|
android:bottomLeftRadius="0dp"
|
||||||
|
android:bottomRightRadius="0dp"/>
|
||||||
|
</shape>
|
62
res/layout/gesture_tip1_go_home.xml
Normal file
62
res/layout/gesture_tip1_go_home.xml
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
<?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.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
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:orientation="vertical">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/title"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="32dp"
|
||||||
|
android:layout_marginLeft="24dp"
|
||||||
|
android:layout_marginRight="24dp"
|
||||||
|
android:layout_gravity="center_horizontal"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceLarge"
|
||||||
|
android:text="@string/gesture_title_go_home"
|
||||||
|
android:textColor="?android:attr/textColorPrimary"/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/summary"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginLeft="24dp"
|
||||||
|
android:layout_marginRight="24dp"
|
||||||
|
android:layout_gravity="center_horizontal"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||||
|
android:text="@string/gesture_summary_go_home"
|
||||||
|
android:textColor="?android:attr/textColorSecondary"/>
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:foregroundGravity="center_horizontal">
|
||||||
|
|
||||||
|
<com.airbnb.lottie.LottieAnimationView
|
||||||
|
android:id="@+id/gesture_tip1_go_home"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
android:scaleType="centerInside"
|
||||||
|
app:lottie_autoPlay="true"
|
||||||
|
app:lottie_loop="true"
|
||||||
|
app:lottie_rawRes="@raw/gesture_tip1_go_home" />
|
||||||
|
</FrameLayout>
|
||||||
|
</LinearLayout>
|
62
res/layout/gesture_tip2_go_back.xml
Normal file
62
res/layout/gesture_tip2_go_back.xml
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
<?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.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
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:orientation="vertical">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/title"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="32dp"
|
||||||
|
android:layout_marginLeft="24dp"
|
||||||
|
android:layout_marginRight="24dp"
|
||||||
|
android:layout_gravity="center_horizontal"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceLarge"
|
||||||
|
android:text="@string/gesture_title_go_back"
|
||||||
|
android:textColor="?android:attr/textColorPrimary"/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/summary"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginLeft="24dp"
|
||||||
|
android:layout_marginRight="24dp"
|
||||||
|
android:layout_gravity="center_horizontal"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||||
|
android:text="@string/gesture_summary_go_back"
|
||||||
|
android:textColor="?android:attr/textColorSecondary"/>
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:foregroundGravity="center_horizontal">
|
||||||
|
|
||||||
|
<com.airbnb.lottie.LottieAnimationView
|
||||||
|
android:id="@+id/gesture_tip2_go_back"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
android:scaleType="centerInside"
|
||||||
|
app:lottie_autoPlay="true"
|
||||||
|
app:lottie_loop="true"
|
||||||
|
app:lottie_rawRes="@raw/gesture_tip2_go_back" />
|
||||||
|
</FrameLayout>
|
||||||
|
</LinearLayout>
|
62
res/layout/gesture_tip3_recent_apps.xml
Normal file
62
res/layout/gesture_tip3_recent_apps.xml
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
<?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.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
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:orientation="vertical">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/title"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="32dp"
|
||||||
|
android:layout_marginLeft="24dp"
|
||||||
|
android:layout_marginRight="24dp"
|
||||||
|
android:layout_gravity="center_horizontal"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceLarge"
|
||||||
|
android:text="@string/gesture_title_recent_apps"
|
||||||
|
android:textColor="?android:attr/textColorPrimary"/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/summary"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginLeft="24dp"
|
||||||
|
android:layout_marginRight="24dp"
|
||||||
|
android:layout_gravity="center_horizontal"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||||
|
android:text="@string/gesture_summary_recent_apps"
|
||||||
|
android:textColor="?android:attr/textColorSecondary"/>
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:foregroundGravity="center_horizontal">
|
||||||
|
|
||||||
|
<com.airbnb.lottie.LottieAnimationView
|
||||||
|
android:id="@+id/gesture_tip3_recent_apps"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
android:scaleType="centerInside"
|
||||||
|
app:lottie_autoPlay="true"
|
||||||
|
app:lottie_loop="true"
|
||||||
|
app:lottie_rawRes="@raw/gesture_tip3_recent_apps" />
|
||||||
|
</FrameLayout>
|
||||||
|
</LinearLayout>
|
62
res/layout/gesture_tip4_notifications.xml
Normal file
62
res/layout/gesture_tip4_notifications.xml
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
<?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.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
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:orientation="vertical">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/title"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="32dp"
|
||||||
|
android:layout_marginLeft="24dp"
|
||||||
|
android:layout_marginRight="24dp"
|
||||||
|
android:layout_gravity="center_horizontal"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceLarge"
|
||||||
|
android:text="@string/gesture_title_notifications"
|
||||||
|
android:textColor="?android:attr/textColorPrimary"/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/summary"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginLeft="24dp"
|
||||||
|
android:layout_marginRight="24dp"
|
||||||
|
android:layout_gravity="center_horizontal"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||||
|
android:text="@string/gesture_summary_notifications"
|
||||||
|
android:textColor="?android:attr/textColorSecondary"/>
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:foregroundGravity="center_horizontal">
|
||||||
|
|
||||||
|
<com.airbnb.lottie.LottieAnimationView
|
||||||
|
android:id="@+id/gesture_tip4_notifications"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
android:scaleType="centerInside"
|
||||||
|
app:lottie_autoPlay="true"
|
||||||
|
app:lottie_loop="true"
|
||||||
|
app:lottie_rawRes="@raw/gesture_tip4_notifications" />
|
||||||
|
</FrameLayout>
|
||||||
|
</LinearLayout>
|
62
res/layout/gesture_tip5_switch_apps.xml
Normal file
62
res/layout/gesture_tip5_switch_apps.xml
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
<?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.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
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:orientation="vertical">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/title"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="32dp"
|
||||||
|
android:layout_marginLeft="24dp"
|
||||||
|
android:layout_marginRight="24dp"
|
||||||
|
android:layout_gravity="center_horizontal"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceLarge"
|
||||||
|
android:text="@string/gesture_title_switch_apps"
|
||||||
|
android:textColor="?android:attr/textColorPrimary"/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/summary"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginLeft="24dp"
|
||||||
|
android:layout_marginRight="24dp"
|
||||||
|
android:layout_gravity="center_horizontal"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||||
|
android:text="@string/gesture_summary_switch_apps"
|
||||||
|
android:textColor="?android:attr/textColorSecondary"/>
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:foregroundGravity="center_horizontal">
|
||||||
|
|
||||||
|
<com.airbnb.lottie.LottieAnimationView
|
||||||
|
android:id="@+id/gesture_tip5_switch_apps"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
android:scaleType="centerInside"
|
||||||
|
app:lottie_autoPlay="true"
|
||||||
|
app:lottie_loop="true"
|
||||||
|
app:lottie_rawRes="@raw/gesture_tip5_switch_apps" />
|
||||||
|
</FrameLayout>
|
||||||
|
</LinearLayout>
|
102
res/layout/trackpad_gesture_preview.xml
Normal file
102
res/layout/trackpad_gesture_preview.xml
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Copyright (C) 2022 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.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
|
||||||
|
android:background="@drawable/trackpad_gesture_dialog_bg"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
|
<androidx.viewpager.widget.ViewPager
|
||||||
|
android:id="@+id/viewpager"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="378dp"/>
|
||||||
|
|
||||||
|
<RelativeLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="48dp"
|
||||||
|
android:layout_marginStart="8dip"
|
||||||
|
android:layout_marginEnd="8dip"
|
||||||
|
android:layout_marginTop="6dip"
|
||||||
|
android:layout_marginBottom="6dip"
|
||||||
|
android:layout_weight="1">
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/button_skip"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="6dip"
|
||||||
|
android:layout_marginBottom="6dip"
|
||||||
|
android:layout_marginStart="8dip"
|
||||||
|
android:layout_alignParentStart="true"
|
||||||
|
android:paddingVertical="14dp"
|
||||||
|
android:drawablePadding="9dp"
|
||||||
|
style="@style/ModifierKeyButtonCancel"
|
||||||
|
android:textColor="?android:attr/textColorPrimary"
|
||||||
|
android:text="@string/gesture_button_skip"/>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/button_restart"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="6dip"
|
||||||
|
android:layout_marginBottom="6dip"
|
||||||
|
android:layout_marginStart="8dip"
|
||||||
|
android:layout_alignParentStart="true"
|
||||||
|
android:paddingVertical="14dp"
|
||||||
|
android:drawablePadding="9dp"
|
||||||
|
style="@style/ModifierKeyButtonCancel"
|
||||||
|
android:textColor="?android:attr/textColorPrimary"
|
||||||
|
android:text="@string/gesture_button_restart"/>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/viewGroup"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="48dp"
|
||||||
|
android:gravity="center"/>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/button_next"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="6dip"
|
||||||
|
android:layout_marginBottom="6dip"
|
||||||
|
android:layout_marginEnd="8dip"
|
||||||
|
android:layout_alignParentEnd="true"
|
||||||
|
android:paddingVertical="14dp"
|
||||||
|
android:drawablePadding="9dp"
|
||||||
|
style="@style/ModifierKeyButtonDone"
|
||||||
|
android:textColor="?androidprv:attr/textColorOnAccent"
|
||||||
|
android:text="@string/gesture_button_next"/>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/button_done"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="6dip"
|
||||||
|
android:layout_marginBottom="6dip"
|
||||||
|
android:layout_marginEnd="8dip"
|
||||||
|
android:layout_alignParentEnd="true"
|
||||||
|
android:paddingVertical="14dp"
|
||||||
|
android:drawablePadding="9dp"
|
||||||
|
style="@style/ModifierKeyButtonDone"
|
||||||
|
android:textColor="?androidprv:attr/textColorOnAccent"
|
||||||
|
android:text="@string/gesture_button_done"/>
|
||||||
|
</RelativeLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
1
res/raw/gesture_tip1_go_home.json
Normal file
1
res/raw/gesture_tip1_go_home.json
Normal file
File diff suppressed because one or more lines are too long
1
res/raw/gesture_tip2_go_back.json
Normal file
1
res/raw/gesture_tip2_go_back.json
Normal file
File diff suppressed because one or more lines are too long
1
res/raw/gesture_tip3_recent_apps.json
Normal file
1
res/raw/gesture_tip3_recent_apps.json
Normal file
File diff suppressed because one or more lines are too long
1
res/raw/gesture_tip4_notifications.json
Normal file
1
res/raw/gesture_tip4_notifications.json
Normal file
File diff suppressed because one or more lines are too long
1
res/raw/gesture_tip5_switch_apps.json
Normal file
1
res/raw/gesture_tip5_switch_apps.json
Normal file
File diff suppressed because one or more lines are too long
@@ -3738,6 +3738,36 @@
|
|||||||
<!-- Title for the button to trigger the 'touch gesture' education. [CHAR LIMIT=35] -->
|
<!-- Title for the button to trigger the 'touch gesture' education. [CHAR LIMIT=35] -->
|
||||||
<string name="trackpad_touch_gesture">Learn touchpad gestures</string>
|
<string name="trackpad_touch_gesture">Learn touchpad gestures</string>
|
||||||
|
|
||||||
|
<!-- Title text for 'Go home' gesture education [CHAR LIMIT=35] -->
|
||||||
|
<string name="gesture_title_go_home">Go home</string>
|
||||||
|
<!-- Summary text for 'Go home' gesture education [CHAR LIMIT=60] -->
|
||||||
|
<string name="gesture_summary_go_home">Swipe up with three fingers anywhere on your touchpad</string>
|
||||||
|
<!-- Title text for 'Go back' gesture education [CHAR LIMIT=35] -->
|
||||||
|
<string name="gesture_title_go_back">Go back</string>
|
||||||
|
<!-- Summary text for 'Go back' gesture education [CHAR LIMIT=60] -->
|
||||||
|
<string name="gesture_summary_go_back">Swipe from the left or right with three fingers</string>
|
||||||
|
<!-- Title text for 'View recent apps' gesture education [CHAR LIMIT=35] -->
|
||||||
|
<string name="gesture_title_recent_apps">View recent apps</string>
|
||||||
|
<!-- Summary text for 'View recent apps' gesture education [CHAR LIMIT=60] -->
|
||||||
|
<string name="gesture_summary_recent_apps">Swipe up with three fingers, hold, then release</string>
|
||||||
|
<!-- Title text for 'View notifications' gesture education [CHAR LIMIT=35] -->
|
||||||
|
<string name="gesture_title_notifications">View notifications & Quick Settings</string>
|
||||||
|
<!-- Summary text for 'View notifications' gesture education [CHAR LIMIT=60] -->
|
||||||
|
<string name="gesture_summary_notifications">Swipe down with three fingers on your home screen</string>
|
||||||
|
<!-- Title text for 'Switch apps' gesture education [CHAR LIMIT=35] -->
|
||||||
|
<string name="gesture_title_switch_apps">Switch apps</string>
|
||||||
|
<!-- Summary text for 'Switch apps' gesture education [CHAR LIMIT=60] -->
|
||||||
|
<string name="gesture_summary_switch_apps">Swipe left or right with four fingers</string>
|
||||||
|
|
||||||
|
<!-- Text for 'Skip' button in gesture education [CHAR LIMIT=10] -->
|
||||||
|
<string name="gesture_button_skip">Skip</string>
|
||||||
|
<!-- Text for 'Next' button in gesture education [CHAR LIMIT=10] -->
|
||||||
|
<string name="gesture_button_next">Next</string>
|
||||||
|
<!-- Text for 'Restart' button in gesture education [CHAR LIMIT=10] -->
|
||||||
|
<string name="gesture_button_restart">Restart</string>
|
||||||
|
<!-- Text for 'Done' button in gesture education [CHAR LIMIT=10] -->
|
||||||
|
<string name="gesture_button_done">Done</string>
|
||||||
|
|
||||||
<!-- Title text for 'Go back' [CHAR LIMIT=35] -->
|
<!-- Title text for 'Go back' [CHAR LIMIT=35] -->
|
||||||
<string name="trackpad_go_back_title">Go back</string>
|
<string name="trackpad_go_back_title">Go back</string>
|
||||||
<!-- Summary text for 'Go back' [CHAR LIMIT=60] -->
|
<!-- Summary text for 'Go back' [CHAR LIMIT=60] -->
|
||||||
|
@@ -19,6 +19,7 @@ package com.android.settings.inputmethod;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.util.FeatureFlagUtils;
|
import android.util.FeatureFlagUtils;
|
||||||
|
|
||||||
|
import androidx.fragment.app.Fragment;
|
||||||
import androidx.preference.PreferenceScreen;
|
import androidx.preference.PreferenceScreen;
|
||||||
|
|
||||||
import com.android.settings.core.BasePreferenceController;
|
import com.android.settings.core.BasePreferenceController;
|
||||||
@@ -29,11 +30,18 @@ public class TouchGesturesButtonPreferenceController extends BasePreferenceContr
|
|||||||
private static final int ORDER_TOP = 0;
|
private static final int ORDER_TOP = 0;
|
||||||
private static final int ORDER_BOTTOM = 100;
|
private static final int ORDER_BOTTOM = 100;
|
||||||
private static final String PREFERENCE_KEY = "trackpad_touch_gesture";
|
private static final String PREFERENCE_KEY = "trackpad_touch_gesture";
|
||||||
|
private static final String GESTURE_DIALOG_TAG = "GESTURE_DIALOG_TAG";
|
||||||
|
|
||||||
|
private Fragment mParent;
|
||||||
|
|
||||||
public TouchGesturesButtonPreferenceController(Context context, String key) {
|
public TouchGesturesButtonPreferenceController(Context context, String key) {
|
||||||
super(context, key);
|
super(context, key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setFragment(Fragment parent) {
|
||||||
|
mParent = parent;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void displayPreference(PreferenceScreen screen) {
|
public void displayPreference(PreferenceScreen screen) {
|
||||||
super.displayPreference(screen);
|
super.displayPreference(screen);
|
||||||
@@ -59,12 +67,8 @@ public class TouchGesturesButtonPreferenceController extends BasePreferenceContr
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void showTouchpadGestureEducation() {
|
private void showTouchpadGestureEducation() {
|
||||||
// TODO: Waiting for the education UX design.
|
|
||||||
/* For example:
|
|
||||||
FragmentManager fragmentManager = mParent.getActivity().getSupportFragmentManager();
|
|
||||||
FragmentTransaction transaction = fragmentManager.beginTransaction();
|
|
||||||
TrackpadGestureDialogFragment fragment = new TrackpadGestureDialogFragment();
|
TrackpadGestureDialogFragment fragment = new TrackpadGestureDialogFragment();
|
||||||
fragment.show(transaction, GESTURE_DIALOG_TAG);
|
fragment.setTargetFragment(mParent, 0);
|
||||||
*/
|
fragment.show(mParent.getActivity().getSupportFragmentManager(), GESTURE_DIALOG_TAG);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,268 @@
|
|||||||
|
/*
|
||||||
|
* 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.settings.inputmethod;
|
||||||
|
|
||||||
|
import static android.content.Context.LAYOUT_INFLATER_SERVICE;
|
||||||
|
import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.app.Dialog;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.graphics.Point;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.view.Display;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.view.Window;
|
||||||
|
import android.view.WindowManager;
|
||||||
|
import android.widget.Button;
|
||||||
|
import android.widget.FrameLayout;
|
||||||
|
import android.widget.ImageView;
|
||||||
|
|
||||||
|
import androidx.viewpager.widget.PagerAdapter;
|
||||||
|
import androidx.viewpager.widget.ViewPager;
|
||||||
|
|
||||||
|
import com.android.settings.R;
|
||||||
|
|
||||||
|
import com.google.android.material.bottomsheet.BottomSheetBehavior;
|
||||||
|
import com.google.android.material.bottomsheet.BottomSheetDialogFragment;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
public class TrackpadGestureDialogFragment extends BottomSheetDialogFragment {
|
||||||
|
|
||||||
|
private Context mContext;
|
||||||
|
private LayoutInflater mInflater;
|
||||||
|
private View mViewArrowPrevious;
|
||||||
|
private View mViewArrowNext;
|
||||||
|
private ViewPager mViewPager;
|
||||||
|
private ArrayList<View> mPageList;
|
||||||
|
private ImageView[] mDotIndicators;
|
||||||
|
private View[] mViewPagerItems;
|
||||||
|
private Button mButtonStartSkip;
|
||||||
|
private Button mButtonStartRestart;
|
||||||
|
private Button mButtonEndNext;
|
||||||
|
private Button mButtonEndDone;
|
||||||
|
|
||||||
|
private static final int DOT_INDICATOR_SIZE = 12;
|
||||||
|
private static final int DOT_INDICATOR_LEFT_PADDING = 6;
|
||||||
|
private static final int DOT_INDICATOR_RIGHT_PADDING = 6;
|
||||||
|
|
||||||
|
public TrackpadGestureDialogFragment() {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAttach(Context context) {
|
||||||
|
super.onAttach(context);
|
||||||
|
mContext = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStart() {
|
||||||
|
super.onStart();
|
||||||
|
final Dialog dialog = getDialog();
|
||||||
|
if (dialog == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Window window = dialog.getWindow();
|
||||||
|
if (window == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final Point size = getScreenSize();
|
||||||
|
final WindowManager.LayoutParams attributes = window.getAttributes();
|
||||||
|
attributes.width = (int) (size.x * 0.75);
|
||||||
|
window.setAttributes(attributes);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Dialog onCreateDialog(final Bundle savedInstanceState) {
|
||||||
|
Dialog dialog = super.onCreateDialog(savedInstanceState);
|
||||||
|
mInflater = (LayoutInflater) mContext.getSystemService(
|
||||||
|
LAYOUT_INFLATER_SERVICE);
|
||||||
|
|
||||||
|
View gestureEducationView = mInflater.inflate(R.layout.trackpad_gesture_preview, null);
|
||||||
|
addViewPager(gestureEducationView);
|
||||||
|
dialog.setContentView(gestureEducationView);
|
||||||
|
|
||||||
|
Window gestureDialogWindow = dialog.getWindow();
|
||||||
|
gestureDialogWindow.setType(TYPE_SYSTEM_DIALOG);
|
||||||
|
|
||||||
|
// Workaround for solve issue about dialog not full expanded when landscape.
|
||||||
|
FrameLayout bottomSheet = (FrameLayout)
|
||||||
|
dialog.findViewById(com.google.android.material.R.id.design_bottom_sheet);
|
||||||
|
bottomSheet.setBackgroundResource(android.R.color.transparent);
|
||||||
|
BottomSheetBehavior.from(bottomSheet)
|
||||||
|
.setState(BottomSheetBehavior.STATE_EXPANDED);
|
||||||
|
|
||||||
|
return dialog;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ArrayList<Integer> getViewPagerResource() {
|
||||||
|
return new ArrayList<Integer>(
|
||||||
|
Arrays.asList(
|
||||||
|
R.layout.gesture_tip1_go_home,
|
||||||
|
R.layout.gesture_tip2_go_back,
|
||||||
|
R.layout.gesture_tip3_recent_apps,
|
||||||
|
R.layout.gesture_tip4_notifications,
|
||||||
|
R.layout.gesture_tip5_switch_apps));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addViewPager(View preview) {
|
||||||
|
mViewPager = preview.findViewById(R.id.viewpager);
|
||||||
|
int viewPagerResourceSize = getViewPagerResource().size();
|
||||||
|
mViewPagerItems = new View[viewPagerResourceSize];
|
||||||
|
for (int i = 0; i < viewPagerResourceSize; i++) {
|
||||||
|
mViewPagerItems[i] =
|
||||||
|
mInflater.inflate(getViewPagerResource().get(i), null /* root */);
|
||||||
|
}
|
||||||
|
|
||||||
|
mPageList = new ArrayList<View>();
|
||||||
|
for (int i = 0; i < mViewPagerItems.length; i++) {
|
||||||
|
mPageList.add(mViewPagerItems[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
mViewPager.setAdapter(new GesturePagerAdapter(mPageList));
|
||||||
|
|
||||||
|
mButtonStartRestart = (Button) preview.findViewById(R.id.button_restart);
|
||||||
|
mButtonStartRestart.setOnClickListener(v -> {
|
||||||
|
final int firstPos = mViewPager.getCurrentItem() - mViewPagerItems.length;
|
||||||
|
mViewPager.setCurrentItem(firstPos, true);
|
||||||
|
});
|
||||||
|
|
||||||
|
mButtonEndDone = (Button) preview.findViewById(R.id.button_done);
|
||||||
|
mButtonEndDone.setOnClickListener(v -> {
|
||||||
|
dismiss();
|
||||||
|
});
|
||||||
|
|
||||||
|
mButtonStartSkip = (Button) preview.findViewById(R.id.button_skip);
|
||||||
|
mButtonStartSkip.setOnClickListener(v -> {
|
||||||
|
dismiss();
|
||||||
|
});
|
||||||
|
|
||||||
|
mButtonEndNext = (Button) preview.findViewById(R.id.button_next);
|
||||||
|
mButtonEndNext.setOnClickListener(v -> {
|
||||||
|
final int nextPos = mViewPager.getCurrentItem() + 1;
|
||||||
|
mViewPager.setCurrentItem(nextPos, true);
|
||||||
|
});
|
||||||
|
|
||||||
|
mViewPager.addOnPageChangeListener(createPageListener());
|
||||||
|
final ViewGroup viewGroup = (ViewGroup) preview.findViewById(R.id.viewGroup);
|
||||||
|
mDotIndicators = new ImageView[mPageList.size()];
|
||||||
|
for (int i = 0; i < mPageList.size(); i++) {
|
||||||
|
final ImageView imageView = new ImageView(mContext);
|
||||||
|
final ViewGroup.MarginLayoutParams lp =
|
||||||
|
new ViewGroup.MarginLayoutParams(DOT_INDICATOR_SIZE, DOT_INDICATOR_SIZE);
|
||||||
|
lp.setMargins(DOT_INDICATOR_LEFT_PADDING, 0, DOT_INDICATOR_RIGHT_PADDING, 0);
|
||||||
|
imageView.setLayoutParams(lp);
|
||||||
|
mDotIndicators[i] = imageView;
|
||||||
|
viewGroup.addView(mDotIndicators[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class GesturePagerAdapter extends PagerAdapter {
|
||||||
|
private final ArrayList<View> mPageViewList;
|
||||||
|
|
||||||
|
GesturePagerAdapter(ArrayList<View> pageViewList) {
|
||||||
|
mPageViewList = pageViewList;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void destroyItem(ViewGroup container, int position, Object object) {
|
||||||
|
if (mPageViewList.get(position) != null) {
|
||||||
|
container.removeView(mPageViewList.get(position));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object instantiateItem(ViewGroup container, int position) {
|
||||||
|
container.addView(mPageViewList.get(position));
|
||||||
|
return mPageViewList.get(position);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getCount() {
|
||||||
|
return mPageViewList.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isViewFromObject(View view, Object object) {
|
||||||
|
return object == view;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private ViewPager.OnPageChangeListener createPageListener() {
|
||||||
|
return new ViewPager.OnPageChangeListener() {
|
||||||
|
@Override
|
||||||
|
public void onPageScrolled(
|
||||||
|
int position, float positionOffset, int positionOffsetPixels) {
|
||||||
|
if (positionOffset != 0) {
|
||||||
|
for (int i = 0; i < mPageList.size(); i++) {
|
||||||
|
mViewPagerItems[i].setVisibility(View.VISIBLE);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
updateIndicator(position);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPageSelected(int position) {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPageScrollStateChanged(int state) {}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateIndicator(int position) {
|
||||||
|
for (int i = 0; i < mPageList.size(); i++) {
|
||||||
|
if (position == i) {
|
||||||
|
mDotIndicators[i].setBackgroundResource(
|
||||||
|
R.drawable.ic_color_page_indicator_focused);
|
||||||
|
mViewPagerItems[i].setVisibility(View.VISIBLE);
|
||||||
|
} else {
|
||||||
|
mDotIndicators[i].setBackgroundResource(
|
||||||
|
R.drawable.ic_color_page_indicator_unfocused);
|
||||||
|
mViewPagerItems[i].setVisibility(View.INVISIBLE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (position >= 0 && position < mViewPagerItems.length - 1) {
|
||||||
|
mButtonStartSkip.setVisibility(View.VISIBLE);
|
||||||
|
mButtonEndNext.setVisibility(View.VISIBLE);
|
||||||
|
mButtonStartRestart.setVisibility(View.GONE);
|
||||||
|
mButtonEndDone.setVisibility(View.GONE);
|
||||||
|
} else {
|
||||||
|
mButtonStartSkip.setVisibility(View.GONE);
|
||||||
|
mButtonEndNext.setVisibility(View.GONE);
|
||||||
|
mButtonStartRestart.setVisibility(View.VISIBLE);
|
||||||
|
mButtonEndDone.setVisibility(View.VISIBLE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Point getScreenSize() {
|
||||||
|
final Point size = new Point();
|
||||||
|
final Activity activity = (Activity) mContext;
|
||||||
|
final Display display = activity.getWindowManager().getDefaultDisplay();
|
||||||
|
display.getSize(size);
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
}
|
@@ -31,6 +31,7 @@ public class TrackpadSettings extends DashboardFragment {
|
|||||||
@Override
|
@Override
|
||||||
public void onAttach(Context context) {
|
public void onAttach(Context context) {
|
||||||
super.onAttach(context);
|
super.onAttach(context);
|
||||||
|
use(TouchGesturesButtonPreferenceController.class).setFragment(this /*parent*/);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@@ -31,6 +31,7 @@ public class TrackpadTouchGestureSettings extends DashboardFragment {
|
|||||||
@Override
|
@Override
|
||||||
public void onAttach(Context context) {
|
public void onAttach(Context context) {
|
||||||
super.onAttach(context);
|
super.onAttach(context);
|
||||||
|
use(TouchGesturesButtonPreferenceController.class).setFragment(this /*parent*/);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
Reference in New Issue
Block a user