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