1 /* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.launcher3; 18 19 import android.animation.TimeInterpolator; 20 import android.content.Context; 21 import android.util.AttributeSet; 22 import android.view.View; 23 import android.view.ViewDebug; 24 import android.view.ViewGroup; 25 import android.view.ViewPropertyAnimator; 26 import android.view.accessibility.AccessibilityManager; 27 import android.view.animation.AccelerateInterpolator; 28 import android.widget.LinearLayout; 29 30 import com.android.launcher3.dragndrop.DragController; 31 import com.android.launcher3.dragndrop.DragOptions; 32 33 /* 34 * The top bar containing various drop targets: Delete/App Info/Uninstall. 35 */ 36 public class DropTargetBar extends LinearLayout implements DragController.DragListener { 37 38 protected static final int DEFAULT_DRAG_FADE_DURATION = 175; 39 protected static final TimeInterpolator DEFAULT_INTERPOLATOR = new AccelerateInterpolator(); 40 41 private final Runnable mFadeAnimationEndRunnable = new Runnable() { 42 43 @Override 44 public void run() { 45 AccessibilityManager am = (AccessibilityManager) 46 getContext().getSystemService(Context.ACCESSIBILITY_SERVICE); 47 boolean accessibilityEnabled = am.isEnabled(); 48 AlphaUpdateListener.updateVisibility(DropTargetBar.this, accessibilityEnabled); 49 } 50 }; 51 52 @ViewDebug.ExportedProperty(category = "launcher") 53 protected boolean mDeferOnDragEnd; 54 55 @ViewDebug.ExportedProperty(category = "launcher") 56 protected boolean mVisible = false; 57 58 private ViewPropertyAnimator mCurrentAnimation; 59 60 public DropTargetBar(Context context, AttributeSet attrs) { 61 super(context, attrs); 62 } 63 64 public DropTargetBar(Context context, AttributeSet attrs, int defStyle) { 65 super(context, attrs, defStyle); 66 } 67 68 @Override 69 protected void onFinishInflate() { 70 super.onFinishInflate(); 71 72 // Initialize with hidden state 73 setAlpha(0f); 74 } 75 76 public void setup(DragController dragController) { 77 dragController.addDragListener(this); 78 setupButtonDropTarget(this, dragController); 79 } 80 81 private void setupButtonDropTarget(View view, DragController dragController) { 82 if (view instanceof ButtonDropTarget) { 83 ButtonDropTarget bdt = (ButtonDropTarget) view; 84 bdt.setDropTargetBar(this); 85 dragController.addDragListener(bdt); 86 dragController.addDropTarget(bdt); 87 } else if (view instanceof ViewGroup) { 88 ViewGroup vg = (ViewGroup) view; 89 for (int i = vg.getChildCount() - 1; i >= 0; i--) { 90 setupButtonDropTarget(vg.getChildAt(i), dragController); 91 } 92 } 93 } 94 95 private void animateToVisibility(boolean isVisible) { 96 if (mVisible != isVisible) { 97 mVisible = isVisible; 98 99 // Cancel any existing animation 100 if (mCurrentAnimation != null) { 101 mCurrentAnimation.cancel(); 102 mCurrentAnimation = null; 103 } 104 105 float finalAlpha = mVisible ? 1 : 0; 106 if (Float.compare(getAlpha(), finalAlpha) != 0) { 107 setVisibility(View.VISIBLE); 108 mCurrentAnimation = animate().alpha(finalAlpha) 109 .setInterpolator(DEFAULT_INTERPOLATOR) 110 .setDuration(DEFAULT_DRAG_FADE_DURATION) 111 .withEndAction(mFadeAnimationEndRunnable); 112 } 113 114 } 115 } 116 117 /* 118 * DragController.DragListener implementation 119 */ 120 @Override 121 public void onDragStart(DropTarget.DragObject dragObject, DragOptions options) { 122 animateToVisibility(true); 123 } 124 125 /** 126 * This is called to defer hiding the delete drop target until the drop animation has completed, 127 * instead of hiding immediately when the drag has ended. 128 */ 129 protected void deferOnDragEnd() { 130 mDeferOnDragEnd = true; 131 } 132 133 @Override 134 public void onDragEnd() { 135 if (!mDeferOnDragEnd) { 136 animateToVisibility(false); 137 } else { 138 mDeferOnDragEnd = false; 139 } 140 } 141 } 142