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     }
     81 
     82     private void setupAnimation(ObjectAnimator anim, final View v) {
     83         anim.setInterpolator(sAccelerateInterpolator);
     84         anim.setDuration(sTransitionInDuration);
     85         anim.addListener(new AnimatorListenerAdapter() {
     86             @Override
     87             public void onAnimationEnd(Animator animation) {
     88                 v.setLayerType(View.LAYER_TYPE_NONE, null);
     89             }
     90         });
     91     }
     92 
     93     @Override
     94     protected void onFinishInflate() {
     95         super.onFinishInflate();
     96 
     97         // Get the individual components
     98         mQSBSearchBar = findViewById(R.id.qsb_search_bar);
     99         mDropTargetBar = findViewById(R.id.drag_target_bar);
    100         mInfoDropTarget = (ButtonDropTarget) mDropTargetBar.findViewById(R.id.info_target_text);
    101         mDeleteDropTarget = (ButtonDropTarget) mDropTargetBar.findViewById(R.id.delete_target_text);
    102         mBarHeight = getResources().getDimensionPixelSize(R.dimen.qsb_bar_height);
    103 
    104         mInfoDropTarget.setSearchDropTargetBar(this);
    105         mDeleteDropTarget.setSearchDropTargetBar(this);
    106 
    107         mEnableDropDownDropTargets =
    108             getResources().getBoolean(R.bool.config_useDropTargetDownTransition);
    109 
    110         // Create the various fade animations
    111         if (mEnableDropDownDropTargets) {
    112             mDropTargetBar.setTranslationY(-mBarHeight);
    113             mDropTargetBarAnim = ObjectAnimator.ofFloat(mDropTargetBar, "translationY", -mBarHeight, 0f);
    114             mQSBSearchBarAnim = ObjectAnimator.ofFloat(mQSBSearchBar, "translationY", 0f, -mBarHeight);
    115         } else {
    116             mDropTargetBar.setAlpha(0f);
    117             mDropTargetBarAnim = ObjectAnimator.ofFloat(mDropTargetBar, "alpha", 0f, 1f);
    118             mQSBSearchBarAnim = ObjectAnimator.ofFloat(mQSBSearchBar, "alpha", 1f, 0f);
    119         }
    120         setupAnimation(mDropTargetBarAnim, mDropTargetBar);
    121         setupAnimation(mQSBSearchBarAnim, mQSBSearchBar);
    122     }
    123 
    124     public void finishAnimations() {
    125         prepareStartAnimation(mDropTargetBar);
    126         mDropTargetBarAnim.reverse();
    127         prepareStartAnimation(mQSBSearchBar);
    128         mQSBSearchBarAnim.reverse();
    129     }
    130 
    131     /*
    132      * Shows and hides the search bar.
    133      */
    134     public void showSearchBar(boolean animated) {
    135         if (!mIsSearchBarHidden) return;
    136         if (animated) {
    137             prepareStartAnimation(mQSBSearchBar);
    138             mQSBSearchBarAnim.reverse();
    139         } else {
    140             mQSBSearchBarAnim.cancel();
    141             if (mEnableDropDownDropTargets) {
    142                 mQSBSearchBar.setTranslationY(0);
    143             } else {
    144                 mQSBSearchBar.setAlpha(1f);
    145             }
    146         }
    147         mIsSearchBarHidden = false;
    148     }
    149     public void hideSearchBar(boolean animated) {
    150         if (mIsSearchBarHidden) return;
    151         if (animated) {
    152             prepareStartAnimation(mQSBSearchBar);
    153             mQSBSearchBarAnim.start();
    154         } else {
    155             mQSBSearchBarAnim.cancel();
    156             if (mEnableDropDownDropTargets) {
    157                 mQSBSearchBar.setTranslationY(-mBarHeight);
    158             } else {
    159                 mQSBSearchBar.setAlpha(0f);
    160             }
    161         }
    162         mIsSearchBarHidden = true;
    163     }
    164 
    165     /*
    166      * Gets various transition durations.
    167      */
    168     public int getTransitionInDuration() {
    169         return sTransitionInDuration;
    170     }
    171     public int getTransitionOutDuration() {
    172         return sTransitionOutDuration;
    173     }
    174 
    175     /*
    176      * DragController.DragListener implementation
    177      */
    178     @Override
    179     public void onDragStart(DragSource source, Object info, int dragAction) {
    180         // Animate out the QSB search bar, and animate in the drop target bar
    181         prepareStartAnimation(mDropTargetBar);
    182         mDropTargetBarAnim.start();
    183         if (!mIsSearchBarHidden) {
    184             prepareStartAnimation(mQSBSearchBar);
    185             mQSBSearchBarAnim.start();
    186         }
    187     }
    188 
    189     public void deferOnDragEnd() {
    190         mDeferOnDragEnd = true;
    191     }
    192 
    193     @Override
    194     public void onDragEnd() {
    195         if (!mDeferOnDragEnd) {
    196             // Restore the QSB search bar, and animate out the drop target bar
    197             prepareStartAnimation(mDropTargetBar);
    198             mDropTargetBarAnim.reverse();
    199             if (!mIsSearchBarHidden) {
    200                 prepareStartAnimation(mQSBSearchBar);
    201                 mQSBSearchBarAnim.reverse();
    202             }
    203         } else {
    204             mDeferOnDragEnd = false;
    205         }
    206     }
    207 
    208     public void onSearchPackagesChanged(boolean searchVisible, boolean voiceVisible) {
    209         if (mQSBSearchBar != null) {
    210             Drawable bg = mQSBSearchBar.getBackground();
    211             if (bg != null && (!searchVisible && !voiceVisible)) {
    212                 // Save the background and disable it
    213                 mPreviousBackground = bg;
    214                 mQSBSearchBar.setBackgroundResource(0);
    215             } else if (mPreviousBackground != null && (searchVisible || voiceVisible)) {
    216                 // Restore the background
    217                 mQSBSearchBar.setBackground(mPreviousBackground);
    218             }
    219         }
    220     }
    221 
    222     public Rect getSearchBarBounds() {
    223         if (mQSBSearchBar != null) {
    224             final int[] pos = new int[2];
    225             mQSBSearchBar.getLocationOnScreen(pos);
    226 
    227             final Rect rect = new Rect();
    228             rect.left = pos[0];
    229             rect.top = pos[1];
    230             rect.right = pos[0] + mQSBSearchBar.getWidth();
    231             rect.bottom = pos[1] + mQSBSearchBar.getHeight();
    232             return rect;
    233         } else {
    234             return null;
    235         }
    236     }
    237 }
    238