Browse Source

[메인][New] 등장 에니메이션 적용 시작

hyodong.min 7 years ago
parent
commit
a2bf5f9de8

+ 24 - 5
app/src/main/java/kr/co/zumo/app/lifeplus/helper/ActionBarHelper.java

@@ -1,5 +1,7 @@
 package kr.co.zumo.app.lifeplus.helper;
 
+import android.animation.Animator;
+import android.animation.ObjectAnimator;
 import android.app.Activity;
 import android.content.Context;
 import android.support.annotation.StringRes;
@@ -16,6 +18,7 @@ import android.widget.RadioButton;
 import java.util.ArrayList;
 
 import kr.co.zumo.app.R;
+import kr.co.zumo.app.lifeplus.supervisor.AnimatorManager;
 import kr.co.zumo.app.lifeplus.util.ResourceUtil;
 import kr.co.zumo.app.lifeplus.view.CustomHeaderBehavior;
 
@@ -215,6 +218,21 @@ public class ActionBarHelper extends Helper {
     navigationBar.setVisibleBookmark(isVisible);
   }
 
+  public void animate() {
+    toolbar.setTranslationY(-ResourceUtil.getDimension(R.dimen.action_bar_height_with_status_bar_height));
+
+    ObjectAnimator textViewAnimator = ObjectAnimator.ofFloat(toolbar, "translationY", 0f);
+    textViewAnimator.setDuration(900);
+    textViewAnimator.addListener(new AnimatorManager.SimpleListener() {
+      @Override
+      public void onAnimationCancel(Animator animation) {
+        toolbar.setTranslationY(0f);
+      }
+    });
+
+    AnimatorManager.getInstance().add(textViewAnimator);
+  }
+
   /***********************************
    * private
    ***********************************/
@@ -224,7 +242,7 @@ public class ActionBarHelper extends Helper {
      * 2 툴바 배경 없음, 스크롤/논스크롤
      */
 
-    AppBarLayout.LayoutParams params = (AppBarLayout.LayoutParams) toolbar.getLayoutParams();
+    AppBarLayout.LayoutParams toolbarLayoutParams = (AppBarLayout.LayoutParams) toolbar.getLayoutParams();
     CoordinatorLayout.LayoutParams appBarLayoutParams = (CoordinatorLayout.LayoutParams) appBarLayout.getLayoutParams();
     CoordinatorLayout.LayoutParams containerLayoutParams = (CoordinatorLayout.LayoutParams) container.getLayoutParams();
 
@@ -233,16 +251,17 @@ public class ActionBarHelper extends Helper {
     }
     else if (isScrollable) {
       // 스크롤 플래그 설정
-      params.setScrollFlags(APP_BAR_LAYOUT_SCROLL_PARAM);
+      toolbarLayoutParams.setScrollFlags(APP_BAR_LAYOUT_SCROLL_PARAM);
       // 스테이터스 바 위로 스크롤 시키기위해서 높이 조절
-      params.height = ResourceUtil.getDimension(R.dimen.action_bar_height_with_status_bar_height);
+      toolbarLayoutParams.height = ResourceUtil.getDimension(R.dimen.action_bar_height_with_status_bar_height);
 
       appBarLayoutParams.setBehavior(new CustomHeaderBehavior());
       containerLayoutParams.setBehavior(null);
     }
     else {
-      params.setScrollFlags(0);
-      params.height = ResourceUtil.getDimension(R.dimen.action_bar_height);
+      toolbarLayoutParams.setScrollFlags(0);
+      // 스테이터스바 아래 ui 가 눌리지 않아서 높이를 조절
+      toolbarLayoutParams.height = ResourceUtil.getDimension(R.dimen.action_bar_height);
 
       appBarLayoutParams.setBehavior(null);
       containerLayoutParams.setBehavior(null);

+ 128 - 0
app/src/main/java/kr/co/zumo/app/lifeplus/supervisor/AnimatorManager.java

@@ -0,0 +1,128 @@
+/*
+ * COPYRIGHT (c) 2018 All rights reserved by HANWHA LIFE.
+ */
+package kr.co.zumo.app.lifeplus.supervisor;
+
+import android.animation.Animator;
+import android.animation.ObjectAnimator;
+import android.util.Log;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * AnimatorManager
+ * <pre>
+ * </pre>
+ *
+ * @author 민효동
+ * @version 1.0
+ * @history 민효동   [2018-12-09]   [최초 작성]
+ * @since 2018-12-09
+ */
+public class AnimatorManager {
+  private static AnimatorManager ourInstance = new AnimatorManager();
+  private boolean isCompleted = false;
+
+  public static AnimatorManager getInstance() {
+    return ourInstance;
+  }
+
+  private AnimatorManager() {
+  }
+
+  private boolean isStarted = false;
+
+  private List<ObjectAnimator> animatorList = new ArrayList<>();
+
+  public void add(ObjectAnimator animator) {
+    if (isCompleted) {
+      Log.i("APP# AnimatorManager | add", "|" + "completed.....");
+      return;
+    }
+    Log.i("APP# AnimatorManager | add", "|" + "animator: ---> " + animator.getTarget());
+    if (isStarted) {
+      startAnimation(animator);
+    }
+    animatorList.add(animator);
+  }
+
+  public void clear() {
+    for (ObjectAnimator animator : animatorList) {
+      animator.cancel();
+    }
+    animatorList = new ArrayList<>();
+    isStarted = false;
+    isCompleted = false;
+    Log.w("APP# AnimatorManager | clear", "|" + "___________________________ cleared");
+  }
+
+  public void start() {
+    isStarted = true;
+    for (ObjectAnimator animator : animatorList) {
+      startAnimation(animator);
+    }
+  }
+
+  private int countOfAnimator = 0;
+
+  private void startAnimation(ObjectAnimator animator) {
+    ++countOfAnimator;
+    animator.start();
+    animator.addListener(new Animator.AnimatorListener() {
+      @Override
+      public void onAnimationStart(Animator animation) {
+      }
+
+      @Override
+      public void onAnimationEnd(Animator animation) {
+        if (--countOfAnimator < 1) {
+          // completed
+          isCompleted = true;
+        }
+      }
+
+      @Override
+      public void onAnimationCancel(Animator animation) {
+
+      }
+
+      @Override
+      public void onAnimationRepeat(Animator animation) {
+
+      }
+    });
+  }
+
+  public void dispose() {
+    clear();
+    animatorList = null;
+  }
+
+  public boolean isCompleted() {
+    return isCompleted;
+  }
+
+  public static class SimpleListener implements Animator.AnimatorListener {
+
+    @Override
+    public void onAnimationStart(Animator animation) {
+
+    }
+
+    @Override
+    public void onAnimationEnd(Animator animation) {
+
+    }
+
+    @Override
+    public void onAnimationCancel(Animator animation) {
+
+    }
+
+    @Override
+    public void onAnimationRepeat(Animator animation) {
+
+    }
+  }
+}

+ 36 - 2
app/src/main/java/kr/co/zumo/app/lifeplus/view/screen/main/MainContentsCategoryHolder.java

@@ -3,6 +3,8 @@
  */
 package kr.co.zumo.app.lifeplus.view.screen.main;
 
+import android.animation.Animator;
+import android.animation.ObjectAnimator;
 import android.content.Context;
 import android.os.Parcelable;
 import android.support.v7.widget.LinearLayoutManager;
@@ -12,6 +14,7 @@ import android.widget.TextView;
 
 import kr.co.zumo.app.R;
 import kr.co.zumo.app.lifeplus.bean.api.MainContentsBean;
+import kr.co.zumo.app.lifeplus.supervisor.AnimatorManager;
 import kr.co.zumo.app.lifeplus.util.ResourceUtil;
 import kr.co.zumo.app.lifeplus.view.Event;
 import kr.co.zumo.app.lifeplus.view.IEventListener;
@@ -60,10 +63,41 @@ public class MainContentsCategoryHolder extends MainContentsHolder {
 
     TextView textView = itemView.findViewById(R.id.text_title);
     textView.setText(bean.getCategoryName());
-
     recyclerView = itemView.findViewById(R.id.recycler_view_category);
 
-    recyclerView.setLayoutManager(new LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false){
+    // 첫 번째 카테고리만 에니메이션 적용
+    if (this.index == 1) {
+
+      textView.setTranslationY(100f);
+
+      ObjectAnimator textViewAnimator = ObjectAnimator.ofFloat(textView, "translationY", 0f);
+      textViewAnimator.setStartDelay(1100);
+      textViewAnimator.setDuration(500);
+      textViewAnimator.addListener(new AnimatorManager.SimpleListener() {
+        @Override
+        public void onAnimationCancel(Animator animation) {
+          textView.setTranslationY(0f);
+        }
+      });
+
+      AnimatorManager.getInstance().add(textViewAnimator);
+
+      recyclerView.setTranslationY(ResourceUtil.dpToPx(330));
+
+      ObjectAnimator viewAnimator = ObjectAnimator.ofFloat(recyclerView, "translationY", 0f);
+      viewAnimator.setDuration(600);
+      viewAnimator.addListener(new AnimatorManager.SimpleListener() {
+        @Override
+        public void onAnimationCancel(Animator animation) {
+          recyclerView.setTranslationY(0f);
+        }
+      });
+
+      AnimatorManager.getInstance().add(viewAnimator);
+    }
+
+
+    recyclerView.setLayoutManager(new LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false) {
       @Override
       protected int getExtraLayoutSpace(RecyclerView.State state) {
         return 1000;

+ 83 - 0
app/src/main/java/kr/co/zumo/app/lifeplus/view/screen/main/MainContentsWeatherHolder.java

@@ -3,15 +3,22 @@
  */
 package kr.co.zumo.app.lifeplus.view.screen.main;
 
+import android.animation.Animator;
+import android.animation.ObjectAnimator;
 import android.content.Context;
 import android.support.v7.widget.RecyclerView;
 import android.util.Log;
 import android.view.View;
 import android.view.ViewGroup;
+import android.view.animation.Animation;
+import android.view.animation.LinearInterpolator;
+import android.widget.ImageView;
+import android.widget.TextView;
 
 import kr.co.zumo.app.R;
 import kr.co.zumo.app.lifeplus.bean.api.MainContentsBean;
 import kr.co.zumo.app.lifeplus.model.SuperModel;
+import kr.co.zumo.app.lifeplus.supervisor.AnimatorManager;
 import kr.co.zumo.app.lifeplus.util.ResourceUtil;
 import kr.co.zumo.app.lifeplus.view.Event;
 import kr.co.zumo.app.lifeplus.view.IEventListener;
@@ -67,9 +74,19 @@ public class MainContentsWeatherHolder extends MainContentsHolder /*implements V
   private float initWeatherY;
   private ViewGroup weather;
 
+  private TextView textTopView;
+  private TextView textBottomView;
+  private ImageView weahterView;
+  private ViewGroup layoutWeatherBottom;
+
   @Override
   public void init(int index, MainContentsBean bean, IEventListener listener) {
     weather = itemView.findViewById(R.id.layout_container_weather);
+    textTopView = itemView.findViewById(R.id.text_weather_top);
+    textBottomView = itemView.findViewById(R.id.text_weather_bottom);
+    weahterView = itemView.findViewById(R.id.icon_weather);
+    layoutWeatherBottom = itemView.findViewById(R.id.layout_weather_bottom);
+
     int statusBarHeight = ResourceUtil.getStatusBarHeightManual();
 
     // 첫 번째 카테고리 내용이 약간 가려지도록 일정 높이를 조절한다.
@@ -82,6 +99,72 @@ public class MainContentsWeatherHolder extends MainContentsHolder /*implements V
     initY = 0; //itemView.getY(); //getScreenY(itemView);
     weather.setOnClickListener(view -> {listener.onEvent(new Event.Builder(Event.CLICK).build());});
     Log.i("APP# MainContentsWeatherHolder | init", "|" + " initY: " + initY + " initWeatherY: " + initWeatherY + ", this: " + this);
+
+    animate();
+  }
+
+  private void animate() {
+//    Keyframe kf0 = Keyframe.ofFloat(0f, 0f);
+//    Keyframe kf1 = Keyframe.ofFloat(.5f, 360f);
+//    Keyframe kf2 = Keyframe.ofFloat(1f, 0f);
+//    PropertyValuesHolder pvhRotation = PropertyValuesHolder.ofKeyframe("rotation", kf0, kf1, kf2);
+//    ObjectAnimator rotationAnim = ObjectAnimator.ofPropertyValuesHolder(weahterView, pvhRotation);
+    ObjectAnimator rotationAnim = ObjectAnimator.ofFloat(weahterView, "rotation", 0f, 360f);
+    rotationAnim.setDuration(17000);
+    rotationAnim.setInterpolator(new LinearInterpolator());
+    rotationAnim.setRepeatCount(Animation.INFINITE);
+
+    rotationAnim.start();
+
+    if (AnimatorManager.getInstance().isCompleted() == false) {
+      weahterView.setTranslationY(100f);
+      ObjectAnimator weatherAnimator = ObjectAnimator.ofFloat(weahterView, "translationY", 0f);
+      weatherAnimator.setDuration(500);
+      weatherAnimator.addListener(new AnimatorManager.SimpleListener() {
+        @Override
+        public void onAnimationCancel(Animator animation) {
+          weahterView.setTranslationY(0f);
+        }
+      });
+
+      weahterView.setAlpha(0f);
+      ObjectAnimator weatherAlphaAnimator = ObjectAnimator.ofFloat(weahterView, "alpha", 1f);
+      weatherAlphaAnimator.setDuration(800);
+      weatherAlphaAnimator.addListener(new AnimatorManager.SimpleListener() {
+        @Override
+        public void onAnimationCancel(Animator animation) {
+          weahterView.setAlpha(1f);
+        }
+      });
+
+      AnimatorManager.getInstance().add(weatherAlphaAnimator);
+      AnimatorManager.getInstance().add(weatherAnimator);
+
+      textTopView.setTranslationY(100f);
+      ObjectAnimator textTopAnimator = ObjectAnimator.ofFloat(textTopView, "translationY", 0f);
+      textTopAnimator.setStartDelay(500);
+      textTopAnimator.setDuration(500);
+      textTopAnimator.addListener(new AnimatorManager.SimpleListener() {
+        @Override
+        public void onAnimationCancel(Animator animation) {
+          textTopView.setTranslationY(0f);
+        }
+      });
+
+      layoutWeatherBottom.setTranslationY(100f);
+      ObjectAnimator textBottomAnimator = ObjectAnimator.ofFloat(layoutWeatherBottom, "translationY", 0f);
+      textBottomAnimator.setStartDelay(700);
+      textBottomAnimator.setDuration(500);
+      textTopAnimator.addListener(new AnimatorManager.SimpleListener() {
+        @Override
+        public void onAnimationCancel(Animator animation) {
+          layoutWeatherBottom.setTranslationY(0f);
+        }
+      });
+
+      AnimatorManager.getInstance().add(textTopAnimator);
+      AnimatorManager.getInstance().add(textBottomAnimator);
+    }
   }
 
 

+ 9 - 4
app/src/main/java/kr/co/zumo/app/lifeplus/view/screen/main/MainFragment.java

@@ -20,6 +20,7 @@ import kr.co.zumo.app.R;
 import kr.co.zumo.app.lifeplus.bean.api.MainContentsBean;
 import kr.co.zumo.app.lifeplus.helper.ActionBarHelper;
 import kr.co.zumo.app.lifeplus.model.SuperModel;
+import kr.co.zumo.app.lifeplus.supervisor.AnimatorManager;
 import kr.co.zumo.app.lifeplus.supervisor.ContentsFlagHelper;
 import kr.co.zumo.app.lifeplus.util.AppUtil;
 import kr.co.zumo.app.lifeplus.util.ResourceUtil;
@@ -60,8 +61,8 @@ public class MainFragment extends FragmentBase<MainPresenter> implements IMainVi
 
     int statusBarHeight = ResourceUtil.getStatusBarHeightManual();
     contentsRecyclerView = findViewById(R.id.recycler_view_main);
-//    contentsRecyclerView.setPadding(0, statusBarHeight, 0, 0);
-//    contentsRecyclerView.setClipToPadding(false);
+    contentsRecyclerView.addOnScrollListener(scrollListener);
+    contentsRecyclerView.addItemDecoration(new PagerIndicatorDecoration(getContext()));
 
     if (contentsRecyclerView.getOnFlingListener() == null) {
       MainContentsSnapper snapper = new MainContentsSnapper(1000, statusBarHeight - ResourceUtil.dpToPx(5) /* 리스트 간격보다 5dp 적다 */);
@@ -178,6 +179,9 @@ public class MainFragment extends FragmentBase<MainPresenter> implements IMainVi
       .search(actionBar -> presenter.onNavigationClickSearch(actionBar))
       .scroll()
       .show();
+
+    AnimatorManager.getInstance().clear();
+    actionBarHelper.animate();
   }
 
   private void clearData() {
@@ -209,6 +213,9 @@ public class MainFragment extends FragmentBase<MainPresenter> implements IMainVi
   public void drawContents(ArrayList<MainContentsBean> data) {
 
     if (null == adapter) {
+
+      AnimatorManager.getInstance().start();
+
       adapter = new MainContentsAdapter(getContext(), data, event -> {
         if (event.getEventId() == Event.SCROLL) {
           contentsRecyclerView.smoothScrollToPosition(1);
@@ -219,8 +226,6 @@ public class MainFragment extends FragmentBase<MainPresenter> implements IMainVi
       });
       contentsRecyclerView.setLayoutManager(new LinearLayoutManager(getContext(), LinearLayoutManager.VERTICAL, false));
       contentsRecyclerView.setAdapter(adapter);
-      contentsRecyclerView.addOnScrollListener(scrollListener);
-      contentsRecyclerView.addItemDecoration(new PagerIndicatorDecoration(getContext()));
     }
     else {
       MainModelHelper.getInstance().dispose();

+ 3 - 4
app/src/main/java/kr/co/zumo/app/lifeplus/view/screen/main/PagerIndicatorDecoration.java

@@ -60,13 +60,12 @@ public class PagerIndicatorDecoration extends RecyclerView.ItemDecoration {
         break;
       }
     }
-
-    drawInactiveIndicators(c, indicatorStartX, indicatorPosY, itemCount, activePosition);
-
     if (activePosition == RecyclerView.NO_POSITION) {
-      return;
+      activePosition = 0;
     }
 
+    drawInactiveIndicators(c, indicatorStartX, indicatorPosY, itemCount, activePosition);
+
     drawHighlights(c, indicatorStartX, indicatorPosY, activePosition);
   }
 

+ 16 - 10
app/src/main/res/layout/main_contents_category.xml

@@ -11,26 +11,32 @@
   android:paddingTop="70dp"
   android:paddingBottom="20dp">
 
-  <TextView
-    android:id="@+id/text_title"
+  <android.support.constraint.ConstraintLayout
+    android:id="@+id/layout_text"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
-    android:lineSpacingExtra="7sp"
     android:paddingStart="@dimen/main_contents_start_gap"
     android:paddingBottom="12dp"
-    android:textColor="@color/C333333"
-    android:textSize="19sp"
-    android:textStyle="bold"
-    tools:text="주말에 뭐하지"
-    />
+    >
+
+    <TextView
+      android:id="@+id/text_title"
+      android:layout_width="wrap_content"
+      android:layout_height="wrap_content"
+      android:textColor="@color/C333333"
+      android:textSize="19sp"
+      android:textStyle="bold"
+      tools:text="주말에 뭐하지"
+      />
+  </android.support.constraint.ConstraintLayout>
 
   <android.support.v7.widget.RecyclerView
     android:id="@+id/recycler_view_category"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:clipToPadding="false"
-    android:paddingStart="@dimen/main_contents_start_gap"
     android:orientation="horizontal"
-    app:layout_constraintTop_toBottomOf="@+id/text_title"/>
+    android:paddingStart="@dimen/main_contents_start_gap"
+    app:layout_constraintTop_toBottomOf="@+id/layout_text"/>
 
 </android.support.constraint.ConstraintLayout>

+ 50 - 18
app/src/main/res/layout/main_contents_weather.xml

@@ -12,8 +12,8 @@
   <LinearLayout
     android:id="@+id/layout_container_weather"
     android:layout_width="wrap_content"
-    android:layout_height="wrap_content"
-    android:gravity="center_vertical"
+    android:layout_height="200dp"
+    android:gravity="top"
     android:orientation="horizontal"
     android:paddingStart="30dp">
 
@@ -23,24 +23,56 @@
       android:layout_height="47dp"
       app:srcCompat="@drawable/ic_icon_weather_sunny_copy"/>
 
-    <TextView
-      android:id="@+id/text_weather"
+    <LinearLayout
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
-      android:lineSpacingExtra="5dp"
-      android:paddingStart="20dp"
-      android:text="@string/weather_sunny"
-      android:textColor="@color/C333333"
-      android:textSize="18sp"
-      android:textStyle="bold"
-      tools:text="지금 서울은\n맑음입니다"/>
+      android:orientation="vertical">
 
-    <ImageView
-      android:id="@+id/icon_dot"
-      android:layout_width="7dp"
-      android:layout_height="10dp"
-      android:layout_gravity="bottom"
-      android:paddingBottom="3dp"
-      app:srcCompat="@drawable/ic_icon_main_dot_copy"/>
+      <LinearLayout
+        android:id="@+id/layout_weather_top"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:orientation="horizontal">
+
+        <TextView
+          android:id="@+id/text_weather_top"
+          android:layout_width="wrap_content"
+          android:layout_height="wrap_content"
+          android:lineSpacingExtra="5dp"
+          android:paddingStart="20dp"
+          android:text="@string/weather_sunny_0"
+          android:textColor="@color/C333333"
+          android:textSize="18sp"
+          android:textStyle="bold"
+          tools:text="@string/weather_sunny_0"/>
+      </LinearLayout>
+
+      <LinearLayout
+        android:id="@+id/layout_weather_bottom"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:orientation="horizontal">
+
+        <TextView
+          android:id="@+id/text_weather_bottom"
+          android:layout_width="wrap_content"
+          android:layout_height="wrap_content"
+          android:lineSpacingExtra="5dp"
+          android:paddingStart="20dp"
+          android:text="@string/weather_sunny_1"
+          android:textColor="@color/C333333"
+          android:textSize="18sp"
+          android:textStyle="bold"
+          tools:text="@string/weather_sunny_1"/>
+
+        <ImageView
+          android:id="@+id/icon_dot"
+          android:layout_width="7dp"
+          android:layout_height="10dp"
+          android:layout_gravity="bottom"
+          android:paddingBottom="3dp"
+          app:srcCompat="@drawable/ic_icon_main_dot_copy"/>
+      </LinearLayout>
+    </LinearLayout>
   </LinearLayout>
 </LinearLayout>

+ 2 - 1
app/src/main/res/values/strings.xml

@@ -502,7 +502,8 @@
   <string name="user_quit_fail_message2">마이너스 코인이 발생한 경우 회원탈퇴가 불가능합니다.</string>
   <string name="user_quit_fail_message3">Lifeplus 정책상 마이너스 코인이\n발생한 경우 회원탈퇴가 불가능합니다.\n최소 0코인 이후부터 회원탈퇴가 가능하므로\n추후 다시 시도해주시기 바랍니다. </string>
   <string name="select_coin_possible_message">최근 1년 이내로 조회 가능합니다.</string>
-  <string name="weather_sunny">지금 서울은\n맑음입니다</string>
+  <string name="weather_sunny_0">지금 서울은</string>
+  <string name="weather_sunny_1">맑음입니다</string>
 
   <string name="make_my_bucket_list">나만의 버킷리스트 만들기</string>