This is the code for the challenge solution I summaried and selected from previous posts
SunsetFragment.java
import android.animation.AnimatorSet;
import android.animation.ArgbEvaluator;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.content.res.Resources;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.content.ContextCompat;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.DecelerateInterpolator;
public class SunsetFragment extends Fragment {
private boolean mSunset;
private View mSceneView;
private View mSunView;
private View mSkyView;
private View mReflectionView;
private int mBlueSkyColor;
private int mSunsetSkyColor;
private int mNightSkyColor;
private int mHotSunColor;
private int mColdSunColor;
private int mSunsetSkyColorCurrent;
private int mNightSkyColorCurrent;
private float mSunYCurrent;
private float mReflectionYCurrent;
private AnimatorSet mSunriseAnimatorSet;
private AnimatorSet mSunsetAnimatorSet;
private String TAG ="Sunset";
public static final int DURATION = 3000;
public static SunsetFragment newInstance(){
return new SunsetFragment();
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
View view =inflater.inflate(R.layout.fragment_sunset,container,false);
mSceneView = view;
mSunView = view.findViewById(R.id.sun);
mReflectionView = view.findViewById(R.id.reflection);
mSkyView = view.findViewById(R.id.sky);
Resources resources = getResources();
mBlueSkyColor = resources.getColor(R.color.blue_sky );
mSunsetSkyColor= resources.getColor(R.color.sunset_sky);
mNightSkyColor = resources.getColor(R.color.night_sky );
mHotSunColor = ContextCompat.getColor(getActivity(), R.color.heat_sun);
mColdSunColor = ContextCompat.getColor(getActivity(), R.color.cold_sun);
mSunsetSkyColorCurrent = mBlueSkyColor;
mNightSkyColorCurrent = mSunsetSkyColor;
mSunset = true;
mSceneView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (mSunset) {
startSunsetAnimation();
if (mSunriseAnimatorSet != null) {
mSunriseAnimatorSet.end();
mSunriseAnimatorSet = null;
}
} else {
startSunriseAnimation();
if (mSunsetAnimatorSet != null) {
mSunsetAnimatorSet.end();
mSunsetAnimatorSet = null;
}
}
mSunset = !mSunset;
startSunHeatAnimation();
}
});
ViewTreeObserver observer = view.getViewTreeObserver();
observer.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
mSunYCurrent = mSunView.getTop();
mReflectionYCurrent = mReflectionView.getTop();
}
});
return view;
}
private void startSunsetAnimation(){
long duration = (long) (DURATION / (mSkyView.getHeight() - mSunView.getTop()) * (mSkyView.getHeight() - mSunYCurrent));
ObjectAnimator sunHeightAnimator = ObjectAnimator.ofFloat(mSunView, "y", mSunYCurrent, mSkyView.getHeight())
.setDuration(duration);
sunHeightAnimator.setInterpolator(new AccelerateInterpolator());
sunHeightAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
mSunYCurrent = (float) animation.getAnimatedValue();
}
});
ObjectAnimator reflectionHeightAnimator = ObjectAnimator.ofFloat(mReflectionView, "y", mReflectionYCurrent, -mReflectionView.getHeight())
.setDuration(duration);
reflectionHeightAnimator.setInterpolator(new AccelerateInterpolator());
reflectionHeightAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
mReflectionYCurrent = (float) animation.getAnimatedValue();
}
});
ObjectAnimator sunsetSkyAnimator = ObjectAnimator.ofObject(mSkyView, "backgroundColor", new ArgbEvaluator(), mSunsetSkyColorCurrent, mSunsetSkyColor)
.setDuration(duration);
sunsetSkyAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
mSunsetSkyColorCurrent = (int) animation.getAnimatedValue();
}
});
ObjectAnimator nightSkyAnimator = ObjectAnimator.ofObject(mSkyView, "backgroundColor",
new ArgbEvaluator(), mNightSkyColorCurrent, mNightSkyColor)
.setDuration(DURATION);
nightSkyAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
mNightSkyColorCurrent = (int) animation.getAnimatedValue();
}
});
mSunsetAnimatorSet = new AnimatorSet();
mSunsetAnimatorSet
.play(sunHeightAnimator)
.with(reflectionHeightAnimator)
.with(sunsetSkyAnimator)
.before(nightSkyAnimator);
mSunsetAnimatorSet.start();
}
private void startSunHeatAnimation() {
ObjectAnimator sunRayAnimator = ObjectAnimator.ofFloat(mSunView, "rotation",0,23)
.setDuration(500);
sunRayAnimator.setRepeatMode(ObjectAnimator.REVERSE);
sunRayAnimator.setRepeatCount(ObjectAnimator.INFINITE);
ObjectAnimator sunHeatAnimator = ObjectAnimator.ofInt(mSunView,"tint",mHotSunColor, mColdSunColor )
.setDuration(500);
sunHeatAnimator.setEvaluator(new ArgbEvaluator());
sunHeatAnimator.setRepeatMode(ObjectAnimator.REVERSE);
sunHeatAnimator.setRepeatCount(ObjectAnimator.INFINITE);
AnimatorSet animatorSet = new AnimatorSet();
animatorSet.play(sunRayAnimator).with(sunHeatAnimator);
animatorSet.start();
}
private void startSunriseAnimation(){
long duration = (long) (DURATION / (mSkyView.getHeight() - mSunView.getTop()) * (mSunYCurrent- mSunView.getTop()));
long nightDuration = (long)(DURATION*((double)(mSunsetSkyColor-mNightSkyColorCurrent)/(double)(mSunsetSkyColor-mNightSkyColor)));
ObjectAnimator sunHeightAnimator = ObjectAnimator.ofFloat(mSunView, "y", mSunYCurrent, mSunView.getTop())
.setDuration(duration);
sunHeightAnimator.setInterpolator(new DecelerateInterpolator());
sunHeightAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
mSunYCurrent = (float) animation.getAnimatedValue();
}
});
ObjectAnimator reflectionHeightAnimator = ObjectAnimator.ofFloat(mReflectionView, "y", mReflectionYCurrent, mReflectionView.getTop())
.setDuration(duration);
reflectionHeightAnimator.setInterpolator(new DecelerateInterpolator());
reflectionHeightAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
mReflectionYCurrent = (float) animation.getAnimatedValue();
}
});
ObjectAnimator daySkyAnimator = ObjectAnimator.ofObject(mSkyView, "backgroundColor", new ArgbEvaluator(), mSunsetSkyColorCurrent, mBlueSkyColor)
.setDuration(duration);
daySkyAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
mSunsetSkyColorCurrent = (int) animation.getAnimatedValue();
}
});
ObjectAnimator nightSkyAnimator = ObjectAnimator.ofObject(mSkyView, "backgroundColor", new ArgbEvaluator(), mNightSkyColorCurrent, mSunsetSkyColor)
.setDuration(nightDuration);
nightSkyAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
mNightSkyColorCurrent = (int) animation.getAnimatedValue();
}
});
mSunriseAnimatorSet = new AnimatorSet();
mSunriseAnimatorSet
.play(sunHeightAnimator)
.with(reflectionHeightAnimator)
.with(daySkyAnimator)
.after(nightSkyAnimator);
mSunriseAnimatorSet.start();
}
}
fragment_sunset.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="@+id/sky"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="0.61"
android:background="@color/blue_sky">
<ImageView
android:id="@+id/sun"
android:layout_width="180dp"
android:layout_height="180dp"
android:layout_gravity="center"
android:src="@drawable/ic_wb_sunny"/>
</FrameLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="0.39"
android:background="@color/sea">
<ImageView
android:id="@+id/reflection"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_gravity="center"
android:src="@drawable/sun"/>
</FrameLayout>
</LinearLayout>
ic_wb_sunny.xml
<vector
android:height="180dp"
android:tint="#fcfcb7"
android:viewportHeight="24.0"
android:viewportWidth="24.0"
android:width="180dp"
xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#FF000000"
android:pathData="M6.76,4.84l-1.8,-1.79 -1.41,1.41 1.79,1.79 1.42,-1.41zM4,10.5L1,10.5v2h3v-2zM13,0.55h-2L11,3.5h2L13,0.55zM20.45,4.46l-1.41,-1.41 -1.79,1.79 1.41,1.41 1.79,-1.79zM17.24,18.16l1.79,1.8 1.41,-1.41 -1.8,-1.79 -1.4,1.4zM20,10.5v2h3v-2h-3zM12,5.5c-3.31,0 -6,2.69 -6,6s2.69,6 6,6 6,-2.69 6,-6 -2.69,-6 -6,-6zM11,22.45h2L13,19.5h-2v2.95zM3.55,18.54l1.41,1.41 1.79,-1.8 -1.41,-1.41 -1.79,1.8z"/>
</vector>
colors.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorPrimary">#3F51B5</color>
<color name="colorPrimaryDark">#303F9F</color>
<color name="colorAccent">#FF4081</color>
<color name="bright_sun"> #fcfcb7 </color>
<color name="blue_sky" > #1e7ac7 </color>
<color name="sunset_sky"> #ec8100 </color>
<color name="night_sky" > #05192e </color>
<color name="sea" > #224869 </color>
<color name="heat_sun">#FFfcfcb7</color>
<color name="cold_sun">#FFff0000</color>
</resources>
sun.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android = "http://schemas.android.com/apk/res/android"
android:shape="oval">
<solid android:color="@color/bright_sun"/>
</shape>
Everything else worked fine expect I counldn’t find the way to altering the color of the sun and since I introduced ic_wb_sunny the method will be different than the one give by the book (if there is a method at all).I appreciate if anyone can help me with that.