1. Use edge-to-edge UI 2. Use new color token 3. Put text in the middle of the button Bug:279163958 Bug:278504911 Test: manual Change-Id: I189e9da2251f7d204ddc18680d3d1ec4638fa2db
330 lines
12 KiB
Java
330 lines
12 KiB
Java
/*
|
|
* 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.view.WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG;
|
|
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL;
|
|
|
|
import android.app.Activity;
|
|
import android.app.Dialog;
|
|
import android.content.Context;
|
|
import android.graphics.Color;
|
|
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.ViewTreeObserver;
|
|
import android.view.Window;
|
|
import android.view.WindowInsets;
|
|
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;
|
|
}
|
|
setLayoutEdgeToEdge(window);
|
|
final Point size = getScreenSize();
|
|
final WindowManager.LayoutParams attributes = window.getAttributes();
|
|
attributes.width = (int) (size.x * 0.75);
|
|
window.setAttributes(attributes);
|
|
}
|
|
|
|
@Override
|
|
public void onPause() {
|
|
super.onPause();
|
|
dismiss();
|
|
}
|
|
|
|
private static void setLayoutEdgeToEdge(Window window) {
|
|
View windowDecorView = window.getDecorView();
|
|
windowDecorView.setSystemUiVisibility(
|
|
windowDecorView.getSystemUiVisibility()
|
|
| View.SYSTEM_UI_FLAG_LAYOUT_STABLE
|
|
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
|
|
window.setNavigationBarColor(Color.TRANSPARENT);
|
|
}
|
|
|
|
@Override
|
|
public Dialog onCreateDialog(final Bundle savedInstanceState) {
|
|
Dialog dialog = super.onCreateDialog(savedInstanceState);
|
|
|
|
mInflater = mContext.getSystemService(LayoutInflater.class);
|
|
View contentView = mInflater.inflate(R.layout.trackpad_gesture_preview, null);
|
|
addViewPager(contentView);
|
|
dialog.setContentView(contentView);
|
|
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<FrameLayout> behavior = BottomSheetBehavior.from(bottomSheet);
|
|
if (!isGestureNavigationEnabled()) {
|
|
behavior.setState(BottomSheetBehavior.STATE_EXPANDED);
|
|
}
|
|
ViewTreeObserver observer = contentView.getViewTreeObserver();
|
|
observer.addOnGlobalLayoutListener(
|
|
new ViewTreeObserver.OnGlobalLayoutListener() {
|
|
@Override
|
|
public void onGlobalLayout() {
|
|
contentView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
|
|
int contentViewHeight = contentView.getMeasuredHeight();
|
|
int navigationBarHeight = getNavigationBarHeight();
|
|
behavior.setPeekHeight(contentViewHeight - navigationBarHeight);
|
|
}
|
|
});
|
|
|
|
// The gesture education view shouldn't be draggable."
|
|
behavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
|
|
@Override
|
|
public void onStateChanged(View bottomSheet, int newState) {
|
|
if (newState == BottomSheetBehavior.STATE_DRAGGING) {
|
|
if (isGestureNavigationEnabled()) {
|
|
behavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
|
|
} else {
|
|
behavior.setState(BottomSheetBehavior.STATE_EXPANDED);
|
|
}
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void onSlide(View bottomSheet, float slideOffset) {
|
|
// Do nothing.
|
|
}
|
|
});
|
|
|
|
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;
|
|
}
|
|
|
|
private int getNavigationBarHeight() {
|
|
final Activity activity = (Activity) mContext;
|
|
WindowInsets insets =
|
|
activity.getWindowManager().getCurrentWindowMetrics().getWindowInsets();
|
|
return insets.getInsets(WindowInsets.Type.navigationBars()).bottom;
|
|
}
|
|
|
|
private boolean isGestureNavigationEnabled() {
|
|
return NAV_BAR_MODE_GESTURAL == mContext.getResources().getInteger(
|
|
com.android.internal.R.integer.config_navBarInteractionMode);
|
|
}
|
|
}
|