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