Home | History | Annotate | Download | only in launcher3
      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.Animator;
     20 import android.animation.AnimatorListenerAdapter;
     21 import android.animation.ObjectAnimator;
     22 import android.animation.ValueAnimator;
     23 import android.content.Context;
     24 import android.graphics.Rect;
     25 import android.util.AttributeSet;
     26 import android.view.View;
     27 import android.view.animation.AccelerateInterpolator;
     28 import android.widget.FrameLayout;
     29 
     30 /*
     31  * Ths bar will manage the transition between the QSB search bar and the delete drop
     32  * targets so that each of the individual IconDropTargets don't have to.
     33  */
     34 public class SearchDropTargetBar extends FrameLayout implements DragController.DragListener {
     35 
     36     private static final int TRANSITION_DURATION = 200;
     37 
     38     private ObjectAnimator mShowDropTargetBarAnim;
     39     private ValueAnimator mHideSearchBarAnim;
     40     private static final AccelerateInterpolator sAccelerateInterpolator =
     41             new AccelerateInterpolator();
     42 
     43     private boolean mIsSearchBarHidden;
     44     private View mQSBSearchBar;
     45     private View mDropTargetBar;
     46     private boolean mDeferOnDragEnd = false;
     47 
     48     // Drop targets
     49     private ButtonDropTarget mInfoDropTarget;
     50     private ButtonDropTarget mDeleteDropTarget;
     51     private ButtonDropTarget mUninstallDropTarget;
     52 
     53     public SearchDropTargetBar(Context context, AttributeSet attrs) {
     54         this(context, attrs, 0);
     55     }
     56 
     57     public SearchDropTargetBar(Context context, AttributeSet attrs, int defStyle) {
     58         super(context, attrs, defStyle);
     59     }
     60 
     61     public void setup(Launcher launcher, DragController dragController) {
     62         dragController.addDragListener(this);
     63         dragController.setFlingToDeleteDropTarget(mDeleteDropTarget);
     64 
     65         dragController.addDragListener(mInfoDropTarget);
     66         dragController.addDragListener(mDeleteDropTarget);
     67         dragController.addDragListener(mUninstallDropTarget);
     68 
     69         dragController.addDropTarget(mInfoDropTarget);
     70         dragController.addDropTarget(mDeleteDropTarget);
     71         dragController.addDropTarget(mUninstallDropTarget);
     72 
     73         mInfoDropTarget.setLauncher(launcher);
     74         mDeleteDropTarget.setLauncher(launcher);
     75         mUninstallDropTarget.setLauncher(launcher);
     76     }
     77 
     78     public void setQsbSearchBar(View qsb) {
     79         mQSBSearchBar = qsb;
     80         if (mQSBSearchBar != null) {
     81             mHideSearchBarAnim = LauncherAnimUtils.ofFloat(mQSBSearchBar, "alpha", 1f, 0f);
     82             setupAnimation(mHideSearchBarAnim, mQSBSearchBar);
     83         } else {
     84             // Create a no-op animation of the search bar is null
     85             mHideSearchBarAnim = ValueAnimator.ofFloat(0, 0);
     86             mHideSearchBarAnim.setDuration(TRANSITION_DURATION);
     87         }
     88     }
     89 
     90     private void prepareStartAnimation(View v) {
     91         // Enable the hw layers before the animation starts (will be disabled in the onAnimationEnd
     92         // callback below)
     93         if (v != null) {
     94             v.setLayerType(View.LAYER_TYPE_HARDWARE, null);
     95         }
     96     }
     97 
     98     private void setupAnimation(ValueAnimator anim, final View v) {
     99         anim.setInterpolator(sAccelerateInterpolator);
    100         anim.setDuration(TRANSITION_DURATION);
    101         anim.addListener(new AnimatorListenerAdapter() {
    102             @Override
    103             public void onAnimationEnd(Animator animation) {
    104                 if (v != null) {
    105                     v.setLayerType(View.LAYER_TYPE_NONE, null);
    106                 }
    107             }
    108         });
    109     }
    110 
    111     @Override
    112     protected void onFinishInflate() {
    113         super.onFinishInflate();
    114 
    115         // Get the individual components
    116         mDropTargetBar = findViewById(R.id.drag_target_bar);
    117         mInfoDropTarget = (ButtonDropTarget) mDropTargetBar.findViewById(R.id.info_target_text);
    118         mDeleteDropTarget = (ButtonDropTarget) mDropTargetBar.findViewById(R.id.delete_target_text);
    119         mUninstallDropTarget = (ButtonDropTarget) mDropTargetBar.findViewById(R.id.uninstall_target_text);
    120 
    121         mInfoDropTarget.setSearchDropTargetBar(this);
    122         mDeleteDropTarget.setSearchDropTargetBar(this);
    123         mUninstallDropTarget.setSearchDropTargetBar(this);
    124 
    125         // Create the various fade animations
    126         mDropTargetBar.setAlpha(0f);
    127         mShowDropTargetBarAnim = LauncherAnimUtils.ofFloat(mDropTargetBar, "alpha", 0f, 1f);
    128         setupAnimation(mShowDropTargetBarAnim, mDropTargetBar);
    129     }
    130 
    131     /**
    132      * Finishes all the animations on the search and drop target bars.
    133      */
    134     public void finishAnimations() {
    135         prepareStartAnimation(mDropTargetBar);
    136         mShowDropTargetBarAnim.reverse();
    137         prepareStartAnimation(mQSBSearchBar);
    138         mHideSearchBarAnim.reverse();
    139     }
    140 
    141     /**
    142      * Shows the search bar.
    143      */
    144     public void showSearchBar(boolean animated) {
    145         if (!mIsSearchBarHidden) return;
    146         if (animated) {
    147             prepareStartAnimation(mQSBSearchBar);
    148             mHideSearchBarAnim.reverse();
    149         } else {
    150             mHideSearchBarAnim.cancel();
    151             if (mQSBSearchBar != null) {
    152                 mQSBSearchBar.setAlpha(1f);
    153             }
    154         }
    155         mIsSearchBarHidden = false;
    156     }
    157 
    158     /**
    159      * Hides the search bar.  We only use this for clings.
    160      */
    161     public void hideSearchBar(boolean animated) {
    162         if (mIsSearchBarHidden) return;
    163         if (animated) {
    164             prepareStartAnimation(mQSBSearchBar);
    165             mHideSearchBarAnim.start();
    166         } else {
    167             mHideSearchBarAnim.cancel();
    168             if (mQSBSearchBar != null) {
    169                 mQSBSearchBar.setAlpha(0f);
    170             }
    171         }
    172         mIsSearchBarHidden = true;
    173     }
    174 
    175     /**
    176      * Shows the drop target bar.
    177      */
    178     public void showDeleteTarget() {
    179         // Animate out the QSB search bar, and animate in the drop target bar
    180         prepareStartAnimation(mDropTargetBar);
    181         mShowDropTargetBarAnim.start();
    182         hideSearchBar(true);
    183     }
    184 
    185     /**
    186      * Hides the drop target bar.
    187      */
    188     public void hideDeleteTarget() {
    189         // Restore the QSB search bar, and animate out the drop target bar
    190         prepareStartAnimation(mDropTargetBar);
    191         mShowDropTargetBarAnim.reverse();
    192         showSearchBar(true);
    193     }
    194 
    195     /*
    196      * DragController.DragListener implementation
    197      */
    198     @Override
    199     public void onDragStart(DragSource source, Object info, int dragAction) {
    200         showDeleteTarget();
    201     }
    202 
    203     public void deferOnDragEnd() {
    204         mDeferOnDragEnd = true;
    205     }
    206 
    207     @Override
    208     public void onDragEnd() {
    209         if (!mDeferOnDragEnd) {
    210             hideDeleteTarget();
    211         } else {
    212             mDeferOnDragEnd = false;
    213         }
    214     }
    215 
    216     public Rect getSearchBarBounds() {
    217         if (mQSBSearchBar != null) {
    218             final int[] pos = new int[2];
    219             mQSBSearchBar.getLocationOnScreen(pos);
    220 
    221             final Rect rect = new Rect();
    222             rect.left = pos[0];
    223             rect.top = pos[1];
    224             rect.right = pos[0] + mQSBSearchBar.getWidth();
    225             rect.bottom = pos[1] + mQSBSearchBar.getHeight();
    226             return rect;
    227         } else {
    228             return null;
    229         }
    230     }
    231 
    232     public void enableAccessibleDrag(boolean enable) {
    233         if (mQSBSearchBar != null) {
    234             mQSBSearchBar.setVisibility(enable ? View.GONE : View.VISIBLE);
    235         }
    236         mInfoDropTarget.enableAccessibleDrag(enable);
    237         mDeleteDropTarget.enableAccessibleDrag(enable);
    238         mUninstallDropTarget.enableAccessibleDrag(enable);
    239     }
    240 }
    241