Removing arrow indicator from homescreen and
adding a separate view for various accessibility actions Bug: 159247871 Change-Id: I14536844929e03d36a6a5f294d4f5daad8c82d15
This commit is contained in:
parent
0edfbc64d4
commit
52e2545a66
|
@ -215,10 +215,8 @@ public class QuickstepLauncher extends BaseQuickstepLauncher {
|
|||
switch (state.ordinal) {
|
||||
case HINT_STATE_ORDINAL: {
|
||||
Workspace workspace = getWorkspace();
|
||||
boolean willMoveScreens = workspace.getNextPage() != Workspace.DEFAULT_PAGE;
|
||||
getStateManager().goToState(NORMAL, true,
|
||||
willMoveScreens ? null : getScrimView()::startDragHandleEducationAnim);
|
||||
if (willMoveScreens) {
|
||||
getStateManager().goToState(NORMAL);
|
||||
if (workspace.getNextPage() != Workspace.DEFAULT_PAGE) {
|
||||
workspace.post(workspace::moveToDefaultScreen);
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -38,11 +38,9 @@ import android.widget.FrameLayout;
|
|||
import com.android.launcher3.BaseQuickstepLauncher;
|
||||
import com.android.launcher3.Hotseat;
|
||||
import com.android.launcher3.LauncherState;
|
||||
import com.android.launcher3.anim.Interpolators;
|
||||
import com.android.launcher3.statehandlers.DepthController;
|
||||
import com.android.launcher3.statemanager.StateManager.StateListener;
|
||||
import com.android.launcher3.uioverrides.plugins.PluginManagerWrapper;
|
||||
import com.android.launcher3.views.ScrimView;
|
||||
import com.android.quickstep.LauncherActivityInterface;
|
||||
import com.android.quickstep.SysUINavigationMode;
|
||||
import com.android.systemui.plugins.PluginListener;
|
||||
|
@ -126,12 +124,6 @@ public class LauncherRecentsView extends RecentsView<BaseQuickstepLauncher>
|
|||
}
|
||||
anim.play(ObjectAnimator.ofFloat(
|
||||
mActivity.getAllAppsController(), ALL_APPS_PROGRESS, allAppsProgressOffscreen));
|
||||
|
||||
ObjectAnimator dragHandleAnim = ObjectAnimator.ofInt(
|
||||
mActivity.getScrimView(), ScrimView.DRAG_HANDLE_ALPHA, 0);
|
||||
dragHandleAnim.setInterpolator(Interpolators.ACCEL_2);
|
||||
anim.play(dragHandleAnim);
|
||||
|
||||
return anim;
|
||||
}
|
||||
|
||||
|
|
|
@ -87,20 +87,6 @@ public class QuickstepOnboardingPrefs extends OnboardingPrefs<BaseQuickstepLaunc
|
|||
});
|
||||
}
|
||||
|
||||
if (!hasReachedMaxCount(ALL_APPS_COUNT)) {
|
||||
stateManager.addStateListener(new StateListener<LauncherState>() {
|
||||
@Override
|
||||
public void onStateTransitionComplete(LauncherState finalState) {
|
||||
if (finalState == ALL_APPS) {
|
||||
if (incrementEventCount(ALL_APPS_COUNT)) {
|
||||
stateManager.removeStateListener(this);
|
||||
mLauncher.getScrimView().updateDragHandleVisibility();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (FeatureFlags.ENABLE_HYBRID_HOTSEAT.get() && !hasReachedMaxCount(
|
||||
HOTSEAT_DISCOVERY_TIP_COUNT)) {
|
||||
stateManager.addStateListener(new StateListener<LauncherState>() {
|
||||
|
|
|
@ -44,7 +44,6 @@ import com.android.launcher3.Utilities;
|
|||
import com.android.launcher3.anim.Interpolators;
|
||||
import com.android.launcher3.config.FeatureFlags;
|
||||
import com.android.launcher3.uioverrides.states.OverviewState;
|
||||
import com.android.launcher3.util.OnboardingPrefs;
|
||||
import com.android.launcher3.util.Themes;
|
||||
import com.android.launcher3.views.ScrimView;
|
||||
import com.android.quickstep.SysUINavigationMode;
|
||||
|
@ -77,15 +76,11 @@ public class ShelfScrimView extends ScrimView<BaseQuickstepLauncher>
|
|||
private final float mRadius;
|
||||
private final int mMaxScrimAlpha;
|
||||
private final Paint mPaint;
|
||||
private final OnboardingPrefs mOnboardingPrefs;
|
||||
|
||||
// Mid point where the alpha changes
|
||||
private int mMidAlpha;
|
||||
private float mMidProgress;
|
||||
|
||||
// The progress at which the drag handle starts moving up with the shelf.
|
||||
private float mDragHandleProgress;
|
||||
|
||||
private Interpolator mBeforeMidProgressColorInterpolator = ACCEL;
|
||||
private Interpolator mAfterMidProgressColorInterpolator = ACCEL;
|
||||
|
||||
|
@ -103,7 +98,6 @@ public class ShelfScrimView extends ScrimView<BaseQuickstepLauncher>
|
|||
private boolean mRemainingScreenPathValid = false;
|
||||
|
||||
private Mode mSysUINavigationMode;
|
||||
private boolean mIsTwoZoneSwipeModel;
|
||||
|
||||
public ShelfScrimView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
|
@ -112,7 +106,6 @@ public class ShelfScrimView extends ScrimView<BaseQuickstepLauncher>
|
|||
mEndAlpha = Color.alpha(mEndScrim);
|
||||
mRadius = BOTTOM_CORNER_RADIUS_RATIO * Themes.getDialogCornerRadius(context);
|
||||
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
mOnboardingPrefs = mLauncher.getOnboardingPrefs();
|
||||
|
||||
// Just assume the easiest UI for now, until we have the proper layout information.
|
||||
mDrawingFlatColor = true;
|
||||
|
@ -145,11 +138,9 @@ public class ShelfScrimView extends ScrimView<BaseQuickstepLauncher>
|
|||
// Show the shelf more quickly before reaching overview progress.
|
||||
mBeforeMidProgressColorInterpolator = ACCEL_2;
|
||||
mAfterMidProgressColorInterpolator = ACCEL;
|
||||
mIsTwoZoneSwipeModel = FeatureFlags.ENABLE_OVERVIEW_ACTIONS.get();
|
||||
} else {
|
||||
mBeforeMidProgressColorInterpolator = ACCEL;
|
||||
mAfterMidProgressColorInterpolator = Interpolators.clampToProgress(ACCEL, 0.5f, 1f);
|
||||
mIsTwoZoneSwipeModel = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -164,7 +155,6 @@ public class ShelfScrimView extends ScrimView<BaseQuickstepLauncher>
|
|||
|
||||
Context context = getContext();
|
||||
if ((OVERVIEW.getVisibleElements(mLauncher) & ALL_APPS_HEADER_EXTRA) == 0) {
|
||||
mDragHandleProgress = 1;
|
||||
if (FeatureFlags.ENABLE_OVERVIEW_ACTIONS.get()
|
||||
&& SysUINavigationMode.removeShelfFromOverview(context)) {
|
||||
// Fade in all apps background quickly to distinguish from swiping from nav bar.
|
||||
|
@ -182,29 +172,22 @@ public class ShelfScrimView extends ScrimView<BaseQuickstepLauncher>
|
|||
+ hotseatPadding.bottom + hotseatPadding.top;
|
||||
float dragHandleTop =
|
||||
Math.min(hotseatSize, LayoutUtils.getDefaultSwipeHeight(context, dp));
|
||||
mDragHandleProgress = 1 - (dragHandleTop / mShiftRange);
|
||||
}
|
||||
mTopOffset = dp.getInsets().top - mDragHandleSize.y;
|
||||
mTopOffset = dp.getInsets().top;
|
||||
mShelfTopAtThreshold = mShiftRange * SCRIM_CATCHUP_THRESHOLD + mTopOffset;
|
||||
}
|
||||
updateColors();
|
||||
updateSysUiColors();
|
||||
updateDragHandleAlpha();
|
||||
invalidate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateColors() {
|
||||
super.updateColors();
|
||||
mDragHandleOffset = 0;
|
||||
if (mDrawingFlatColor) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (mProgress < mDragHandleProgress) {
|
||||
mDragHandleOffset = mShiftRange * (mDragHandleProgress - mProgress);
|
||||
}
|
||||
|
||||
if (mProgress >= SCRIM_CATCHUP_THRESHOLD) {
|
||||
mShelfTop = mShiftRange * mProgress + mTopOffset;
|
||||
} else {
|
||||
|
@ -258,20 +241,8 @@ public class ShelfScrimView extends ScrimView<BaseQuickstepLauncher>
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean shouldDragHandleBeVisible() {
|
||||
boolean needsAllAppsEdu = mIsTwoZoneSwipeModel
|
||||
&& !mOnboardingPrefs.hasReachedMaxCount(OnboardingPrefs.ALL_APPS_COUNT);
|
||||
return needsAllAppsEdu || super.shouldDragHandleBeVisible();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDraw(Canvas canvas) {
|
||||
drawBackground(canvas);
|
||||
drawDragHandle(canvas);
|
||||
}
|
||||
|
||||
private void drawBackground(Canvas canvas) {
|
||||
if (mDrawingFlatColor) {
|
||||
if (mCurrentFlatColor != 0) {
|
||||
canvas.drawColor(mCurrentFlatColor);
|
||||
|
@ -311,9 +282,4 @@ public class ShelfScrimView extends ScrimView<BaseQuickstepLauncher>
|
|||
mPaint.setColor(mShelfColor);
|
||||
canvas.drawRoundRect(0, mShelfTop, width, height + mRadius, mRadius, mRadius, mPaint);
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getVisualTop() {
|
||||
return mShelfTop;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,19 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2020 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.
|
||||
-->
|
||||
<com.android.launcher3.graphics.ShadowDrawable
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:src="@drawable/drag_handle_indicator_no_shadow"
|
||||
android:elevation="@dimen/vertical_drag_handle_elevation" />
|
|
@ -1,29 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2020 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="@dimen/vertical_drag_handle_width"
|
||||
android:height="@dimen/vertical_drag_handle_height"
|
||||
android:viewportWidth="18.0"
|
||||
android:viewportHeight="6.0"
|
||||
android:tint="?attr/workspaceTextColor" >
|
||||
|
||||
<path
|
||||
android:pathData="M17,6c-0.15,0-0.3-0.03-0.45-0.11L9,2.12L1.45,5.89c-0.5,0.25-1.09,
|
||||
0.05-1.34-0.45S0.06,4.35,0.55,4.11l8-4c0.28-0.14,0.61-0.14,0.89,0l8,4c0.49,0.25,0.69,
|
||||
0.85,0.45,1.34C17.72,5.8,17.37,6,17,6z"
|
||||
android:fillColor="@android:color/white" />
|
||||
</vector>
|
|
@ -28,6 +28,12 @@
|
|||
android:clipToPadding="false"
|
||||
android:importantForAccessibility="no">
|
||||
|
||||
<com.android.launcher3.views.AccessibilityActionsView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:contentDescription="@string/home_screen"
|
||||
/>
|
||||
|
||||
<!-- The workspace contains 5 screens of cells -->
|
||||
<!-- DO NOT CHANGE THE ID -->
|
||||
<com.android.launcher3.Workspace
|
||||
|
|
|
@ -40,14 +40,6 @@
|
|||
<dimen name="workspace_page_indicator_line_height">1dp</dimen>
|
||||
<dimen name="workspace_page_indicator_overlap_workspace">0dp</dimen>
|
||||
|
||||
<!-- Hotseat/all-apps scrim -->
|
||||
<dimen name="all_apps_scrim_blur">4dp</dimen>
|
||||
<dimen name="vertical_drag_handle_width">18dp</dimen>
|
||||
<dimen name="vertical_drag_handle_height">6dp</dimen>
|
||||
<dimen name="vertical_drag_handle_elevation">1dp</dimen>
|
||||
<dimen name="vertical_drag_handle_touch_size">48dp</dimen>
|
||||
<dimen name="vertical_drag_handle_padding_in_vertical_bar_layout">16dp</dimen>
|
||||
|
||||
<!-- Drop target bar -->
|
||||
<dimen name="dynamic_grid_drop_target_size">48dp</dimen>
|
||||
<dimen name="drop_target_vertical_gap">20dp</dimen>
|
||||
|
|
|
@ -18,5 +18,4 @@
|
|||
<drawable name="ic_remove_shadow">@drawable/ic_remove_no_shadow</drawable>
|
||||
<drawable name="ic_uninstall_shadow">@drawable/ic_uninstall_no_shadow</drawable>
|
||||
<drawable name="ic_block_shadow">@drawable/ic_block_no_shadow</drawable>
|
||||
<drawable name="all_apps_arrow_shadow">@drawable/drag_handle_indicator_no_shadow</drawable>
|
||||
</resources>
|
|
@ -36,7 +36,7 @@
|
|||
<!-- Message shown when a shortcut is not available. It could have been temporarily disabled and may start working again after some time. -->
|
||||
<string name="shortcut_not_available">Shortcut isn\'t available</string>
|
||||
<!-- User visible name for the launcher/home screen. [CHAR_LIMIT=30] -->
|
||||
<string name="home_screen">Home screen</string>
|
||||
<string name="home_screen">Home</string>
|
||||
<!-- Label for showing custom action list of a shortcut or widget. [CHAR_LIMIT=30] -->
|
||||
<string name="custom_actions">Custom actions</string>
|
||||
|
||||
|
@ -88,10 +88,6 @@
|
|||
<string name="all_apps_button_personal_label">Personal apps list</string>
|
||||
<string name="all_apps_button_work_label">Work apps list</string>
|
||||
|
||||
<!-- Label for button in all applications label to go back home (to the workspace / desktop)
|
||||
for accessibilty (spoken when the button gets focus). -->
|
||||
<string name="all_apps_home_button_label">Home</string>
|
||||
|
||||
<!-- Label for remove drop target (from the homescreen only).
|
||||
May appear next to uninstall_drop_target_label [CHAR_LIMIT=20] -->
|
||||
<string name="remove_drop_target_label">Remove</string>
|
||||
|
|
|
@ -453,10 +453,10 @@ public class Launcher extends StatefulActivity<LauncherState> implements Launche
|
|||
mAppsView.getAlphaProperty(APPS_VIEW_ALPHA_CHANNEL_INDEX).setValue(alpha);
|
||||
} else if (finalState == OVERVIEW || finalState == OVERVIEW_PEEK) {
|
||||
mAppsView.getAlphaProperty(APPS_VIEW_ALPHA_CHANNEL_INDEX).setValue(alpha);
|
||||
mScrimView.getAlphaProperty(SCRIM_VIEW_ALPHA_CHANNEL_INDEX).setValue(alpha);
|
||||
mScrimView.setAlpha(alpha);
|
||||
} else {
|
||||
mAppsView.getAlphaProperty(APPS_VIEW_ALPHA_CHANNEL_INDEX).setValue(1f);
|
||||
mScrimView.getAlphaProperty(SCRIM_VIEW_ALPHA_CHANNEL_INDEX).setValue(1f);
|
||||
mScrimView.setAlpha(1f);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -553,7 +553,7 @@ public class Launcher extends StatefulActivity<LauncherState> implements Launche
|
|||
mAppsView.getAlphaProperty(APPS_VIEW_ALPHA_CHANNEL_INDEX).setValue(alpha);
|
||||
} else if (state == OVERVIEW || state == OVERVIEW_PEEK) {
|
||||
mAppsView.getAlphaProperty(APPS_VIEW_ALPHA_CHANNEL_INDEX).setValue(alpha);
|
||||
mScrimView.getAlphaProperty(SCRIM_VIEW_ALPHA_CHANNEL_INDEX).setValue(alpha);
|
||||
mScrimView.setAlpha(alpha);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1936,7 +1936,7 @@ public class Launcher extends StatefulActivity<LauncherState> implements Launche
|
|||
// Populate event with a fake title based on the current state.
|
||||
// TODO: When can workspace be null?
|
||||
text.add(mWorkspace == null
|
||||
? getString(R.string.all_apps_home_button_label)
|
||||
? getString(R.string.home_screen)
|
||||
: mStateManager.getState().getDescription(this));
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -3263,7 +3263,7 @@ public class Workspace extends PagedView<WorkspacePageIndicator>
|
|||
}
|
||||
if (nScreens == 0) {
|
||||
// When the workspace is not loaded, we do not know how many screen will be bound.
|
||||
return getContext().getString(R.string.all_apps_home_button_label);
|
||||
return getContext().getString(R.string.home_screen);
|
||||
}
|
||||
return getContext().getString(R.string.workspace_scroll_format, page + 1, nScreens);
|
||||
}
|
||||
|
|
|
@ -19,7 +19,6 @@ import static com.android.launcher3.LauncherState.ALL_APPS_CONTENT;
|
|||
import static com.android.launcher3.LauncherState.ALL_APPS_HEADER_EXTRA;
|
||||
import static com.android.launcher3.LauncherState.APPS_VIEW_ITEM_MASK;
|
||||
import static com.android.launcher3.LauncherState.OVERVIEW;
|
||||
import static com.android.launcher3.LauncherState.VERTICAL_SWIPE_INDICATOR;
|
||||
import static com.android.launcher3.anim.Interpolators.FAST_OUT_SLOW_IN;
|
||||
import static com.android.launcher3.anim.Interpolators.FINAL_FRAME;
|
||||
import static com.android.launcher3.anim.Interpolators.INSTANT;
|
||||
|
@ -222,9 +221,6 @@ public class AllAppsTransitionController implements StateHandler<LauncherState>,
|
|||
|
||||
mAppsView.getSearchUiManager().setContentVisibility(visibleElements, setter, allAppsFade);
|
||||
|
||||
setter.setInt(mScrimView, ScrimView.DRAG_HANDLE_ALPHA,
|
||||
(visibleElements & VERTICAL_SWIPE_INDICATOR) != 0 ? 255 : 0, allAppsFade);
|
||||
|
||||
// Set visibility of the container at the very beginning or end of the transition.
|
||||
setter.setViewAlpha(mAppsView, hasAnyVisibleItem ? 1 : 0,
|
||||
hasAnyVisibleItem ? INSTANT : FINAL_FRAME);
|
||||
|
|
|
@ -36,7 +36,6 @@ public class OnboardingPrefs<T extends Launcher> {
|
|||
public static final String SHELF_BOUNCE_SEEN = "launcher.shelf_bounce_seen";
|
||||
public static final String HOME_BOUNCE_COUNT = "launcher.home_bounce_count";
|
||||
public static final String SHELF_BOUNCE_COUNT = "launcher.shelf_bounce_count";
|
||||
public static final String ALL_APPS_COUNT = "launcher.all_apps_count";
|
||||
public static final String HOTSEAT_DISCOVERY_TIP_COUNT = "launcher.hotseat_discovery_tip_count";
|
||||
public static final String HOTSEAT_LONGPRESS_TIP_SEEN = "launcher.hotseat_longpress_tip_seen";
|
||||
|
||||
|
@ -56,7 +55,6 @@ public class OnboardingPrefs<T extends Launcher> {
|
|||
@StringDef(value = {
|
||||
HOME_BOUNCE_COUNT,
|
||||
SHELF_BOUNCE_COUNT,
|
||||
ALL_APPS_COUNT,
|
||||
HOTSEAT_DISCOVERY_TIP_COUNT
|
||||
})
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
|
@ -67,7 +65,6 @@ public class OnboardingPrefs<T extends Launcher> {
|
|||
Map<String, Integer> maxCounts = new ArrayMap<>(4);
|
||||
maxCounts.put(HOME_BOUNCE_COUNT, 3);
|
||||
maxCounts.put(SHELF_BOUNCE_COUNT, 3);
|
||||
maxCounts.put(ALL_APPS_COUNT, 5);
|
||||
maxCounts.put(HOTSEAT_DISCOVERY_TIP_COUNT, 5);
|
||||
MAX_COUNTS = Collections.unmodifiableMap(maxCounts);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,97 @@
|
|||
/*
|
||||
* Copyright (C) 2020 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.launcher3.views;
|
||||
|
||||
import static com.android.launcher3.LauncherState.ALL_APPS;
|
||||
import static com.android.launcher3.LauncherState.NORMAL;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
import android.view.accessibility.AccessibilityNodeInfo;
|
||||
import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.android.launcher3.Launcher;
|
||||
import com.android.launcher3.LauncherState;
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.statemanager.StateManager.StateListener;
|
||||
import com.android.launcher3.views.OptionsPopupView.OptionItem;
|
||||
|
||||
/**
|
||||
* Placeholder view to expose additional Launcher actions via accessibility actions
|
||||
*/
|
||||
public class AccessibilityActionsView extends View implements StateListener<LauncherState> {
|
||||
|
||||
public AccessibilityActionsView(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public AccessibilityActionsView(Context context, @Nullable AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
|
||||
public AccessibilityActionsView(Context context, @Nullable AttributeSet attrs,
|
||||
int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
Launcher.getLauncher(context).getStateManager().addStateListener(this);
|
||||
setWillNotDraw(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStateTransitionComplete(LauncherState finalState) {
|
||||
setImportantForAccessibility(finalState == NORMAL
|
||||
? IMPORTANT_FOR_ACCESSIBILITY_YES : IMPORTANT_FOR_ACCESSIBILITY_NO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AccessibilityNodeInfo createAccessibilityNodeInfo() {
|
||||
AccessibilityNodeInfo info = super.createAccessibilityNodeInfo();
|
||||
Launcher l = Launcher.getLauncher(getContext());
|
||||
info.addAction(new AccessibilityAction(
|
||||
R.string.all_apps_button_label, l.getText(R.string.all_apps_button_label)));
|
||||
for (OptionItem item : OptionsPopupView.getOptions(l)) {
|
||||
info.addAction(new AccessibilityAction(item.labelRes, l.getText(item.labelRes)));
|
||||
}
|
||||
return info;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean performAccessibilityAction(int action, Bundle arguments) {
|
||||
if (super.performAccessibilityAction(action, arguments)) {
|
||||
return true;
|
||||
}
|
||||
Launcher l = Launcher.getLauncher(getContext());
|
||||
if (action == R.string.all_apps_button_label) {
|
||||
l.getStateManager().goToState(ALL_APPS);
|
||||
return true;
|
||||
}
|
||||
for (OptionItem item : OptionsPopupView.getOptions(l)) {
|
||||
if (item.labelRes == action) {
|
||||
if (item.eventId.getId() > 0) {
|
||||
l.getStatsLogManager().logger().log(item.eventId);
|
||||
}
|
||||
if (item.clickListener.onLongClick(this)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -85,10 +85,10 @@ public class OptionsPopupView extends ArrowPopup
|
|||
if (item == null) {
|
||||
return false;
|
||||
}
|
||||
if (item.mEventId.getId() > 0) {
|
||||
mLauncher.getStatsLogManager().logger().log(item.mEventId);
|
||||
if (item.eventId.getId() > 0) {
|
||||
mLauncher.getStatsLogManager().logger().log(item.eventId);
|
||||
}
|
||||
if (item.mClickListener.onLongClick(view)) {
|
||||
if (item.clickListener.onLongClick(view)) {
|
||||
close(true);
|
||||
return true;
|
||||
}
|
||||
|
@ -130,8 +130,8 @@ public class OptionsPopupView extends ArrowPopup
|
|||
for (OptionItem item : items) {
|
||||
DeepShortcutView view =
|
||||
(DeepShortcutView) popup.inflateAndAdd(R.layout.system_shortcut, popup);
|
||||
view.getIconView().setBackgroundResource(item.mIconRes);
|
||||
view.getBubbleText().setText(item.mLabelRes);
|
||||
view.getIconView().setBackgroundResource(item.iconRes);
|
||||
view.getBubbleText().setText(item.labelRes);
|
||||
view.setDividerVisibility(View.INVISIBLE);
|
||||
view.setOnClickListener(popup);
|
||||
view.setOnLongClickListener(popup);
|
||||
|
@ -152,7 +152,13 @@ public class OptionsPopupView extends ArrowPopup
|
|||
y = launcher.getDragLayer().getHeight() / 2;
|
||||
}
|
||||
RectF target = new RectF(x - halfSize, y - halfSize, x + halfSize, y + halfSize);
|
||||
show(launcher, target, getOptions(launcher));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of supported actions
|
||||
*/
|
||||
public static ArrayList<OptionItem> getOptions(Launcher launcher) {
|
||||
ArrayList<OptionItem> options = new ArrayList<>();
|
||||
int resString = Utilities.existsStyleWallpapers(launcher) ?
|
||||
R.string.styles_wallpaper_button_text : R.string.wallpaper_button_text;
|
||||
|
@ -170,10 +176,10 @@ public class OptionsPopupView extends ArrowPopup
|
|||
LAUNCHER_SETTINGS_BUTTON_TAP_OR_LONGPRESS,
|
||||
OptionsPopupView::startSettings));
|
||||
|
||||
show(launcher, target, options);
|
||||
return options;
|
||||
}
|
||||
|
||||
public static boolean onWidgetsClicked(View view) {
|
||||
private static boolean onWidgetsClicked(View view) {
|
||||
return openWidgets(Launcher.getLauncher(view.getContext())) != null;
|
||||
}
|
||||
|
||||
|
@ -188,7 +194,7 @@ public class OptionsPopupView extends ArrowPopup
|
|||
}
|
||||
}
|
||||
|
||||
public static boolean startSettings(View view) {
|
||||
private static boolean startSettings(View view) {
|
||||
TestLogging.recordEvent(TestProtocol.SEQUENCE_MAIN, "start: startSettings");
|
||||
Launcher launcher = Launcher.getLauncher(view.getContext());
|
||||
launcher.startActivity(new Intent(Intent.ACTION_APPLICATION_PREFERENCES)
|
||||
|
@ -201,7 +207,7 @@ public class OptionsPopupView extends ArrowPopup
|
|||
* Event handler for the wallpaper picker button that appears after a long press
|
||||
* on the home screen.
|
||||
*/
|
||||
public static boolean startWallpaperPicker(View v) {
|
||||
private static boolean startWallpaperPicker(View v) {
|
||||
Launcher launcher = Launcher.getLauncher(v.getContext());
|
||||
if (!Utilities.isWallpaperAllowed(launcher)) {
|
||||
Toast.makeText(launcher, R.string.msg_disabled_by_admin, Toast.LENGTH_SHORT).show();
|
||||
|
@ -233,17 +239,17 @@ public class OptionsPopupView extends ArrowPopup
|
|||
|
||||
public static class OptionItem {
|
||||
|
||||
private final int mLabelRes;
|
||||
private final int mIconRes;
|
||||
private final EventEnum mEventId;
|
||||
private final OnLongClickListener mClickListener;
|
||||
public final int labelRes;
|
||||
public final int iconRes;
|
||||
public final EventEnum eventId;
|
||||
public final OnLongClickListener clickListener;
|
||||
|
||||
public OptionItem(int labelRes, int iconRes, EventEnum eventId,
|
||||
OnLongClickListener clickListener) {
|
||||
mLabelRes = labelRes;
|
||||
mIconRes = iconRes;
|
||||
mEventId = eventId;
|
||||
mClickListener = clickListener;
|
||||
this.labelRes = labelRes;
|
||||
this.iconRes = iconRes;
|
||||
this.eventId = eventId;
|
||||
this.clickListener = clickListener;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,119 +15,37 @@
|
|||
*/
|
||||
package com.android.launcher3.views;
|
||||
|
||||
import static android.content.Context.ACCESSIBILITY_SERVICE;
|
||||
import static android.view.MotionEvent.ACTION_DOWN;
|
||||
|
||||
import static androidx.core.graphics.ColorUtils.compositeColors;
|
||||
|
||||
import static com.android.launcher3.LauncherState.ALL_APPS;
|
||||
import static com.android.launcher3.LauncherState.NORMAL;
|
||||
import static com.android.launcher3.anim.Interpolators.ACCEL_DEACCEL;
|
||||
import static com.android.launcher3.anim.Interpolators.DEACCEL;
|
||||
import static com.android.launcher3.anim.Interpolators.LINEAR;
|
||||
import static com.android.launcher3.anim.Interpolators.clampToProgress;
|
||||
import static com.android.launcher3.icons.GraphicsUtils.setColorAlphaBound;
|
||||
import static com.android.launcher3.util.SystemUiController.UI_STATE_SCRIM_VIEW;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorListenerAdapter;
|
||||
import android.animation.Keyframe;
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.animation.PropertyValuesHolder;
|
||||
import android.animation.RectEvaluator;
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Point;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.RectF;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Bundle;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.IntProperty;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.accessibility.AccessibilityManager;
|
||||
import android.view.accessibility.AccessibilityManager.AccessibilityStateChangeListener;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.core.graphics.ColorUtils;
|
||||
import androidx.core.view.ViewCompat;
|
||||
import androidx.core.view.accessibility.AccessibilityNodeInfoCompat;
|
||||
import androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat;
|
||||
import androidx.customview.widget.ExploreByTouchHelper;
|
||||
|
||||
import com.android.launcher3.DeviceProfile;
|
||||
import com.android.launcher3.Insettable;
|
||||
import com.android.launcher3.Launcher;
|
||||
import com.android.launcher3.LauncherState;
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.Utilities;
|
||||
import com.android.launcher3.statemanager.StateManager;
|
||||
import com.android.launcher3.statemanager.StateManager.StateListener;
|
||||
import com.android.launcher3.uioverrides.WallpaperColorInfo;
|
||||
import com.android.launcher3.uioverrides.WallpaperColorInfo.OnChangeListener;
|
||||
import com.android.launcher3.userevent.nano.LauncherLogProto.Action;
|
||||
import com.android.launcher3.userevent.nano.LauncherLogProto.ControlType;
|
||||
import com.android.launcher3.util.MultiValueAlpha;
|
||||
import com.android.launcher3.util.MultiValueAlpha.AlphaProperty;
|
||||
import com.android.launcher3.util.Themes;
|
||||
import com.android.launcher3.widget.WidgetsFullSheet;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Simple scrim which draws a flat color
|
||||
*/
|
||||
public class ScrimView<T extends Launcher> extends View implements Insettable, OnChangeListener,
|
||||
AccessibilityStateChangeListener {
|
||||
|
||||
public static final IntProperty<ScrimView> DRAG_HANDLE_ALPHA =
|
||||
new IntProperty<ScrimView>("dragHandleAlpha") {
|
||||
|
||||
@Override
|
||||
public Integer get(ScrimView scrimView) {
|
||||
return scrimView.mDragHandleAlpha;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setValue(ScrimView scrimView, int value) {
|
||||
scrimView.setDragHandleAlpha(value);
|
||||
}
|
||||
};
|
||||
private static final int WALLPAPERS = R.string.wallpaper_button_text;
|
||||
private static final int WIDGETS = R.string.widget_button_text;
|
||||
private static final int SETTINGS = R.string.settings_button_text;
|
||||
private static final int ALPHA_CHANNEL_COUNT = 1;
|
||||
|
||||
private static final long DRAG_HANDLE_BOUNCE_DURATION_MS = 300;
|
||||
// How much to delay before repeating the bounce.
|
||||
private static final long DRAG_HANDLE_BOUNCE_DELAY_MS = 200;
|
||||
// Repeat this many times (i.e. total number of bounces is 1 + this).
|
||||
private static final int DRAG_HANDLE_BOUNCE_REPEAT_COUNT = 2;
|
||||
|
||||
private final Rect mTempRect = new Rect();
|
||||
private final int[] mTempPos = new int[2];
|
||||
public class ScrimView<T extends Launcher> extends View implements Insettable, OnChangeListener {
|
||||
|
||||
protected final T mLauncher;
|
||||
private final WallpaperColorInfo mWallpaperColorInfo;
|
||||
private final AccessibilityManager mAM;
|
||||
protected final int mEndScrim;
|
||||
protected final boolean mIsScrimDark;
|
||||
|
||||
private final StateListener<LauncherState> mAccessibilityLauncherStateListener =
|
||||
new StateListener<LauncherState>() {
|
||||
@Override
|
||||
public void onStateTransitionComplete(LauncherState finalState) {
|
||||
setImportantForAccessibility(finalState == ALL_APPS
|
||||
? IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS
|
||||
: IMPORTANT_FOR_ACCESSIBILITY_AUTO);
|
||||
}
|
||||
};
|
||||
|
||||
protected float mMaxScrimAlpha;
|
||||
|
||||
protected float mProgress = 1;
|
||||
|
@ -137,22 +55,6 @@ public class ScrimView<T extends Launcher> extends View implements Insettable, O
|
|||
protected int mEndFlatColor;
|
||||
protected int mEndFlatColorAlpha;
|
||||
|
||||
protected final Point mDragHandleSize;
|
||||
private final int mDragHandleTouchSize;
|
||||
private final int mDragHandlePaddingInVerticalBarLayout;
|
||||
protected float mDragHandleOffset;
|
||||
private final Rect mDragHandleBounds;
|
||||
private final RectF mHitRect = new RectF();
|
||||
private ObjectAnimator mDragHandleAnim;
|
||||
|
||||
private final MultiValueAlpha mMultiValueAlpha;
|
||||
|
||||
private final AccessibilityHelper mAccessibilityHelper;
|
||||
@Nullable
|
||||
protected Drawable mDragHandle;
|
||||
|
||||
private int mDragHandleAlpha = 255;
|
||||
|
||||
public ScrimView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
mLauncher = Launcher.cast(Launcher.getLauncher(context));
|
||||
|
@ -161,59 +63,24 @@ public class ScrimView<T extends Launcher> extends View implements Insettable, O
|
|||
mIsScrimDark = ColorUtils.calculateLuminance(mEndScrim) < 0.5f;
|
||||
|
||||
mMaxScrimAlpha = 0.7f;
|
||||
|
||||
Resources res = context.getResources();
|
||||
mDragHandleSize = new Point(res.getDimensionPixelSize(R.dimen.vertical_drag_handle_width),
|
||||
res.getDimensionPixelSize(R.dimen.vertical_drag_handle_height));
|
||||
mDragHandleBounds = new Rect(0, 0, mDragHandleSize.x, mDragHandleSize.y);
|
||||
mDragHandleTouchSize = res.getDimensionPixelSize(R.dimen.vertical_drag_handle_touch_size);
|
||||
mDragHandlePaddingInVerticalBarLayout = context.getResources()
|
||||
.getDimensionPixelSize(R.dimen.vertical_drag_handle_padding_in_vertical_bar_layout);
|
||||
|
||||
mAccessibilityHelper = createAccessibilityHelper();
|
||||
ViewCompat.setAccessibilityDelegate(this, mAccessibilityHelper);
|
||||
|
||||
mAM = (AccessibilityManager) context.getSystemService(ACCESSIBILITY_SERVICE);
|
||||
setFocusable(false);
|
||||
mMultiValueAlpha = new MultiValueAlpha(this, ALPHA_CHANNEL_COUNT);
|
||||
}
|
||||
|
||||
public AlphaProperty getAlphaProperty(int index) {
|
||||
return mMultiValueAlpha.getProperty(index);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
protected AccessibilityHelper createAccessibilityHelper() {
|
||||
return new AccessibilityHelper();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setInsets(Rect insets) {
|
||||
updateDragHandleBounds();
|
||||
updateDragHandleVisibility();
|
||||
}
|
||||
public void setInsets(Rect insets) { }
|
||||
|
||||
@Override
|
||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
||||
updateDragHandleBounds();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onAttachedToWindow() {
|
||||
super.onAttachedToWindow();
|
||||
mWallpaperColorInfo.addOnChangeListener(this);
|
||||
onExtractedColorsChanged(mWallpaperColorInfo);
|
||||
|
||||
mAM.addAccessibilityStateChangeListener(this);
|
||||
onAccessibilityStateChanged(mAM.isEnabled());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDetachedFromWindow() {
|
||||
super.onDetachedFromWindow();
|
||||
mWallpaperColorInfo.removeOnChangeListener(this);
|
||||
mAM.removeAccessibilityStateChangeListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -234,10 +101,8 @@ public class ScrimView<T extends Launcher> extends View implements Insettable, O
|
|||
public void setProgress(float progress) {
|
||||
if (mProgress != progress) {
|
||||
mProgress = progress;
|
||||
stopDragHandleEducationAnim();
|
||||
updateColors();
|
||||
updateSysUiColors();
|
||||
updateDragHandleAlpha();
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
|
@ -260,286 +125,10 @@ public class ScrimView<T extends Launcher> extends View implements Insettable, O
|
|||
}
|
||||
}
|
||||
|
||||
protected void updateDragHandleAlpha() {
|
||||
if (mDragHandle != null) {
|
||||
mDragHandle.setAlpha(mDragHandleAlpha);
|
||||
}
|
||||
}
|
||||
|
||||
private void setDragHandleAlpha(int alpha) {
|
||||
if (alpha != mDragHandleAlpha) {
|
||||
mDragHandleAlpha = alpha;
|
||||
if (mDragHandle != null) {
|
||||
mDragHandle.setAlpha(mDragHandleAlpha);
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDraw(Canvas canvas) {
|
||||
if (mCurrentFlatColor != 0) {
|
||||
canvas.drawColor(mCurrentFlatColor);
|
||||
}
|
||||
drawDragHandle(canvas);
|
||||
}
|
||||
|
||||
protected void drawDragHandle(Canvas canvas) {
|
||||
if (mDragHandle != null) {
|
||||
canvas.translate(0, -mDragHandleOffset);
|
||||
mDragHandle.draw(canvas);
|
||||
canvas.translate(0, mDragHandleOffset);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTouchEvent(MotionEvent event) {
|
||||
boolean superHandledTouch = super.onTouchEvent(event);
|
||||
if (event.getAction() == ACTION_DOWN) {
|
||||
if (!superHandledTouch && mHitRect.contains(event.getX(), event.getY())) {
|
||||
if (startDragHandleEducationAnim()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
stopDragHandleEducationAnim();
|
||||
}
|
||||
return superHandledTouch;
|
||||
}
|
||||
|
||||
/**
|
||||
* Animates the drag handle to demonstrate how to get to all apps.
|
||||
* @return Whether the animation was started (false if drag handle is invisible).
|
||||
*/
|
||||
public boolean startDragHandleEducationAnim() {
|
||||
stopDragHandleEducationAnim();
|
||||
|
||||
if (mDragHandle == null || mDragHandle.getAlpha() != 255) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final Drawable drawable = mDragHandle;
|
||||
mDragHandle = null;
|
||||
|
||||
Rect bounds = new Rect(mDragHandleBounds);
|
||||
bounds.offset(0, -(int) mDragHandleOffset);
|
||||
drawable.setBounds(bounds);
|
||||
|
||||
Rect topBounds = new Rect(bounds);
|
||||
topBounds.offset(0, -bounds.height());
|
||||
|
||||
Rect invalidateRegion = new Rect(bounds);
|
||||
invalidateRegion.top = topBounds.top;
|
||||
|
||||
final float progressToReachTop = 0.6f;
|
||||
Keyframe frameTop = Keyframe.ofObject(progressToReachTop, topBounds);
|
||||
frameTop.setInterpolator(DEACCEL);
|
||||
Keyframe frameBot = Keyframe.ofObject(1, bounds);
|
||||
frameBot.setInterpolator(ACCEL_DEACCEL);
|
||||
PropertyValuesHolder holder = PropertyValuesHolder.ofKeyframe("bounds",
|
||||
Keyframe.ofObject(0, bounds), frameTop, frameBot);
|
||||
holder.setEvaluator(new RectEvaluator());
|
||||
|
||||
mDragHandleAnim = ObjectAnimator.ofPropertyValuesHolder(drawable, holder);
|
||||
long totalBounceDuration = DRAG_HANDLE_BOUNCE_DURATION_MS + DRAG_HANDLE_BOUNCE_DELAY_MS;
|
||||
// The bounce finishes by this progress, the rest of the duration just delays next bounce.
|
||||
float delayStartProgress = 1f - (float) DRAG_HANDLE_BOUNCE_DELAY_MS / totalBounceDuration;
|
||||
mDragHandleAnim.addUpdateListener((v) -> invalidate(invalidateRegion));
|
||||
mDragHandleAnim.setDuration(totalBounceDuration);
|
||||
mDragHandleAnim.setInterpolator(clampToProgress(LINEAR, 0, delayStartProgress));
|
||||
mDragHandleAnim.setRepeatCount(DRAG_HANDLE_BOUNCE_REPEAT_COUNT);
|
||||
getOverlay().add(drawable);
|
||||
|
||||
mDragHandleAnim.addListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
mDragHandleAnim = null;
|
||||
getOverlay().remove(drawable);
|
||||
updateDragHandleVisibility(drawable);
|
||||
}
|
||||
});
|
||||
mDragHandleAnim.start();
|
||||
return true;
|
||||
}
|
||||
|
||||
private void stopDragHandleEducationAnim() {
|
||||
if (mDragHandleAnim != null) {
|
||||
mDragHandleAnim.end();
|
||||
}
|
||||
}
|
||||
|
||||
protected void updateDragHandleBounds() {
|
||||
DeviceProfile grid = mLauncher.getDeviceProfile();
|
||||
final int left;
|
||||
final int width = getMeasuredWidth();
|
||||
final int top = getMeasuredHeight() - mDragHandleSize.y - grid.getInsets().bottom;
|
||||
final int topMargin;
|
||||
|
||||
if (grid.isVerticalBarLayout()) {
|
||||
topMargin = grid.workspacePadding.bottom + mDragHandlePaddingInVerticalBarLayout;
|
||||
if (grid.isSeascape()) {
|
||||
left = width - grid.getInsets().right - mDragHandleSize.x
|
||||
- mDragHandlePaddingInVerticalBarLayout;
|
||||
} else {
|
||||
left = grid.getInsets().left + mDragHandlePaddingInVerticalBarLayout;
|
||||
}
|
||||
} else {
|
||||
left = Math.round((width - mDragHandleSize.x) / 2f);
|
||||
topMargin = grid.hotseatBarSizePx;
|
||||
}
|
||||
mDragHandleBounds.offsetTo(left, top - topMargin);
|
||||
mHitRect.set(mDragHandleBounds);
|
||||
// Inset outwards to increase touch size.
|
||||
mHitRect.inset((mDragHandleSize.x - mDragHandleTouchSize) / 2f,
|
||||
(mDragHandleSize.y - mDragHandleTouchSize) / 2f);
|
||||
|
||||
if (mDragHandle != null) {
|
||||
mDragHandle.setBounds(mDragHandleBounds);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAccessibilityStateChanged(boolean enabled) {
|
||||
StateManager<LauncherState> stateManager = mLauncher.getStateManager();
|
||||
stateManager.removeStateListener(mAccessibilityLauncherStateListener);
|
||||
|
||||
if (enabled) {
|
||||
stateManager.addStateListener(mAccessibilityLauncherStateListener);
|
||||
mAccessibilityLauncherStateListener.onStateTransitionComplete(stateManager.getState());
|
||||
} else {
|
||||
setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS);
|
||||
}
|
||||
updateDragHandleVisibility();
|
||||
}
|
||||
|
||||
public void updateDragHandleVisibility() {
|
||||
updateDragHandleVisibility(null);
|
||||
}
|
||||
|
||||
private void updateDragHandleVisibility(@Nullable Drawable recycle) {
|
||||
boolean visible = shouldDragHandleBeVisible();
|
||||
boolean wasVisible = mDragHandle != null;
|
||||
if (visible != wasVisible) {
|
||||
if (visible) {
|
||||
mDragHandle = recycle != null ? recycle :
|
||||
mLauncher.getDrawable(R.drawable.drag_handle_indicator_shadow);
|
||||
mDragHandle.setBounds(mDragHandleBounds);
|
||||
|
||||
updateDragHandleAlpha();
|
||||
} else {
|
||||
mDragHandle = null;
|
||||
}
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean shouldDragHandleBeVisible() {
|
||||
return mLauncher.getDeviceProfile().isVerticalBarLayout() || mAM.isEnabled();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean dispatchHoverEvent(MotionEvent event) {
|
||||
return mAccessibilityHelper.dispatchHoverEvent(event) || super.dispatchHoverEvent(event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean dispatchKeyEvent(KeyEvent event) {
|
||||
return mAccessibilityHelper.dispatchKeyEvent(event) || super.dispatchKeyEvent(event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFocusChanged(boolean gainFocus, int direction,
|
||||
Rect previouslyFocusedRect) {
|
||||
super.onFocusChanged(gainFocus, direction, previouslyFocusedRect);
|
||||
mAccessibilityHelper.onFocusChanged(gainFocus, direction, previouslyFocusedRect);
|
||||
}
|
||||
|
||||
protected class AccessibilityHelper extends ExploreByTouchHelper {
|
||||
|
||||
private static final int DRAG_HANDLE_ID = 1;
|
||||
|
||||
public AccessibilityHelper() {
|
||||
super(ScrimView.this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getVirtualViewAt(float x, float y) {
|
||||
return mHitRect.contains((int) x, (int) y)
|
||||
? DRAG_HANDLE_ID : INVALID_ID;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void getVisibleVirtualViews(List<Integer> virtualViewIds) {
|
||||
virtualViewIds.add(DRAG_HANDLE_ID);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPopulateNodeForVirtualView(int virtualViewId,
|
||||
AccessibilityNodeInfoCompat node) {
|
||||
node.setContentDescription(getContext().getString(R.string.all_apps_button_label));
|
||||
node.setBoundsInParent(mDragHandleBounds);
|
||||
|
||||
getLocationOnScreen(mTempPos);
|
||||
mTempRect.set(mDragHandleBounds);
|
||||
mTempRect.offset(mTempPos[0], mTempPos[1]);
|
||||
node.setBoundsInScreen(mTempRect);
|
||||
|
||||
node.addAction(AccessibilityNodeInfoCompat.ACTION_CLICK);
|
||||
node.setClickable(true);
|
||||
node.setFocusable(true);
|
||||
|
||||
if (mLauncher.isInState(NORMAL)) {
|
||||
Context context = getContext();
|
||||
if (Utilities.isWallpaperAllowed(context)) {
|
||||
node.addAction(
|
||||
new AccessibilityActionCompat(WALLPAPERS, context.getText(WALLPAPERS)));
|
||||
}
|
||||
node.addAction(new AccessibilityActionCompat(WIDGETS, context.getText(WIDGETS)));
|
||||
node.addAction(new AccessibilityActionCompat(SETTINGS, context.getText(SETTINGS)));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean onPerformActionForVirtualView(
|
||||
int virtualViewId, int action, Bundle arguments) {
|
||||
if (action == AccessibilityNodeInfoCompat.ACTION_CLICK) {
|
||||
mLauncher.getUserEventDispatcher().logActionOnControl(
|
||||
Action.Touch.TAP, ControlType.ALL_APPS_BUTTON,
|
||||
mLauncher.getStateManager().getState().containerType);
|
||||
mLauncher.getStateManager().goToState(ALL_APPS);
|
||||
return true;
|
||||
} else if (action == WALLPAPERS) {
|
||||
return OptionsPopupView.startWallpaperPicker(ScrimView.this);
|
||||
} else if (action == WIDGETS) {
|
||||
int originalImportanceForAccessibility = getImportantForAccessibility();
|
||||
setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS);
|
||||
WidgetsFullSheet widgetsFullSheet = OptionsPopupView.openWidgets(mLauncher);
|
||||
if (widgetsFullSheet == null) {
|
||||
setImportantForAccessibility(originalImportanceForAccessibility);
|
||||
return false;
|
||||
}
|
||||
widgetsFullSheet.addOnAttachStateChangeListener(new OnAttachStateChangeListener() {
|
||||
@Override
|
||||
public void onViewAttachedToWindow(View view) {}
|
||||
|
||||
@Override
|
||||
public void onViewDetachedFromWindow(View view) {
|
||||
setImportantForAccessibility(originalImportanceForAccessibility);
|
||||
widgetsFullSheet.removeOnAttachStateChangeListener(this);
|
||||
}
|
||||
});
|
||||
return true;
|
||||
} else if (action == SETTINGS) {
|
||||
return OptionsPopupView.startSettings(ScrimView.this);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The top of this scrim view, or {@link Float#MAX_VALUE} if there's no distinct top.
|
||||
*/
|
||||
public float getVisualTop() {
|
||||
return Float.MAX_VALUE;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue