/*
* Copyright 2015. Appsi Mobile
*
* 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.appsimobile.appsii;
import android.animation.ObjectAnimator;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import com.appsimobile.annotation.KeepName;
/**
* Created by nick on 22/08/14.
*/
public class ExpandCollapseDrawable extends Drawable {
private static Paint sPaint;
final int mColor;
int mAlpha;
final float[] mPositionsX = new float[]{.25f, .5f, .75f};
final float[] mExpandedYPositions = new float[]{.35f, .6f, .35f};
final float[] mCollapsedYPositions = new float[]{.65f, .4f, .65f};
// we need a new array, don't reference mCollapsedYPositions
final float[] mCurrentYPositions = new float[]{.6f, .4f, .6f};
private ColorFilter mColorFilter;
private boolean mExpanded;
private final ObjectAnimator mY1Animator;
private final ObjectAnimator mY2Animator;
private final ObjectAnimator mY3Animator;
private final Path mPath = new Path();
public ExpandCollapseDrawable(Resources resources) {
this(resources, 0x3d000000);
}
public ExpandCollapseDrawable(Resources resources, int color) {
if (sPaint == null) {
sPaint = new Paint();
sPaint.setStrokeWidth(2.5f * resources.getDisplayMetrics().density);
sPaint.setStyle(Paint.Style.STROKE);
sPaint.setAntiAlias(true);
sPaint.setStrokeCap(Paint.Cap.SQUARE);
}
mY1Animator = ObjectAnimator.ofFloat(this, "y1", 0, 0).setDuration(220);
mY2Animator = ObjectAnimator.ofFloat(this, "y2", 0, 0).setDuration(220);
mY3Animator = ObjectAnimator.ofFloat(this, "y3", 0, 0).setDuration(220);
mY1Animator.setFloatValues();
mColor = color;
}
/**
* Setter for the mY1Animator. Used by the animator.
*/
@SuppressWarnings("UnusedDeclaration")
@KeepName
public void setY1(float y1) {
mCurrentYPositions[0] = y1;
notifyCallback();
}
private void notifyCallback() {
Callback callback = getCallback();
if (callback != null) {
callback.invalidateDrawable(this);
}
}
/**
* Setter for the value of {@link #mY2Animator}. Used by the animator
*/
@SuppressWarnings("UnusedDeclaration")
@KeepName
public void setY2(float y2) {
mCurrentYPositions[1] = y2;
notifyCallback();
}
/**
* Setter for the value of {@link #mY3Animator}. Used by the animator
*/
@SuppressWarnings("UnusedDeclaration")
@KeepName
public void setY3(float y3) {
mCurrentYPositions[2] = y3;
notifyCallback();
}
@Override
public void draw(Canvas canvas) {
Rect rect = getBounds();
sPaint.setColor(mColor);
sPaint.setColorFilter(mColorFilter);
int x1 = (int) (rect.width() * mPositionsX[0]);
int x2 = (int) (rect.width() * mPositionsX[1]);
int x3 = (int) (rect.width() * mPositionsX[2]);
int y1 = (int) (rect.height() * mCurrentYPositions[0]);
int y2 = (int) (rect.height() * mCurrentYPositions[1]);
int y3 = (int) (rect.height() * mCurrentYPositions[2]);
mPath.reset();
mPath.moveTo(x1, y1);
mPath.lineTo(x2, y2);
mPath.lineTo(x3, y3);
canvas.drawPath(mPath, sPaint);
// canvas.drawLine(x1, y1, x2, y2, sPaint);
// canvas.drawLine(x3, y3, x2, y2, sPaint);
}
@Override
public void setAlpha(int alpha) {
mAlpha = alpha;
notifyCallback();
}
@Override
public void setColorFilter(ColorFilter cf) {
mColorFilter = cf;
notifyCallback();
}
@Override
public int getOpacity() {
return PixelFormat.TRANSLUCENT;
}
@Override
protected boolean onStateChange(int[] state) {
boolean changed = super.onStateChange(state);
boolean foundExpanded = false;
int count = state.length;
for (int i = 0; i < count; i++) {
if (state[i] == android.R.attr.state_expanded) {
foundExpanded = true;
break;
}
}
if (mExpanded != foundExpanded) {
mExpanded = foundExpanded;
startAnimation();
changed = true;
}
return changed;
}
private void startAnimation() {
float[] targetPositions = mExpanded ? mExpandedYPositions : mCollapsedYPositions;
mY1Animator.setFloatValues(mCurrentYPositions[0], targetPositions[0]);
mY2Animator.setFloatValues(mCurrentYPositions[1], targetPositions[1]);
mY3Animator.setFloatValues(mCurrentYPositions[2], targetPositions[2]);
mY2Animator.setStartDelay(100);
mY3Animator.setStartDelay(150);
mY1Animator.start();
mY2Animator.start();
mY3Animator.start();
}
public void setExpanded(boolean expanded, boolean animate) {
if (mExpanded != expanded) {
mExpanded = expanded;
if (animate) {
startAnimation();
} else {
if (expanded) {
System.arraycopy(mExpandedYPositions, 0, mCurrentYPositions, 0,
mCurrentYPositions.length);
} else {
System.arraycopy(mCollapsedYPositions, 0, mCurrentYPositions, 0,
mCurrentYPositions.length);
}
}
notifyCallback();
}
}
public boolean isExpanded() {
return mExpanded;
}
}