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:
danielwbhuang
2023-01-11 04:20:45 +08:00
committed by Daniel Huang
parent 4525cfb462
commit 40cab1692d
17 changed files with 751 additions and 6 deletions

View 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>

View 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>

View 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>

View 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>

View 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>

View 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>

View 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>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -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 &amp; 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] -->

View File

@@ -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);
} }
} }

View File

@@ -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;
}
}

View File

@@ -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

View File

@@ -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