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 sTransitionInDuration = 200;
     37     private static final int sTransitionOutDuration = 175;
     38 
     39     private ObjectAnimator mDropTargetBarAnim;
     40     private ValueAnimator mQSBSearchBarAnim;
     41     private static final AccelerateInterpolator sAccelerateInterpolator =
     42             new AccelerateInterpolator();
     43 
     44     private boolean mIsSearchBarHidden;
     45     private View mQSBSearchBar;
     46     private View mDropTargetBar;
     47     private ButtonDropTarget mInfoDropTarget;
     48     private ButtonDropTarget mDeleteDropTarget;
     49     private int mBarHeight;
     50     private boolean mDeferOnDragEnd = false;
     51 
     52     private boolean mEnableDropDownDropTargets;
     53 
     54     public SearchDropTargetBar(Context context, AttributeSet attrs) {
     55         this(context, attrs, 0);
     56     }
     57 
     58     public SearchDropTargetBar(Context context, AttributeSet attrs, int defStyle) {
     59         super(context, attrs, defStyle);
     60     }
     61 
     62     public void setup(Launcher launcher, DragController dragController) {
     63         dragController.addDragListener(this);
     64         dragController.addDragListener(mInfoDropTarget);
     65         dragController.addDragListener(mDeleteDropTarget);
     66         dragController.addDropTarget(mInfoDropTarget);
     67         dragController.addDropTarget(mDeleteDropTarget);
     68         dragController.setFlingToDeleteDropTarget(mDeleteDropTarget);
     69         mInfoDropTarget.setLauncher(launcher);
     70         mDeleteDropTarget.setLauncher(launcher);
     71     }
     72 
     73     public void setQsbSearchBar(View qsb) {
     74         mQSBSearchBar = qsb;
     75         if (mQSBSearchBar != null) {
     76             if (mEnableDropDownDropTargets) {
     77                 mQSBSearchBarAnim = LauncherAnimUtils.ofFloat(mQSBSearchBar, "translationY", 0,
     78                         -mBarHeight);
     79             } else {
     80                 mQSBSearchBarAnim = LauncherAnimUtils.ofFloat(mQSBSearchBar, "alpha", 1f, 0f);
     81             }
     82             setupAnimation(mQSBSearchBarAnim, mQSBSearchBar);
     83         } else {
     84             // Create a no-op animation of the search bar is null
     85             mQSBSearchBarAnim = ValueAnimator.ofFloat(0, 0);
     86             mQSBSearchBarAnim.setDuration(sTransitionInDuration);
     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(sTransitionInDuration);
    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 
    120         mInfoDropTarget.setSearchDropTargetBar(this);
    121         mDeleteDropTarget.setSearchDropTargetBar(this);
    122 
    123         mEnableDropDownDropTargets =
    124             getResources().getBoolean(R.bool.config_useDropTargetDownTransition);
    125 
    126         // Create the various fade animations
    127         if (mEnableDropDownDropTargets) {
    128             LauncherAppState app = LauncherAppState.getInstance();
    129             DeviceProfile grid = app.getDynamicGrid().getDeviceProfile();
    130             mBarHeight = grid.searchBarSpaceHeightPx;
    131             mDropTargetBar.setTranslationY(-mBarHeight);
    132             mDropTargetBarAnim = LauncherAnimUtils.ofFloat(mDropTargetBar, "translationY",
    133                     -mBarHeight, 0f);
    134 
    135         } else {
    136             mDropTargetBar.setAlpha(0f);
    137             mDropTargetBarAnim = LauncherAnimUtils.ofFloat(mDropTargetBar, "alpha", 0f, 1f);
    138         }
    139         setupAnimation(mDropTargetBarAnim, mDropTargetBar);
    140     }
    141 
    142     public void finishAnimations() {
    143         prepareStartAnimation(mDropTargetBar);
    144         mDropTargetBarAnim.reverse();
    145         prepareStartAnimation(mQSBSearchBar);
    146         mQSBSearchBarAnim.reverse();
    147     }
    148 
    149     /*
    150      * Shows and hides the search bar.
    151      */
    152     public void showSearchBar(boolean animated) {
    153         boolean needToCancelOngoingAnimation = mQSBSearchBarAnim.isRunning() && !animated;
    154         if (!mIsSearchBarHidden && !needToCancelOngoingAnimation) return;
    155         if (animated) {
    156             prepareStartAnimation(mQSBSearchBar);
    157             mQSBSearchBarAnim.reverse();
    158         } else {
    159             mQSBSearchBarAnim.cancel();
    160             if (mQSBSearchBar != null && mEnableDropDownDropTargets) {
    161                 mQSBSearchBar.setTranslationY(0);
    162             } else if (mQSBSearchBar != null) {
    163                 mQSBSearchBar.setAlpha(1f);
    164             }
    165         }
    166         mIsSearchBarHidden = false;
    167     }
    168     public void hideSearchBar(boolean animated) {
    169         boolean needToCancelOngoingAnimation = mQSBSearchBarAnim.isRunning() && !animated;
    170         if (mIsSearchBarHidden && !needToCancelOngoingAnimation) return;
    171         if (animated) {
    172             prepareStartAnimation(mQSBSearchBar);
    173             mQSBSearchBarAnim.start();
    174         } else {
    175             mQSBSearchBarAnim.cancel();
    176             if (mQSBSearchBar != null && mEnableDropDownDropTargets) {
    177                 mQSBSearchBar.setTranslationY(-mBarHeight);
    178             } else if (mQSBSearchBar != null) {
    179                 mQSBSearchBar.setAlpha(0f);
    180             }
    181         }
    182         mIsSearchBarHidden = true;
    183     }
    184 
    185     /*
    186      * Gets various transition durations.
    187      */
    188     public int getTransitionInDuration() {
    189         return sTransitionInDuration;
    190     }
    191     public int getTransitionOutDuration() {
    192         return sTransitionOutDuration;
    193     }
    194 
    195     /*
    196      * DragController.DragListener implementation
    197      */
    198     @Override
    199     public void onDragStart(DragSource source, Object info, int dragAction) {
    200         // Animate out the QSB search bar, and animate in the drop target bar
    201         prepareStartAnimation(mDropTargetBar);
    202         mDropTargetBarAnim.start();
    203         if (!mIsSearchBarHidden) {
    204             prepareStartAnimation(mQSBSearchBar);
    205             mQSBSearchBarAnim.start();
    206         }
    207     }
    208 
    209     public void deferOnDragEnd() {
    210         mDeferOnDragEnd = true;
    211     }
    212 
    213     @Override
    214     public void onDragEnd() {
    215         if (!mDeferOnDragEnd) {
    216             // Restore the QSB search bar, and animate out the drop target bar
    217             prepareStartAnimation(mDropTargetBar);
    218             mDropTargetBarAnim.reverse();
    219             if (!mIsSearchBarHidden) {
    220                 prepareStartAnimation(mQSBSearchBar);
    221                 mQSBSearchBarAnim.reverse();
    222             }
    223         } else {
    224             mDeferOnDragEnd = false;
    225         }
    226     }
    227 
    228     public Rect getSearchBarBounds() {
    229         if (mQSBSearchBar != null) {
    230             final int[] pos = new int[2];
    231             mQSBSearchBar.getLocationOnScreen(pos);
    232 
    233             final Rect rect = new Rect();
    234             rect.left = pos[0];
    235             rect.top = pos[1];
    236             rect.right = pos[0] + mQSBSearchBar.getWidth();
    237             rect.bottom = pos[1] + mQSBSearchBar.getHeight();
    238             return rect;
    239         } else {
    240             return null;
    241         }
    242     }
    243 }
    244