package com.florianmski.tracktoid.ui.widgets;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ArgbEvaluator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorFilter;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.StateListDrawable;
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.widget.Button;
import com.florianmski.tracktoid.R;
public class TraktActionView extends Button
{
private boolean checked = false;
private boolean working = false;
private int colorNotChecked;
private int colorChecked;
private int colorPressed;
private WorkingDrawable workingDrawable;
private OnTAVClickListener userListener;
private OnClickListener internalListener = new OnClickListener()
{
@Override
public void onClick(View v)
{
toggle();
}
};
public TraktActionView(Context context)
{
super(context);
init(context, null);
}
public TraktActionView(Context context, AttributeSet attrs)
{
super(context, attrs);
init(context, attrs);
}
private void init(Context context, AttributeSet attrs)
{
colorNotChecked = getColor(R.color.gray);
TypedArray attr = context.obtainStyledAttributes(attrs, R.styleable.TraktActionView, 0, 0);
if (attr == null)
return;
try
{
colorChecked = attr.getColor(R.styleable.TraktActionView_colorChecked, Color.BLACK);
colorPressed = attr.getColor(R.styleable.TraktActionView_colorPressed, Color.RED);
}
finally
{
attr.recycle();
}
setBackgroundDrawable(createDefaultDrawable());
workingDrawable = new WorkingDrawable(colorNotChecked, colorChecked);
setOnClickListener(internalListener);
}
private StateListDrawable createDefaultDrawable()
{
StateListDrawable drawable = new StateListDrawable();
Drawable colorNotCheckedDrawable = new ColorDrawable(colorNotChecked);
Drawable colorCheckedDrawable = new ColorDrawable(colorChecked);
Drawable colorPressedDrawable = new ColorDrawable(colorPressed);
drawable.addState(new int[]{android.R.attr.state_pressed}, colorPressedDrawable);
drawable.addState(new int[]{android.R.attr.state_focused}, colorPressedDrawable);
drawable.addState(new int[]{android.R.attr.state_selected}, colorPressedDrawable);
drawable.addState(new int[]{}, checked ? colorCheckedDrawable : colorNotCheckedDrawable);
return drawable;
}
private int getColor(int id)
{
return getResources().getColor(id);
}
@Override
public void setOnClickListener(OnClickListener l)
{
super.setOnClickListener(l);
}
public void setOnTAVClickListener(OnTAVClickListener listener)
{
this.userListener = listener;
}
public void setChecked(boolean checked)
{
if(this.checked == checked)
return;
this.checked = checked;
setBackgroundDrawable(createDefaultDrawable());
}
public boolean isChecked()
{
return checked;
}
public void success()
{
workingDrawable.stopAnimation(true);
}
public void error()
{
workingDrawable.stopAnimation(false);
}
public void toggle()
{
// not clickable if working
if(!working)
{
goToWork();
if(userListener != null)
userListener.onClick(isChecked());
}
}
private void goToWork()
{
working = true;
if(checked)
{
setBackgroundDrawable(workingDrawable);
workingDrawable.startAnimation(true);
}
else
{
setBackgroundDrawable(workingDrawable);
workingDrawable.startAnimation(false);
}
}
public interface OnTAVClickListener
{
public void onClick(boolean checked);
}
public class WorkingDrawable extends Drawable
{
private int startColor;
private int currentColor;
private int endColor;
private ValueAnimator colorAnimation;
public WorkingDrawable(int startColor, int endColor)
{
this.startColor = startColor;
this.endColor = endColor;
this.currentColor = startColor;
}
@Override
public void draw(Canvas canvas)
{
canvas.drawColor(currentColor);
}
@Override
public void setAlpha(int i) {}
@Override
public void setColorFilter(ColorFilter colorFilter) {}
@Override
public int getOpacity()
{
return 0;
}
public void startAnimation(boolean reverse)
{
if(reverse)
colorAnimation = ValueAnimator.ofObject(new ArgbEvaluator(), endColor, startColor, endColor);
else
colorAnimation = ValueAnimator.ofObject(new ArgbEvaluator(), startColor, endColor, startColor);
colorAnimation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener()
{
@Override
public void onAnimationUpdate(ValueAnimator animator)
{
currentColor = (Integer) animator.getAnimatedValue();
invalidateSelf();
}
});
colorAnimation.setDuration(1500);
colorAnimation.setInterpolator(new AccelerateDecelerateInterpolator());
colorAnimation.setRepeatCount(ValueAnimator.INFINITE);
colorAnimation.start();
}
public void stopAnimation(final boolean success)
{
if (success)
checked = !checked;
colorAnimation.removeAllListeners();
colorAnimation.addListener(new AnimatorListenerAdapter()
{
@Override
public void onAnimationEnd(Animator animation)
{
setBackgroundDrawable(createDefaultDrawable());
working = false;
}
});
colorAnimation.setRepeatCount(0);
}
}
}