487 lines
18 KiB
Java
Executable File
487 lines
18 KiB
Java
Executable File
package code.name.monkey.retromusic.swipebtn;
|
|
|
|
import android.animation.Animator;
|
|
import android.animation.AnimatorListenerAdapter;
|
|
import android.animation.AnimatorSet;
|
|
import android.animation.ObjectAnimator;
|
|
import android.animation.ValueAnimator;
|
|
import android.annotation.TargetApi;
|
|
import android.content.Context;
|
|
import android.content.res.TypedArray;
|
|
import android.graphics.Color;
|
|
import android.graphics.drawable.Drawable;
|
|
import android.support.v4.content.ContextCompat;
|
|
import android.util.AttributeSet;
|
|
import android.view.Gravity;
|
|
import android.view.MotionEvent;
|
|
import android.view.View;
|
|
import android.view.ViewGroup;
|
|
import android.view.animation.AccelerateDecelerateInterpolator;
|
|
import android.widget.ImageView;
|
|
import android.widget.LinearLayout;
|
|
import android.widget.RelativeLayout;
|
|
import android.widget.TextView;
|
|
|
|
import code.name.monkey.retromusic.R;
|
|
|
|
public class SwipeButton extends RelativeLayout {
|
|
|
|
|
|
private static final int ENABLED = 0;
|
|
private static final int DISABLED = 1;
|
|
private ImageView swipeButtonInner;
|
|
private float initialX;
|
|
private boolean active;
|
|
private TextView centerText;
|
|
private ViewGroup background;
|
|
private Drawable disabledDrawable;
|
|
private Drawable enabledDrawable;
|
|
private OnStateChangeListener onStateChangeListener;
|
|
private OnActiveListener onActiveListener;
|
|
private int collapsedWidth;
|
|
private int collapsedHeight;
|
|
|
|
private LinearLayout layer;
|
|
private boolean trailEnabled = false;
|
|
private boolean hasActivationState;
|
|
|
|
public SwipeButton(Context context) {
|
|
super(context);
|
|
|
|
init(context, null, -1, -1);
|
|
}
|
|
|
|
public SwipeButton(Context context, AttributeSet attrs) {
|
|
super(context, attrs);
|
|
|
|
init(context, attrs, -1, -1);
|
|
}
|
|
|
|
public SwipeButton(Context context, AttributeSet attrs, int defStyleAttr) {
|
|
super(context, attrs, defStyleAttr);
|
|
|
|
init(context, attrs, defStyleAttr, -1);
|
|
}
|
|
|
|
@TargetApi(21)
|
|
public SwipeButton(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
|
|
super(context, attrs, defStyleAttr, defStyleRes);
|
|
|
|
init(context, attrs, defStyleAttr, defStyleRes);
|
|
}
|
|
|
|
public void setCenterTextColor(int color) {
|
|
if (centerText == null) {
|
|
return;
|
|
}
|
|
centerText.setTextColor(color);
|
|
}
|
|
|
|
public boolean isActive() {
|
|
return active;
|
|
}
|
|
|
|
public void setText(String text) {
|
|
centerText.setText(text);
|
|
}
|
|
|
|
public void setBackground(Drawable drawable) {
|
|
background.setBackground(drawable);
|
|
}
|
|
|
|
public ViewGroup getSwipeBackground() {
|
|
return background;
|
|
}
|
|
|
|
public void setSlidingButtonBackground(Drawable drawable) {
|
|
background.setBackground(drawable);
|
|
}
|
|
|
|
public void setDisabledDrawable(Drawable drawable) {
|
|
disabledDrawable = drawable;
|
|
|
|
if (!active) {
|
|
swipeButtonInner.setImageDrawable(drawable);
|
|
}
|
|
}
|
|
|
|
public void setButtonBackground(Drawable buttonBackground) {
|
|
if (buttonBackground != null) {
|
|
swipeButtonInner.setBackground(buttonBackground);
|
|
}
|
|
}
|
|
|
|
public void setEnabledDrawable(Drawable drawable) {
|
|
enabledDrawable = drawable;
|
|
|
|
if (active) {
|
|
swipeButtonInner.setImageDrawable(drawable);
|
|
}
|
|
}
|
|
|
|
public void setOnStateChangeListener(OnStateChangeListener onStateChangeListener) {
|
|
this.onStateChangeListener = onStateChangeListener;
|
|
}
|
|
|
|
public void setOnActiveListener(OnActiveListener onActiveListener) {
|
|
this.onActiveListener = onActiveListener;
|
|
}
|
|
|
|
public void setInnerTextPadding(int left, int top, int right, int bottom) {
|
|
centerText.setPadding(left, top, right, bottom);
|
|
}
|
|
|
|
public void setSwipeButtonPadding(int left, int top, int right, int bottom) {
|
|
swipeButtonInner.setPadding(left, top, right, bottom);
|
|
}
|
|
|
|
public void setHasActivationState(boolean hasActivationState) {
|
|
this.hasActivationState = hasActivationState;
|
|
}
|
|
|
|
private void init(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
|
|
hasActivationState = true;
|
|
|
|
background = new RelativeLayout(context);
|
|
|
|
LayoutParams layoutParamsView = new LayoutParams(
|
|
ViewGroup.LayoutParams.MATCH_PARENT,
|
|
ViewGroup.LayoutParams.WRAP_CONTENT);
|
|
|
|
layoutParamsView.addRule(RelativeLayout.CENTER_IN_PARENT, RelativeLayout.TRUE);
|
|
|
|
addView(background, layoutParamsView);
|
|
|
|
final TextView centerText = new TextView(context);
|
|
this.centerText = centerText;
|
|
centerText.setGravity(Gravity.CENTER);
|
|
|
|
LayoutParams layoutParams = new LayoutParams(
|
|
ViewGroup.LayoutParams.WRAP_CONTENT,
|
|
ViewGroup.LayoutParams.WRAP_CONTENT);
|
|
|
|
layoutParams.addRule(RelativeLayout.CENTER_IN_PARENT, RelativeLayout.TRUE);
|
|
|
|
background.addView(centerText, layoutParams);
|
|
|
|
final ImageView swipeButton = new ImageView(context);
|
|
this.swipeButtonInner = swipeButton;
|
|
|
|
if (attrs != null && defStyleAttr == -1 && defStyleRes == -1) {
|
|
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.SwipeButton,
|
|
defStyleAttr, defStyleRes);
|
|
|
|
collapsedWidth = (int) typedArray.getDimension(R.styleable.SwipeButton_button_image_width,
|
|
ViewGroup.LayoutParams.WRAP_CONTENT);
|
|
collapsedHeight = (int) typedArray.getDimension(R.styleable.SwipeButton_button_image_height,
|
|
ViewGroup.LayoutParams.WRAP_CONTENT);
|
|
trailEnabled = typedArray.getBoolean(R.styleable.SwipeButton_button_trail_enabled,
|
|
false);
|
|
Drawable trailingDrawable = typedArray.getDrawable(R.styleable.SwipeButton_button_trail_drawable);
|
|
|
|
Drawable backgroundDrawable = typedArray.getDrawable(R.styleable.SwipeButton_inner_text_background);
|
|
|
|
if (backgroundDrawable != null) {
|
|
background.setBackground(backgroundDrawable);
|
|
} else {
|
|
background.setBackground(ContextCompat.getDrawable(context, R.drawable.shape_rounded_edit));
|
|
}
|
|
|
|
if (trailEnabled) {
|
|
layer = new LinearLayout(context);
|
|
|
|
if (trailingDrawable != null) {
|
|
layer.setBackground(trailingDrawable);
|
|
} else {
|
|
layer.setBackground(typedArray.getDrawable(R.styleable.SwipeButton_button_background));
|
|
}
|
|
|
|
layer.setGravity(Gravity.START);
|
|
layer.setVisibility(View.GONE);
|
|
background.addView(layer, layoutParamsView);
|
|
}
|
|
|
|
centerText.setText(typedArray.getText(R.styleable.SwipeButton_inner_text));
|
|
centerText.setTextColor(typedArray.getColor(R.styleable.SwipeButton_inner_text_color,
|
|
Color.WHITE));
|
|
|
|
float textSize = DimentionUtils.convertPixelsToSp(
|
|
typedArray.getDimension(R.styleable.SwipeButton_inner_text_size, 0), context);
|
|
|
|
if (textSize != 0) {
|
|
centerText.setTextSize(textSize);
|
|
} else {
|
|
centerText.setTextSize(12);
|
|
}
|
|
|
|
disabledDrawable = typedArray.getDrawable(R.styleable.SwipeButton_button_image_disabled);
|
|
enabledDrawable = typedArray.getDrawable(R.styleable.SwipeButton_button_image_enabled);
|
|
float innerTextLeftPadding = typedArray.getDimension(
|
|
R.styleable.SwipeButton_inner_text_left_padding, 0);
|
|
float innerTextTopPadding = typedArray.getDimension(
|
|
R.styleable.SwipeButton_inner_text_top_padding, 0);
|
|
float innerTextRightPadding = typedArray.getDimension(
|
|
R.styleable.SwipeButton_inner_text_right_padding, 0);
|
|
float innerTextBottomPadding = typedArray.getDimension(
|
|
R.styleable.SwipeButton_inner_text_bottom_padding, 0);
|
|
|
|
int initialState = typedArray.getInt(R.styleable.SwipeButton_initial_state, DISABLED);
|
|
|
|
if (initialState == ENABLED) {
|
|
LayoutParams layoutParamsButton = new LayoutParams(
|
|
ViewGroup.LayoutParams.MATCH_PARENT,
|
|
ViewGroup.LayoutParams.WRAP_CONTENT);
|
|
|
|
layoutParamsButton.addRule(RelativeLayout.ALIGN_PARENT_LEFT, RelativeLayout.TRUE);
|
|
layoutParamsButton.addRule(RelativeLayout.CENTER_VERTICAL, RelativeLayout.TRUE);
|
|
|
|
swipeButton.setImageDrawable(enabledDrawable);
|
|
|
|
addView(swipeButton, layoutParamsButton);
|
|
|
|
active = true;
|
|
} else {
|
|
LayoutParams layoutParamsButton = new LayoutParams(collapsedWidth, collapsedHeight);
|
|
|
|
layoutParamsButton.addRule(RelativeLayout.ALIGN_PARENT_LEFT, RelativeLayout.TRUE);
|
|
layoutParamsButton.addRule(RelativeLayout.CENTER_VERTICAL, RelativeLayout.TRUE);
|
|
|
|
swipeButton.setImageDrawable(disabledDrawable);
|
|
|
|
addView(swipeButton, layoutParamsButton);
|
|
|
|
active = false;
|
|
}
|
|
|
|
centerText.setPadding((int) innerTextLeftPadding,
|
|
(int) innerTextTopPadding,
|
|
(int) innerTextRightPadding,
|
|
(int) innerTextBottomPadding);
|
|
|
|
Drawable buttonBackground = typedArray.getDrawable(R.styleable.SwipeButton_button_background);
|
|
|
|
if (buttonBackground != null) {
|
|
swipeButton.setBackground(buttonBackground);
|
|
} else {
|
|
swipeButton.setBackground(ContextCompat.getDrawable(context, R.drawable.shape_rounded_edit));
|
|
}
|
|
|
|
float buttonLeftPadding = typedArray.getDimension(
|
|
R.styleable.SwipeButton_button_left_padding, 0);
|
|
float buttonTopPadding = typedArray.getDimension(
|
|
R.styleable.SwipeButton_button_top_padding, 0);
|
|
float buttonRightPadding = typedArray.getDimension(
|
|
R.styleable.SwipeButton_button_right_padding, 0);
|
|
float buttonBottomPadding = typedArray.getDimension(
|
|
R.styleable.SwipeButton_button_bottom_padding, 0);
|
|
|
|
swipeButton.setPadding((int) buttonLeftPadding,
|
|
(int) buttonTopPadding,
|
|
(int) buttonRightPadding,
|
|
(int) buttonBottomPadding);
|
|
|
|
hasActivationState = typedArray.getBoolean(R.styleable.SwipeButton_has_activate_state, true);
|
|
|
|
typedArray.recycle();
|
|
}
|
|
|
|
setOnTouchListener(getButtonTouchListener());
|
|
}
|
|
|
|
private OnTouchListener getButtonTouchListener() {
|
|
return new OnTouchListener() {
|
|
@Override
|
|
public boolean onTouch(View v, MotionEvent event) {
|
|
switch (event.getAction()) {
|
|
case MotionEvent.ACTION_DOWN:
|
|
return !TouchUtils.isTouchOutsideInitialPosition(event, swipeButtonInner);
|
|
case MotionEvent.ACTION_MOVE:
|
|
if (initialX == 0) {
|
|
initialX = swipeButtonInner.getX();
|
|
}
|
|
|
|
if (event.getX() > swipeButtonInner.getWidth() / 2 &&
|
|
event.getX() + swipeButtonInner.getWidth() / 2 < getWidth()) {
|
|
swipeButtonInner.setX(event.getX() - swipeButtonInner.getWidth() / 2);
|
|
centerText.setAlpha(1 - 1.3f * (swipeButtonInner.getX() + swipeButtonInner.getWidth()) / getWidth());
|
|
setTrailingEffect();
|
|
}
|
|
|
|
if (event.getX() + swipeButtonInner.getWidth() / 2 > getWidth() &&
|
|
swipeButtonInner.getX() + swipeButtonInner.getWidth() / 2 < getWidth()) {
|
|
swipeButtonInner.setX(getWidth() - swipeButtonInner.getWidth());
|
|
}
|
|
|
|
if (event.getX() < swipeButtonInner.getWidth() / 2) {
|
|
swipeButtonInner.setX(0);
|
|
}
|
|
|
|
return true;
|
|
case MotionEvent.ACTION_UP:
|
|
if (active) {
|
|
collapseButton();
|
|
} else {
|
|
if (swipeButtonInner.getX() + swipeButtonInner.getWidth() > getWidth() * 0.9) {
|
|
if (hasActivationState) {
|
|
expandButton();
|
|
} else if (onActiveListener != null) {
|
|
onActiveListener.onActive();
|
|
moveButtonBack();
|
|
}
|
|
} else {
|
|
moveButtonBack();
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
};
|
|
}
|
|
|
|
private void expandButton() {
|
|
final ValueAnimator positionAnimator =
|
|
ValueAnimator.ofFloat(swipeButtonInner.getX(), 0);
|
|
positionAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
|
|
@Override
|
|
public void onAnimationUpdate(ValueAnimator animation) {
|
|
float x = (Float) positionAnimator.getAnimatedValue();
|
|
swipeButtonInner.setX(x);
|
|
}
|
|
});
|
|
|
|
|
|
final ValueAnimator widthAnimator = ValueAnimator.ofInt(
|
|
swipeButtonInner.getWidth(),
|
|
getWidth());
|
|
|
|
widthAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
|
|
@Override
|
|
public void onAnimationUpdate(ValueAnimator animation) {
|
|
ViewGroup.LayoutParams params = swipeButtonInner.getLayoutParams();
|
|
params.width = (Integer) widthAnimator.getAnimatedValue();
|
|
swipeButtonInner.setLayoutParams(params);
|
|
}
|
|
});
|
|
|
|
|
|
AnimatorSet animatorSet = new AnimatorSet();
|
|
animatorSet.addListener(new AnimatorListenerAdapter() {
|
|
@Override
|
|
public void onAnimationEnd(Animator animation) {
|
|
super.onAnimationEnd(animation);
|
|
|
|
active = true;
|
|
swipeButtonInner.setImageDrawable(enabledDrawable);
|
|
|
|
if (onStateChangeListener != null) {
|
|
onStateChangeListener.onStateChange(active);
|
|
}
|
|
|
|
if (onActiveListener != null) {
|
|
onActiveListener.onActive();
|
|
}
|
|
}
|
|
});
|
|
|
|
animatorSet.playTogether(positionAnimator, widthAnimator);
|
|
animatorSet.start();
|
|
}
|
|
|
|
private void moveButtonBack() {
|
|
final ValueAnimator positionAnimator =
|
|
ValueAnimator.ofFloat(swipeButtonInner.getX(), 0);
|
|
positionAnimator.setInterpolator(new AccelerateDecelerateInterpolator());
|
|
positionAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
|
|
@Override
|
|
public void onAnimationUpdate(ValueAnimator animation) {
|
|
float x = (Float) positionAnimator.getAnimatedValue();
|
|
swipeButtonInner.setX(x);
|
|
setTrailingEffect();
|
|
}
|
|
});
|
|
|
|
positionAnimator.addListener(new AnimatorListenerAdapter() {
|
|
@Override
|
|
public void onAnimationEnd(Animator animation) {
|
|
super.onAnimationEnd(animation);
|
|
if (layer != null) {
|
|
layer.setVisibility(View.GONE);
|
|
}
|
|
}
|
|
});
|
|
|
|
ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(
|
|
centerText, "alpha", 1);
|
|
|
|
positionAnimator.setDuration(200);
|
|
|
|
AnimatorSet animatorSet = new AnimatorSet();
|
|
animatorSet.playTogether(objectAnimator, positionAnimator);
|
|
animatorSet.start();
|
|
}
|
|
|
|
private void collapseButton() {
|
|
int finalWidth;
|
|
|
|
if (collapsedWidth == ViewGroup.LayoutParams.WRAP_CONTENT) {
|
|
finalWidth = swipeButtonInner.getHeight();
|
|
} else {
|
|
finalWidth = collapsedWidth;
|
|
}
|
|
|
|
final ValueAnimator widthAnimator = ValueAnimator.ofInt(swipeButtonInner.getWidth(), finalWidth);
|
|
|
|
widthAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
|
|
@Override
|
|
public void onAnimationUpdate(ValueAnimator animation) {
|
|
ViewGroup.LayoutParams params = swipeButtonInner.getLayoutParams();
|
|
params.width = (Integer) widthAnimator.getAnimatedValue();
|
|
swipeButtonInner.setLayoutParams(params);
|
|
setTrailingEffect();
|
|
}
|
|
});
|
|
|
|
widthAnimator.addListener(new AnimatorListenerAdapter() {
|
|
@Override
|
|
public void onAnimationEnd(Animator animation) {
|
|
super.onAnimationEnd(animation);
|
|
active = false;
|
|
swipeButtonInner.setImageDrawable(disabledDrawable);
|
|
if (onStateChangeListener != null) {
|
|
onStateChangeListener.onStateChange(active);
|
|
}
|
|
if (layer != null) {
|
|
layer.setVisibility(View.GONE);
|
|
}
|
|
}
|
|
});
|
|
|
|
ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(
|
|
centerText, "alpha", 1);
|
|
|
|
AnimatorSet animatorSet = new AnimatorSet();
|
|
|
|
animatorSet.playTogether(objectAnimator, widthAnimator);
|
|
animatorSet.start();
|
|
}
|
|
|
|
private void setTrailingEffect() {
|
|
if (trailEnabled) {
|
|
layer.setVisibility(View.VISIBLE);
|
|
layer.setLayoutParams(new LayoutParams(
|
|
(int) (swipeButtonInner.getX() + swipeButtonInner.getWidth() / 3), centerText.getHeight()));
|
|
}
|
|
}
|
|
|
|
public void toggleState() {
|
|
if (isActive()) {
|
|
collapseButton();
|
|
} else {
|
|
expandButton();
|
|
}
|
|
}
|
|
}
|