| /* |
| * Copyright (C) 2015 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package com.android.systemui.stackdivider; |
| |
| import android.animation.Animator; |
| import android.animation.AnimatorListenerAdapter; |
| import android.animation.AnimatorSet; |
| import android.animation.ObjectAnimator; |
| import android.annotation.Nullable; |
| import android.content.Context; |
| import android.graphics.Canvas; |
| import android.graphics.Paint; |
| import android.util.AttributeSet; |
| import android.util.Property; |
| import android.view.View; |
| |
| import com.android.systemui.Interpolators; |
| import com.android.systemui.R; |
| |
| /** |
| * View for the handle in the docked stack divider. |
| */ |
| public class DividerHandleView extends View { |
| |
| private final static Property<DividerHandleView, Integer> WIDTH_PROPERTY |
| = new Property<DividerHandleView, Integer>(Integer.class, "width") { |
| |
| @Override |
| public Integer get(DividerHandleView object) { |
| return object.mCurrentWidth; |
| } |
| |
| @Override |
| public void set(DividerHandleView object, Integer value) { |
| object.mCurrentWidth = value; |
| object.invalidate(); |
| } |
| }; |
| |
| private final static Property<DividerHandleView, Integer> HEIGHT_PROPERTY |
| = new Property<DividerHandleView, Integer>(Integer.class, "height") { |
| |
| @Override |
| public Integer get(DividerHandleView object) { |
| return object.mCurrentHeight; |
| } |
| |
| @Override |
| public void set(DividerHandleView object, Integer value) { |
| object.mCurrentHeight = value; |
| object.invalidate(); |
| } |
| }; |
| |
| private final Paint mPaint = new Paint(); |
| private final int mWidth; |
| private final int mHeight; |
| private final int mCircleDiameter; |
| private int mCurrentWidth; |
| private int mCurrentHeight; |
| private AnimatorSet mAnimator; |
| private boolean mTouching; |
| |
| public DividerHandleView(Context context, @Nullable AttributeSet attrs) { |
| super(context, attrs); |
| mPaint.setColor(getResources().getColor(R.color.docked_divider_handle, null)); |
| mPaint.setAntiAlias(true); |
| mWidth = getResources().getDimensionPixelSize(R.dimen.docked_divider_handle_width); |
| mHeight = getResources().getDimensionPixelSize(R.dimen.docked_divider_handle_height); |
| mCurrentWidth = mWidth; |
| mCurrentHeight = mHeight; |
| mCircleDiameter = (mWidth + mHeight) / 3; |
| } |
| |
| public void setTouching(boolean touching, boolean animate) { |
| if (touching == mTouching) { |
| return; |
| } |
| if (mAnimator != null) { |
| mAnimator.cancel(); |
| mAnimator = null; |
| } |
| if (!animate) { |
| if (touching) { |
| mCurrentWidth = mCircleDiameter; |
| mCurrentHeight = mCircleDiameter; |
| } else { |
| mCurrentWidth = mWidth; |
| mCurrentHeight = mHeight; |
| } |
| invalidate(); |
| } else { |
| animateToTarget(touching ? mCircleDiameter : mWidth, |
| touching ? mCircleDiameter : mHeight, touching); |
| } |
| mTouching = touching; |
| } |
| |
| private void animateToTarget(int targetWidth, int targetHeight, boolean touching) { |
| ObjectAnimator widthAnimator = ObjectAnimator.ofInt(this, WIDTH_PROPERTY, |
| mCurrentWidth, targetWidth); |
| ObjectAnimator heightAnimator = ObjectAnimator.ofInt(this, HEIGHT_PROPERTY, |
| mCurrentHeight, targetHeight); |
| mAnimator = new AnimatorSet(); |
| mAnimator.playTogether(widthAnimator, heightAnimator); |
| mAnimator.setDuration(touching |
| ? DividerView.TOUCH_ANIMATION_DURATION |
| : DividerView.TOUCH_RELEASE_ANIMATION_DURATION); |
| mAnimator.setInterpolator(touching |
| ? Interpolators.TOUCH_RESPONSE |
| : Interpolators.FAST_OUT_SLOW_IN); |
| mAnimator.addListener(new AnimatorListenerAdapter() { |
| @Override |
| public void onAnimationEnd(Animator animation) { |
| mAnimator = null; |
| } |
| }); |
| mAnimator.start(); |
| } |
| |
| @Override |
| protected void onDraw(Canvas canvas) { |
| int left = getWidth() / 2 - mCurrentWidth / 2; |
| int top = getHeight() / 2 - mCurrentHeight / 2; |
| int radius = Math.min(mCurrentWidth, mCurrentHeight) / 2; |
| canvas.drawRoundRect(left, top, left + mCurrentWidth, top + mCurrentHeight, |
| radius, radius, mPaint); |
| } |
| |
| @Override |
| public boolean hasOverlappingRendering() { |
| return false; |
| } |
| } |