DividerHandleView.java revision 514b2cf0f8ddd11a4176412cb3584ab96fbb763a
1514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi/* 2514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi * Copyright (C) 2015 The Android Open Source Project 3514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi * 4514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi * Licensed under the Apache License, Version 2.0 (the "License"); 5514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi * you may not use this file except in compliance with the License. 6514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi * You may obtain a copy of the License at 7514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi * 8514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi * http://www.apache.org/licenses/LICENSE-2.0 9514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi * 10514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi * Unless required by applicable law or agreed to in writing, software 11514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi * distributed under the License is distributed on an "AS IS" BASIS, 12514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi * See the License for the specific language governing permissions and 14514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi * limitations under the License. 15514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi */ 16514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi 17514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggipackage com.android.systemui.stackdivider; 18514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi 19514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggiimport android.animation.Animator; 20514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggiimport android.animation.AnimatorListenerAdapter; 21514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggiimport android.animation.AnimatorSet; 22514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggiimport android.animation.ObjectAnimator; 23514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggiimport android.annotation.Nullable; 24514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggiimport android.content.Context; 25514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggiimport android.graphics.Canvas; 26514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggiimport android.graphics.Paint; 27514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggiimport android.util.AttributeSet; 28514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggiimport android.util.Property; 29514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggiimport android.view.animation.AnimationUtils; 30514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggiimport android.view.animation.Interpolator; 31514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggiimport android.widget.ImageButton; 32514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi 33514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggiimport com.android.systemui.R; 34514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi 35514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi/** 36514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi * View for the handle in the docked stack divider. 37514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi */ 38514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggipublic class DividerHandleView extends ImageButton { 39514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi 40514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi private final static Property<DividerHandleView, Integer> WIDTH_PROPERTY 41514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi = new Property<DividerHandleView, Integer>(Integer.class, "width") { 42514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi 43514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi @Override 44514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi public Integer get(DividerHandleView object) { 45514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi return object.mCurrentWidth; 46514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi } 47514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi 48514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi @Override 49514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi public void set(DividerHandleView object, Integer value) { 50514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi object.mCurrentWidth = value; 51514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi object.invalidate(); 52514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi } 53514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi }; 54514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi 55514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi private final static Property<DividerHandleView, Integer> HEIGHT_PROPERTY 56514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi = new Property<DividerHandleView, Integer>(Integer.class, "height") { 57514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi 58514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi @Override 59514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi public Integer get(DividerHandleView object) { 60514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi return object.mCurrentHeight; 61514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi } 62514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi 63514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi @Override 64514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi public void set(DividerHandleView object, Integer value) { 65514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi object.mCurrentHeight = value; 66514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi object.invalidate(); 67514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi } 68514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi }; 69514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi 70514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi private final Paint mPaint = new Paint(); 71514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi private final int mWidth; 72514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi private final int mHeight; 73514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi private final int mCircleDiameter; 74514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi private final Interpolator mFastOutSlowInInterpolator; 75514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi private int mCurrentWidth; 76514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi private int mCurrentHeight; 77514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi private AnimatorSet mAnimator; 78514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi 79514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi public DividerHandleView(Context context, @Nullable AttributeSet attrs) { 80514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi super(context, attrs); 81514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi mPaint.setColor(getResources().getColor(R.color.docked_divider_handle, null)); 82514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi mPaint.setAntiAlias(true); 83514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi mWidth = getResources().getDimensionPixelSize(R.dimen.docked_divider_handle_width); 84514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi mHeight = getResources().getDimensionPixelSize(R.dimen.docked_divider_handle_height); 85514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi mCurrentWidth = mWidth; 86514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi mCurrentHeight = mHeight; 87514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi mCircleDiameter = (mWidth + mHeight) / 3; 88514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi mFastOutSlowInInterpolator = AnimationUtils.loadInterpolator(getContext(), 89514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi android.R.interpolator.fast_out_slow_in); 90514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi } 91514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi 92514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi public void setTouching(boolean touching, boolean animate) { 93514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi if (mAnimator != null) { 94514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi mAnimator.cancel(); 95514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi mAnimator = null; 96514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi } 97514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi if (!animate) { 98514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi if (touching) { 99514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi mCurrentWidth = mCircleDiameter; 100514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi mCurrentHeight = mCircleDiameter; 101514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi } else { 102514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi mCurrentWidth = mWidth; 103514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi mCurrentHeight = mHeight; 104514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi } 105514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi invalidate(); 106514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi } else { 107514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi animateToTarget(touching ? mCircleDiameter : mWidth, 108514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi touching ? mCircleDiameter : mHeight, touching); 109514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi } 110514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi } 111514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi 112514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi private void animateToTarget(int targetWidth, int targetHeight, boolean touching) { 113514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi ObjectAnimator widthAnimator = ObjectAnimator.ofInt(this, WIDTH_PROPERTY, 114514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi mCurrentWidth, targetWidth); 115514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi ObjectAnimator heightAnimator = ObjectAnimator.ofInt(this, HEIGHT_PROPERTY, 116514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi mCurrentHeight, targetHeight); 117514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi mAnimator = new AnimatorSet(); 118514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi mAnimator.playTogether(widthAnimator, heightAnimator); 119514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi mAnimator.setDuration(touching 120514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi ? DividerView.TOUCH_ANIMATION_DURATION 121514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi : DividerView.TOUCH_RELEASE_ANIMATION_DURATION); 122514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi mAnimator.setInterpolator(touching 123514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi ? DividerView.TOUCH_RESPONSE_INTERPOLATOR 124514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi : mFastOutSlowInInterpolator); 125514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi mAnimator.addListener(new AnimatorListenerAdapter() { 126514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi @Override 127514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi public void onAnimationEnd(Animator animation) { 128514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi mAnimator = null; 129514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi } 130514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi }); 131514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi mAnimator.start(); 132514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi } 133514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi 134514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi @Override 135514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi protected void onDraw(Canvas canvas) { 136514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi int left = getWidth() / 2 - mCurrentWidth / 2; 137514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi int top = getHeight() / 2 - mCurrentHeight / 2; 138514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi int radius = Math.min(mCurrentWidth, mCurrentHeight) / 2; 139514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi canvas.drawRoundRect(left, top, left + mCurrentWidth, top + mCurrentHeight, 140514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi radius, radius, mPaint); 141514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi } 142514b2cf0f8ddd11a4176412cb3584ab96fbb763aJorim Jaggi} 143