SearchDropTargetBar.java revision 043f2af567178b82b0b41f12d379e7dd12da2936
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
17package com.android.launcher2;
18
19import android.animation.Animator;
20import android.animation.AnimatorListenerAdapter;
21import android.animation.AnimatorSet;
22import android.animation.ObjectAnimator;
23import android.content.Context;
24import android.graphics.Rect;
25import android.graphics.drawable.Drawable;
26import android.util.AttributeSet;
27import android.view.View;
28import android.view.animation.AccelerateInterpolator;
29import android.view.animation.DecelerateInterpolator;
30import android.widget.FrameLayout;
31
32import 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 */
38public 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        dragController.setFlingToDeleteDropTarget(mDeleteDropTarget);
73        mInfoDropTarget.setLauncher(launcher);
74        mDeleteDropTarget.setLauncher(launcher);
75    }
76
77    @Override
78    protected void onFinishInflate() {
79        super.onFinishInflate();
80
81        // Get the individual components
82        mQSBSearchBar = findViewById(R.id.qsb_search_bar);
83        mDropTargetBar = findViewById(R.id.drag_target_bar);
84        mInfoDropTarget = (ButtonDropTarget) mDropTargetBar.findViewById(R.id.info_target_text);
85        mDeleteDropTarget = (ButtonDropTarget) mDropTargetBar.findViewById(R.id.delete_target_text);
86        mBarHeight = getResources().getDimensionPixelSize(R.dimen.qsb_bar_height);
87
88        mInfoDropTarget.setSearchDropTargetBar(this);
89        mDeleteDropTarget.setSearchDropTargetBar(this);
90
91        boolean enableDropDownDropTargets =
92            getResources().getBoolean(R.bool.config_useDropTargetDownTransition);
93
94        // Create the various fade animations
95        mDropTargetBar.setAlpha(0f);
96        ObjectAnimator fadeInAlphaAnim = ObjectAnimator.ofFloat(mDropTargetBar, "alpha", 1f);
97        fadeInAlphaAnim.setInterpolator(new DecelerateInterpolator());
98        mDropTargetBarFadeInAnim = new AnimatorSet();
99        AnimatorSet.Builder fadeInAnimators = mDropTargetBarFadeInAnim.play(fadeInAlphaAnim);
100        if (enableDropDownDropTargets) {
101            mDropTargetBar.setTranslationY(-mBarHeight);
102            fadeInAnimators.with(ObjectAnimator.ofFloat(mDropTargetBar, "translationY", 0f));
103        }
104        mDropTargetBarFadeInAnim.setDuration(sTransitionInDuration);
105        mDropTargetBarFadeInAnim.addListener(new AnimatorListenerAdapter() {
106            @Override
107            public void onAnimationStart(Animator animation) {
108                mDropTargetBar.setVisibility(View.VISIBLE);
109            }
110        });
111        ObjectAnimator fadeOutAlphaAnim = ObjectAnimator.ofFloat(mDropTargetBar, "alpha", 0f);
112        fadeOutAlphaAnim.setInterpolator(new AccelerateInterpolator());
113        mDropTargetBarFadeOutAnim = new AnimatorSet();
114        AnimatorSet.Builder fadeOutAnimators = mDropTargetBarFadeOutAnim.play(fadeOutAlphaAnim);
115        if (enableDropDownDropTargets) {
116            fadeOutAnimators.with(ObjectAnimator.ofFloat(mDropTargetBar, "translationY",
117                    -mBarHeight));
118        }
119        mDropTargetBarFadeOutAnim.setDuration(sTransitionOutDuration);
120        mDropTargetBarFadeOutAnim.addListener(new AnimatorListenerAdapter() {
121            @Override
122            public void onAnimationEnd(Animator animation) {
123                mDropTargetBar.setVisibility(View.INVISIBLE);
124                mDropTargetBar.setLayerType(View.LAYER_TYPE_NONE, null);
125            }
126        });
127        mQSBSearchBarFadeInAnim = ObjectAnimator.ofFloat(mQSBSearchBar, "alpha", 1f);
128        mQSBSearchBarFadeInAnim.setDuration(sTransitionInDuration);
129        mQSBSearchBarFadeInAnim.addListener(new AnimatorListenerAdapter() {
130            @Override
131            public void onAnimationStart(Animator animation) {
132                mQSBSearchBar.setVisibility(View.VISIBLE);
133                mQSBSearchBar.setLayerType(View.LAYER_TYPE_HARDWARE, null);
134            }
135
136            @Override
137            public void onAnimationEnd(Animator animation) {
138                mQSBSearchBar.setLayerType(View.LAYER_TYPE_NONE, null);
139            }
140        });
141        mQSBSearchBarFadeOutAnim = ObjectAnimator.ofFloat(mQSBSearchBar, "alpha", 0f);
142        mQSBSearchBarFadeOutAnim.setDuration(sTransitionOutDuration);
143        mQSBSearchBarFadeOutAnim.addListener(new AnimatorListenerAdapter() {
144            @Override
145            public void onAnimationStart(Animator animation) {
146                mQSBSearchBar.setLayerType(View.LAYER_TYPE_HARDWARE, null);
147            }
148
149            @Override
150            public void onAnimationEnd(Animator animation) {
151                mQSBSearchBar.setVisibility(View.INVISIBLE);
152                mQSBSearchBar.setLayerType(View.LAYER_TYPE_NONE, null);
153            }
154        });
155    }
156
157    public void finishAnimations() {
158        mDropTargetBarFadeInAnim.end();
159        mDropTargetBarFadeOutAnim.end();
160        mQSBSearchBarFadeInAnim.end();
161        mQSBSearchBarFadeOutAnim.end();
162    }
163
164    private void cancelAnimations() {
165        mDropTargetBarFadeInAnim.cancel();
166        mDropTargetBarFadeOutAnim.cancel();
167        mQSBSearchBarFadeInAnim.cancel();
168        mQSBSearchBarFadeOutAnim.cancel();
169    }
170
171    /*
172     * Shows and hides the search bar.
173     */
174    public void showSearchBar(boolean animated) {
175        cancelAnimations();
176        if (animated) {
177            mQSBSearchBarFadeInAnim.start();
178        } else {
179            mQSBSearchBar.setVisibility(View.VISIBLE);
180            mQSBSearchBar.setAlpha(1f);
181        }
182        mIsSearchBarHidden = false;
183    }
184    public void hideSearchBar(boolean animated) {
185        cancelAnimations();
186        if (animated) {
187            mQSBSearchBarFadeOutAnim.start();
188        } else {
189            mQSBSearchBar.setVisibility(View.INVISIBLE);
190            mQSBSearchBar.setAlpha(0f);
191        }
192        mIsSearchBarHidden = true;
193    }
194
195    /*
196     * Gets various transition durations.
197     */
198    public int getTransitionInDuration() {
199        return sTransitionInDuration;
200    }
201    public int getTransitionOutDuration() {
202        return sTransitionOutDuration;
203    }
204
205    /*
206     * DragController.DragListener implementation
207     */
208    @Override
209    public void onDragStart(DragSource source, Object info, int dragAction) {
210        // Animate out the QSB search bar, and animate in the drop target bar
211        mDropTargetBar.setLayerType(View.LAYER_TYPE_HARDWARE, null);
212        mDropTargetBar.buildLayer();
213        mDropTargetBarFadeOutAnim.cancel();
214        mDropTargetBarFadeInAnim.start();
215        if (!mIsSearchBarHidden) {
216            mQSBSearchBarFadeInAnim.cancel();
217            mQSBSearchBarFadeOutAnim.start();
218        }
219    }
220
221    public void deferOnDragEnd() {
222        mDeferOnDragEnd = true;
223    }
224
225    @Override
226    public void onDragEnd() {
227        if (!mDeferOnDragEnd) {
228            // Restore the QSB search bar, and animate out the drop target bar
229            mDropTargetBarFadeInAnim.cancel();
230            mDropTargetBarFadeOutAnim.start();
231            if (!mIsSearchBarHidden) {
232                mQSBSearchBarFadeOutAnim.cancel();
233                mQSBSearchBarFadeInAnim.start();
234            }
235        } else {
236            mDeferOnDragEnd = false;
237        }
238    }
239
240    public void onSearchPackagesChanged(boolean searchVisible, boolean voiceVisible) {
241        if (mQSBSearchBar != null) {
242            Drawable bg = mQSBSearchBar.getBackground();
243            if (bg != null && (!searchVisible && !voiceVisible)) {
244                // Save the background and disable it
245                mPreviousBackground = bg;
246                mQSBSearchBar.setBackgroundResource(0);
247            } else if (mPreviousBackground != null && (searchVisible || voiceVisible)) {
248                // Restore the background
249                mQSBSearchBar.setBackgroundDrawable(mPreviousBackground);
250            }
251        }
252    }
253
254    public Rect getSearchBarBounds() {
255        if (mQSBSearchBar != null) {
256            final float appScale = mQSBSearchBar.getContext().getResources()
257                    .getCompatibilityInfo().applicationScale;
258            final int[] pos = new int[2];
259            mQSBSearchBar.getLocationOnScreen(pos);
260
261            final Rect rect = new Rect();
262            rect.left = (int) (pos[0] * appScale + 0.5f);
263            rect.top = (int) (pos[1] * appScale + 0.5f);
264            rect.right = (int) ((pos[0] + mQSBSearchBar.getWidth()) * appScale + 0.5f);
265            rect.bottom = (int) ((pos[1] + mQSBSearchBar.getHeight()) * appScale + 0.5f);
266            return rect;
267        } else {
268            return null;
269        }
270    }
271}
272