package com.eleks.tesla.mainApp;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.support.wearable.view.CircledImageView;
import android.support.wearable.view.WatchViewStub;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.OvershootInterpolator;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import com.eleks.tesla.R;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class MainActivity extends CommunicationActivity implements View.OnClickListener {
public static final int ANIMATION_DURATION = 500;
public static final float MAX_SCALE = 1f;
public static final float MIN_SCALE = 0f;
private final String LOG_TAG = MainActivity.class.getSimpleName();
private final int MAX_BUTTONS_COUNT = 4;
private View[] mButtons; // right top left bottom
protected ImageView[] mImages; // right top left bottom
protected CircledImageView[] mCircles; // right top left bottom
protected ImageView[] mRipples;
private MarginSetter[] mMarginSetter;
private int mScreenWidth;
private int mButtonSideSize;
private int mButtonMargin;
protected int mImageSideSize;
private AnimatorSet mOpenAnimatorSet;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final WatchViewStub stub = (WatchViewStub) findViewById(R.id.watch_view_stub);
stub.setOnLayoutInflatedListener(new WatchViewStub.OnLayoutInflatedListener() {
@Override
public void onLayoutInflated(WatchViewStub stub) {
initFields();
setUpUI();
setWidgetsPosition(stub.getMeasuredWidth());
playStartAnimation();
}
});
}
protected void setUpUI() {
mCircles[0].setCircleColor(getResources().getColor(R.color.category_charge));
mRipples[0].setImageResource(R.drawable.fake_ripple_charge);
mImages[0].setImageResource(R.drawable.category_charge);
mCircles[1].setCircleColor(getResources().getColor(R.color.category_location));
mRipples[1].setImageResource(R.drawable.fake_ripple_location);
mImages[1].setImageResource(R.drawable.category_location);
mCircles[2].setCircleColor(getResources().getColor(R.color.category_condition));
mRipples[2].setImageResource(R.drawable.fake_ripple_condition);
mImages[2].setImageResource(R.drawable.category_condition);
mCircles[3].setCircleColor(getResources().getColor(R.color.category_drive));
mRipples[3].setImageResource(R.drawable.fake_ripple_drive);
mImages[3].setImageResource(R.drawable.category_drive);
}
protected void initFields() {
mRipples = new ImageView[MAX_BUTTONS_COUNT];
mRipples[0] = (ImageView) findViewById(R.id.ripple_right);
mRipples[1] = (ImageView) findViewById(R.id.ripple_top);
mRipples[2] = (ImageView) findViewById(R.id.ripple_left);
mRipples[3] = (ImageView) findViewById(R.id.ripple_bottom);
mButtons = new View[MAX_BUTTONS_COUNT];
mButtons[0] = findViewById(R.id.segment_right);
mButtons[0].setOnClickListener(this);
mButtons[0].setOnTouchListener(new RippleTouchListener(mRipples[0]));
mButtons[1] = findViewById(R.id.segment_top);
mButtons[1].setOnClickListener(this);
mButtons[1].setOnTouchListener(new RippleTouchListener(mRipples[1]));
mButtons[2] = findViewById(R.id.segment_left);
mButtons[2].setOnClickListener(this);
mButtons[2].setOnTouchListener(new RippleTouchListener(mRipples[2]));
mButtons[3] = findViewById(R.id.segment_bottom);
mButtons[3].setOnClickListener(this);
mButtons[3].setOnTouchListener(new RippleTouchListener(mRipples[3]));
mImages = new ImageView[MAX_BUTTONS_COUNT];
mImages[0] = (ImageView) findViewById(R.id.right_image_1);
mImages[1] = (ImageView) findViewById(R.id.top_image_1);
mImages[2] = (ImageView) findViewById(R.id.left_image_1);
mImages[3] = (ImageView) findViewById(R.id.bottom_image_1);
mCircles = new CircledImageView[MAX_BUTTONS_COUNT];
mCircles[0] = (CircledImageView) findViewById(R.id.right_image_background);
mCircles[1] = (CircledImageView) findViewById(R.id.top_image_background);
mCircles[2] = (CircledImageView) findViewById(R.id.left_image_background);
mCircles[3] = (CircledImageView) findViewById(R.id.bottom_image_background);
mMarginSetter = new MarginSetter[]{
new MarginSetter() {
@Override
public void setMargin(RelativeLayout.LayoutParams params, int value) {
params.setMargins(0, 0, value, 0);
}
},
new MarginSetter() {
@Override
public void setMargin(RelativeLayout.LayoutParams params, int value) {
params.setMargins(0, value, 0, 0);
}
},
new MarginSetter() {
@Override
public void setMargin(RelativeLayout.LayoutParams params, int value) {
params.setMargins(value, 0, 0, 0);
}
},
new MarginSetter() {
@Override
public void setMargin(RelativeLayout.LayoutParams params, int value) {
params.setMargins(0, 0, 0, value);
}
}
};
}
protected void setWidgetsPosition(int width) {
mScreenWidth = width;
mButtonSideSize = width / 4;
mImageSideSize = width / 6;
mButtonMargin = (int) (((float) width) / 32 * 3);
for (int i = 0; i < MAX_BUTTONS_COUNT; i++) {
if (mCircles[i] != null) {
mCircles[i].setCircleRadius(mButtonSideSize / 2);
}
if (mImages[i] != null) {
FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) mImages[i].getLayoutParams();
params.width = mImageSideSize;
params.height = mImageSideSize;
mImages[i].setLayoutParams(params);
}
if (mButtons[i] != null) {
RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) mButtons[i].getLayoutParams();
params.width = mButtonSideSize;
params.height = mButtonSideSize;
mMarginSetter[i].setMargin(params, mButtonMargin);
mButtons[i].setLayoutParams(params);
mRipples[i].setLayoutParams(params);
mButtons[i].setVisibility(View.VISIBLE);
}
}
}
@Override
protected void onResume() {
super.onResume();
if (mOpenAnimatorSet != null && !mOpenAnimatorSet.isRunning()) {
mOpenAnimatorSet.start();
restoreViews();
}
}
@Override
public void onClick(View v) {
AnimatorListenerAdapter animatorListenerAdapter = null;
switch (v.getId()) {
case R.id.segment_top:
animatorListenerAdapter = new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
startActivity(new Intent(MainActivity.this, LocationActivity.class));
overridePendingTransition(R.animator.zoom_enetr, R.animator.empty_animation);
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
hideViews();
}
}, 1000);
}
};
playCloseAnimationToLocation(animatorListenerAdapter);
break;
case R.id.segment_left:
animatorListenerAdapter = new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
openSetValueActivity(SetValueActivity.SELECTOR_TYPE_CONDITIONING);
}
};
playCloseAnimation(animatorListenerAdapter);
break;
case R.id.segment_right:
animatorListenerAdapter = new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
openSetValueActivity(SetValueActivity.SELECTOR_TYPE_CHARGING);
}
};
playCloseAnimation(animatorListenerAdapter);
break;
case R.id.segment_bottom:
animatorListenerAdapter = new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
Intent intent = new Intent(MainActivity.this, DriveActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
startActivity(intent);
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
hideViews();
}
}, 1000);
}
};
playCloseAnimationToDrive(animatorListenerAdapter);
break;
}
}
protected void playStartAnimation() {
List<Animator> animations = new ArrayList<>();
ValueAnimator startSlideAnim = ValueAnimator.ofFloat(0, 1);
startSlideAnim.setDuration(ANIMATION_DURATION);
startSlideAnim.setInterpolator(new OvershootInterpolator());
startSlideAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
float animatedValue = (float) animation.getAnimatedValue();
float reversAnimatorValue = 1f - animatedValue;
float maxCurve = mScreenWidth / 5;
if (mButtons[0] != null) {
mButtons[0].setTranslationX(-reversAnimatorValue * ((mScreenWidth - mButtonSideSize) / 2 - mButtonMargin));
mButtons[0].setTranslationY((float) (-maxCurve * Math.sin(Math.PI * animatedValue)));
}
if (mButtons[1] != null) {
mButtons[1].setTranslationX((float) (-maxCurve * Math.sin(Math.PI * animatedValue)));
mButtons[1].setTranslationY(reversAnimatorValue * ((mScreenWidth - mButtonSideSize) / 2 - mButtonMargin));
}
if (mButtons[2] != null) {
mButtons[2].setTranslationX(reversAnimatorValue * ((mScreenWidth - mButtonSideSize) / 2 - mButtonMargin));
mButtons[2].setTranslationY((float) (maxCurve * Math.sin(Math.PI * animatedValue)));
}
if (mButtons[3] != null) {
mButtons[3].setTranslationX((float) (maxCurve * Math.sin(Math.PI * animatedValue)));
mButtons[3].setTranslationY(-reversAnimatorValue * ((mScreenWidth - mButtonSideSize) / 2 - mButtonMargin));
}
}
});
animations.add(startSlideAnim);
for (int i = 0; i < MAX_BUTTONS_COUNT; i++) {
if (mButtons[i] == null) {
continue;
}
ObjectAnimator scaleDownXImage = ObjectAnimator.ofFloat(mButtons[i], "scaleX", MIN_SCALE, MAX_SCALE);
scaleDownXImage.setDuration(ANIMATION_DURATION);
scaleDownXImage.setInterpolator(new OvershootInterpolator());
animations.add(scaleDownXImage);
ObjectAnimator scaleDownYImage = ObjectAnimator.ofFloat(mButtons[i], "scaleY", MIN_SCALE, MAX_SCALE);
scaleDownYImage.setDuration(ANIMATION_DURATION);
scaleDownYImage.setInterpolator(new OvershootInterpolator());
animations.add(scaleDownYImage);
}
mOpenAnimatorSet = new AnimatorSet();
mOpenAnimatorSet.playTogether(animations);
mOpenAnimatorSet.start();
}
private void restoreViews() {
if (mButtons[3] != null) {
mImages[3].setAlpha(1f);
mImages[3].setScaleX(1f);
mImages[3].setScaleY(1f);
mCircles[3].setAlpha(1f);
}
if (mButtons[1] != null) {
mImages[1].setAlpha(1f);
mImages[1].setScaleX(1f);
mImages[1].setScaleY(1f);
mCircles[1].setAlpha(1f);
}
}
private void hideViews() {
if (mButtons[3] != null) {
mImages[3].setAlpha(0f);
mCircles[3].setAlpha(0f);
}
if (mButtons[1] != null) {
mImages[1].setAlpha(0f);
mCircles[1].setAlpha(0f);
}
}
protected void playCloseAnimation(AnimatorListenerAdapter animatorListenerAdapter) {
List<Animator> animations = new ArrayList<>();
ValueAnimator closeSlideAnim = createCloseSlideAnimator(mButtons);
animations.add(closeSlideAnim);
addScaleDownAnimations(animations, mButtons);
AnimatorSet animatorSet = new AnimatorSet();
animatorSet.playTogether(animations);
animatorSet.addListener(animatorListenerAdapter);
animatorSet.start();
}
private void addScaleDownAnimations(List<Animator> animations, View[] buttons) {
for (int i = 0; i < MAX_BUTTONS_COUNT; i++) {
if (buttons[i] == null) {
continue;
}
addScaleDownAnimation(animations, buttons[i]);
}
}
private void addScaleDownAnimation(List<Animator> animations, View button) {
ObjectAnimator scaleDownXImage = ObjectAnimator.ofFloat(button, "scaleX", MAX_SCALE, MIN_SCALE);
scaleDownXImage.setDuration(ANIMATION_DURATION);
scaleDownXImage.setInterpolator(new AccelerateInterpolator());
animations.add(scaleDownXImage);
ObjectAnimator scaleDownYImage = ObjectAnimator.ofFloat(button, "scaleY", MAX_SCALE, MIN_SCALE);
scaleDownYImage.setDuration(ANIMATION_DURATION);
scaleDownYImage.setInterpolator(new AccelerateInterpolator());
animations.add(scaleDownYImage);
}
private ValueAnimator createCloseSlideAnimator(final View[] buttons) {
ValueAnimator startSlideAnim = ValueAnimator.ofFloat(0, 1);
startSlideAnim.setDuration(ANIMATION_DURATION);
startSlideAnim.setInterpolator(new AccelerateInterpolator());
startSlideAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
float animatedValue = (float) animation.getAnimatedValue();
float maxCurve = mScreenWidth / 5;
if (buttons[0] != null) {
buttons[0].setTranslationX(-animatedValue * ((mScreenWidth - mButtonSideSize) / 2 - mButtonMargin));
buttons[0].setTranslationY((float) (maxCurve * Math.sin(Math.PI * animatedValue)));
}
if (buttons[1] != null) {
buttons[1].setTranslationX((float) (maxCurve * Math.sin(Math.PI * animatedValue)));
buttons[1].setTranslationY(animatedValue * ((mScreenWidth - mButtonSideSize) / 2 - mButtonMargin));
}
if (buttons[2] != null) {
buttons[2].setTranslationX(animatedValue * ((mScreenWidth - mButtonSideSize) / 2 - mButtonMargin));
buttons[2].setTranslationY((float) (-maxCurve * Math.sin(Math.PI * animatedValue)));
}
if (buttons[3] != null) {
buttons[3].setTranslationX((float) (-maxCurve * Math.sin(Math.PI * animatedValue)));
buttons[3].setTranslationY(-animatedValue * ((mScreenWidth - mButtonSideSize) / 2 - mButtonMargin));
}
}
});
return startSlideAnim;
}
protected void playCloseAnimationToDrive(AnimatorListenerAdapter animatorListenerAdapter) {
List<Animator> animations = new ArrayList<>();
ValueAnimator closeSlideAnim = createCloseSlideAnimator(mButtons);
animations.add(closeSlideAnim);
View[] buttonsToAnimate = Arrays.copyOf(mButtons, mButtons.length);
buttonsToAnimate[3] = null;
addScaleDownAnimations(animations, buttonsToAnimate);
ObjectAnimator circleAlphaAnim = ObjectAnimator.ofFloat(mCircles[3], "alpha", 1f, 0f);
circleAlphaAnim.setDuration(ANIMATION_DURATION);
circleAlphaAnim.setInterpolator(new AccelerateInterpolator());
animations.add(circleAlphaAnim);
ObjectAnimator imageAlphaAnim = ObjectAnimator.ofFloat(mImages[3], "alpha", 1f, 0.5f);
imageAlphaAnim.setDuration(ANIMATION_DURATION);
imageAlphaAnim.setInterpolator(new AccelerateInterpolator());
animations.add(imageAlphaAnim);
ObjectAnimator scaleDownXImage = ObjectAnimator.ofFloat(mImages[3], "scaleX", MAX_SCALE, 0.8f);
scaleDownXImage.setDuration(ANIMATION_DURATION);
scaleDownXImage.setInterpolator(new AccelerateInterpolator());
animations.add(scaleDownXImage);
ObjectAnimator scaleDownYImage = ObjectAnimator.ofFloat(mImages[3], "scaleY", MAX_SCALE, 0.8f);
scaleDownYImage.setDuration(ANIMATION_DURATION);
scaleDownYImage.setInterpolator(new AccelerateInterpolator());
animations.add(scaleDownYImage);
AnimatorSet animatorSet = new AnimatorSet();
animatorSet.playTogether(animations);
animatorSet.addListener(animatorListenerAdapter);
animatorSet.start();
}
protected void playCloseAnimationToLocation(AnimatorListenerAdapter animatorListenerAdapter) {
List<Animator> animations = new ArrayList<>();
ValueAnimator closeSlideAnim = createCloseSlideAnimator(mButtons);
animations.add(closeSlideAnim);
View[] buttonsToAnimate = Arrays.copyOf(mButtons, mButtons.length);
buttonsToAnimate[1] = null;
addScaleDownAnimations(animations, buttonsToAnimate);
ObjectAnimator circleAlphaAnim = ObjectAnimator.ofFloat(mCircles[1], "alpha", 1f, 0f);
circleAlphaAnim.setDuration(ANIMATION_DURATION);
circleAlphaAnim.setInterpolator(new AccelerateInterpolator());
animations.add(circleAlphaAnim);
ObjectAnimator imageAlphaAnim = ObjectAnimator.ofFloat(mImages[1], "alpha", 1f, 0f);
imageAlphaAnim.setDuration(ANIMATION_DURATION);
imageAlphaAnim.setInterpolator(new AccelerateInterpolator());
animations.add(imageAlphaAnim);
ObjectAnimator scaleDownXImage = ObjectAnimator.ofFloat(mImages[1], "scaleX", MAX_SCALE, 0.8f);
scaleDownXImage.setDuration(ANIMATION_DURATION);
scaleDownXImage.setInterpolator(new AccelerateInterpolator());
animations.add(scaleDownXImage);
ObjectAnimator scaleDownYImage = ObjectAnimator.ofFloat(mImages[1], "scaleY", MAX_SCALE, 0.8f);
scaleDownYImage.setDuration(ANIMATION_DURATION);
scaleDownYImage.setInterpolator(new AccelerateInterpolator());
animations.add(scaleDownYImage);
AnimatorSet animatorSet = new AnimatorSet();
animatorSet.playTogether(animations);
animatorSet.addListener(animatorListenerAdapter);
animatorSet.start();
}
private void openSetValueActivity(int actionSelector) {
Intent intent = new Intent(this, SetValueActivity.class);
intent.putExtra(SetValueActivity.SELECTOR_TYPE, actionSelector);
startActivity(intent);
overridePendingTransition(R.animator.zoom_enetr, R.animator.empty_animation);
}
protected void startRippleAnimation(final View view) {
AnimatorSet rippleAnim = new AnimatorSet();
ObjectAnimator scaleX = ObjectAnimator.ofFloat(view, "scaleX", 1f, 10f);
ObjectAnimator scaleY = ObjectAnimator.ofFloat(view, "scaleY", 1f, 10f);
rippleAnim.playTogether(scaleX, scaleY);
rippleAnim.setInterpolator(new AccelerateInterpolator());
rippleAnim.setDuration(Math.round(ANIMATION_DURATION * 0.7f));
rippleAnim.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
view.setVisibility(View.VISIBLE);
}
@Override
public void onAnimationEnd(Animator animation) {
view.setScaleX(1f);
view.setScaleY(1f);
view.setVisibility(View.INVISIBLE);
}
@Override
public void onAnimationCancel(Animator animation) {
}
@Override
public void onAnimationRepeat(Animator animation) {
}
});
rippleAnim.start();
}
protected class RippleTouchListener implements View.OnTouchListener {
private View view;
public RippleTouchListener(View view) {
this.view = view;
}
@Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
startRippleAnimation(view);
}
return false;
}
}
interface MarginSetter {
public void setMargin(RelativeLayout.LayoutParams params, int value);
}
}