Browse Source

[메인][Common] Snapper 클래스 분리 및 콘텐츠 상세 리싸이클러뷰 스내퍼 설정

Hasemi 7 years ago
parent
commit
475a3ce131

+ 294 - 0
app/src/main/java/kr/co/zumo/app/lifeplus/view/custom/Snapper.java

@@ -0,0 +1,294 @@
+package kr.co.zumo.app.lifeplus.view.custom;
+
+import android.graphics.PointF;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.support.v7.widget.LinearSmoothScroller;
+import android.support.v7.widget.LinearSnapHelper;
+import android.support.v7.widget.OrientationHelper;
+import android.support.v7.widget.RecyclerView;
+import android.util.DisplayMetrics;
+import android.util.Log;
+import android.view.View;
+import android.view.animation.DecelerateInterpolator;
+import android.widget.Scroller;
+
+/**
+ * Snapper
+ * <pre>
+ * </pre>
+ *
+ * @author 하세미
+ * @version 1.0
+ * @history 하세미   [2018-11-27]   [최초 작성]
+ * @since 2018-11-27
+ */
+public class Snapper extends LinearSnapHelper {
+
+  static final float MILLISECONDS_PER_INCH = 100f;
+
+
+  private static final float INVALID_DISTANCE = 1f;
+  @Nullable
+  private OrientationHelper mVerticalHelper;
+  @Nullable
+  private OrientationHelper mHorizontalHelper;
+
+  private RecyclerView recyclerView;
+  private int minVelocity = 200;
+
+  public Snapper(RecyclerView recyclerView, int minVelocity) {
+    this.recyclerView = recyclerView;
+    if (minVelocity > this.minVelocity) {
+      this.minVelocity = minVelocity;
+    }
+  }
+
+  @Override
+  public boolean onFling(int velocityX, int velocityY) {
+    Log.w("APP# Snapper | onFling", "|" + "velociyX: " + velocityX);
+    Scroller mGravityScroller = new Scroller(recyclerView.getContext(), new DecelerateInterpolator());
+    mGravityScroller.fling(0, 0, velocityX, velocityY, Integer.MIN_VALUE, Integer.MAX_VALUE, Integer.MIN_VALUE, Integer.MAX_VALUE);
+//      Log.w("APP# MainBannerView | onFling", "| " + mGravityScroller.getFinalX());
+//      boolean result = super.onFling(velocityX, velocityY);
+//      Log.w("APP# Snapper | onFling", "|" + "result: " + result);
+    RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();
+    if (layoutManager == null) {
+      return false;
+    }
+    RecyclerView.Adapter adapter = recyclerView.getAdapter();
+    if (adapter == null) {
+      return false;
+    }
+    int minFlingVelocity = 0;
+    return (Math.abs(velocityY) > minFlingVelocity || Math.abs(velocityX) > minFlingVelocity)
+      && snapFromFling2(layoutManager, velocityX, velocityY);
+  }
+
+  boolean snapFromFling2(@NonNull RecyclerView.LayoutManager layoutManager, int velocityX, int velocityY) {
+    if (!(layoutManager instanceof RecyclerView.SmoothScroller.ScrollVectorProvider)) {
+      return false;
+    }
+
+    RecyclerView.SmoothScroller smoothScroller = createScroller(layoutManager);
+    if (smoothScroller == null) {
+      return false;
+    }
+
+    int targetPosition = findTargetSnapPosition(layoutManager, velocityX, velocityY);
+    Log.w("APP# Snapper | snapFromFling2", "|" + "targetPosition: " + targetPosition);
+    if (targetPosition == RecyclerView.NO_POSITION) {
+      return false;
+    }
+
+    smoothScroller.setTargetPosition(targetPosition);
+    layoutManager.startSmoothScroll(smoothScroller);
+    return true;
+  }
+
+  @Override
+  public int findTargetSnapPosition(RecyclerView.LayoutManager layoutManager, int velocityX, int velocityY) {
+    if (!(layoutManager instanceof RecyclerView.SmoothScroller.ScrollVectorProvider)) {
+      return RecyclerView.NO_POSITION;
+    }
+
+    final int itemCount = layoutManager.getItemCount();
+    if (itemCount == 0) {
+      return RecyclerView.NO_POSITION;
+    }
+
+    final View currentView = findSnapView(layoutManager);
+    if (currentView == null) {
+      return RecyclerView.NO_POSITION;
+    }
+
+    final int currentPosition = layoutManager.getPosition(currentView);
+    if (currentPosition == RecyclerView.NO_POSITION) {
+      return RecyclerView.NO_POSITION;
+    }
+
+    RecyclerView.SmoothScroller.ScrollVectorProvider vectorProvider =
+      (RecyclerView.SmoothScroller.ScrollVectorProvider) layoutManager;
+    // deltaJumps sign comes from the velocity which may not match the order of children in
+    // the LayoutManager. To overcome this, we ask for a vector from the LayoutManager to
+    // get the direction.
+    PointF vectorForEnd = vectorProvider.computeScrollVectorForPosition(itemCount - 1);
+    if (vectorForEnd == null) {
+      // cannot get a vector for the given position.
+      return RecyclerView.NO_POSITION;
+    }
+
+    int vDeltaJump, hDeltaJump;
+    if (layoutManager.canScrollHorizontally()) {
+      hDeltaJump = estimateNextPositionDiffForFling(layoutManager,
+        getHorizontalHelper(layoutManager), velocityX, 0);
+      if (vectorForEnd.x < 0) {
+        hDeltaJump = -hDeltaJump;
+      }
+    }
+    else {
+      hDeltaJump = 0;
+    }
+    if (layoutManager.canScrollVertically()) {
+      vDeltaJump = estimateNextPositionDiffForFling(layoutManager,
+        getVerticalHelper(layoutManager), 0, velocityY);
+      if (vectorForEnd.y < 0) {
+        vDeltaJump = -vDeltaJump;
+      }
+    }
+    else {
+      vDeltaJump = 0;
+    }
+
+    int deltaJump = layoutManager.canScrollVertically() ? vDeltaJump : hDeltaJump;
+    Log.i("APP# Snapper | findTargetSnapPosition", "|" + "deltaJump: " + deltaJump);
+    if (deltaJump == 0) {
+      return RecyclerView.NO_POSITION;
+    }
+
+    int targetPos = currentPosition + deltaJump;
+    if (targetPos < 0) {
+      targetPos = 0;
+    }
+    if (targetPos >= itemCount) {
+      targetPos = itemCount - 1;
+    }
+    return targetPos;
+  }
+
+  /**
+   * Estimates a position to which SnapHelper will try to scroll to in response to a fling.
+   *
+   * @param layoutManager The {@link RecyclerView.LayoutManager} associated with the attached
+   *                      {@link RecyclerView}.
+   * @param helper        The {@link OrientationHelper} that is created from the LayoutManager.
+   * @param velocityX     The velocity on the x axis.
+   * @param velocityY     The velocity on the y axis.
+   * @return The diff between the target scroll position and the current position.
+   */
+  private int estimateNextPositionDiffForFling(RecyclerView.LayoutManager layoutManager, OrientationHelper helper, int velocityX, int velocityY) {
+    int[] distances = calculateScrollDistance(velocityX, velocityY);
+    float distancePerChild = computeDistancePerChild(layoutManager, helper);
+    if (distancePerChild <= 0) {
+      return 0;
+    }
+    int distance = Math.abs(distances[0]) > Math.abs(distances[1]) ? distances[0] : distances[1];
+
+    int min = 0;
+    // 속도가 minVelocity 보다 크면 기본 1칸 이동
+    if (Math.abs(velocityX) > minVelocity || Math.abs(velocityY) > minVelocity) {
+      min = 1;
+    }
+    int result = Math.round(distance / distancePerChild);
+    if (result == 0 && min > 0) {
+      result = distance > 0 ? min : -min;
+    }
+
+    return result;
+  }
+
+  /**
+   * Computes an average pixel value to pass a single child.
+   * <p>
+   * Returns a negative value if it cannot be calculated.
+   *
+   * @param layoutManager The {@link RecyclerView.LayoutManager} associated with the attached
+   *                      {@link RecyclerView}.
+   * @param helper        The relevant {@link OrientationHelper} for the attached
+   *                      {@link RecyclerView.LayoutManager}.
+   * @return A float value that is the average number of pixels needed to scroll by one view in
+   * the relevant direction.
+   */
+  private float computeDistancePerChild(RecyclerView.LayoutManager layoutManager,
+                                        OrientationHelper helper) {
+    View minPosView = null;
+    View maxPosView = null;
+    int minPos = Integer.MAX_VALUE;
+    int maxPos = Integer.MIN_VALUE;
+    int childCount = layoutManager.getChildCount();
+    if (childCount == 0) {
+      return INVALID_DISTANCE;
+    }
+
+    for (int i = 0; i < childCount; i++) {
+      View child = layoutManager.getChildAt(i);
+      final int pos = layoutManager.getPosition(child);
+      if (pos == RecyclerView.NO_POSITION) {
+        continue;
+      }
+      if (pos < minPos) {
+        minPos = pos;
+        minPosView = child;
+      }
+      if (pos > maxPos) {
+        maxPos = pos;
+        maxPosView = child;
+      }
+    }
+    if (minPosView == null || maxPosView == null) {
+      return INVALID_DISTANCE;
+    }
+    int start = Math.min(helper.getDecoratedStart(minPosView),
+      helper.getDecoratedStart(maxPosView));
+    int end = Math.max(helper.getDecoratedEnd(minPosView),
+      helper.getDecoratedEnd(maxPosView));
+    int distance = end - start;
+    if (distance == 0) {
+      return INVALID_DISTANCE;
+    }
+    return 1f * distance / ((maxPos - minPos) + 1);
+  }
+
+  @NonNull
+  private OrientationHelper getVerticalHelper(@NonNull RecyclerView.LayoutManager layoutManager) {
+    if (mVerticalHelper == null || mVerticalHelper.getLayoutManager() != layoutManager) {
+      mVerticalHelper = OrientationHelper.createVerticalHelper(layoutManager);
+    }
+    return mVerticalHelper;
+  }
+
+  @NonNull
+  private OrientationHelper getHorizontalHelper(
+    @NonNull RecyclerView.LayoutManager layoutManager) {
+    if (mHorizontalHelper == null || mHorizontalHelper.getLayoutManager() != layoutManager) {
+      mHorizontalHelper = OrientationHelper.createHorizontalHelper(layoutManager);
+    }
+    return mHorizontalHelper;
+  }
+
+  /**
+   * Creates a scroller to be used in the snapping implementation.
+   *
+   * @param layoutManager The {@link RecyclerView.LayoutManager} associated with the attached
+   *                      {@link RecyclerView}.
+   * @return a {@link RecyclerView.SmoothScroller} which will handle the scrolling.
+   */
+  @Nullable
+  protected RecyclerView.SmoothScroller createScroller(RecyclerView.LayoutManager layoutManager) {
+
+    if (!(layoutManager instanceof RecyclerView.SmoothScroller.ScrollVectorProvider)) {
+      return null;
+    }
+    return new LinearSmoothScroller(recyclerView.getContext()) {
+      @Override
+      protected void onTargetFound(View targetView, RecyclerView.State state, RecyclerView.SmoothScroller.Action action) {
+        if (recyclerView == null) {
+          // The associated RecyclerView has been removed so there is no action to take.
+          return;
+        }
+        int[] snapDistances = calculateDistanceToFinalSnap(recyclerView.getLayoutManager(), targetView);
+        final int dx = snapDistances[0];
+        final int dy = snapDistances[1];
+        final int time = calculateTimeForDeceleration(Math.max(Math.abs(dx), Math.abs(dy)));
+        if (time > 0) {
+          action.update(dx, dy, time, mDecelerateInterpolator);
+        }
+      }
+
+      @Override
+      protected float calculateSpeedPerPixel(DisplayMetrics displayMetrics) {
+        return MILLISECONDS_PER_INCH / displayMetrics.densityDpi;
+      }
+    };
+  }
+}

+ 2 - 280
app/src/main/java/kr/co/zumo/app/lifeplus/view/custom/category/banner/MainBannerView.java

@@ -1,29 +1,20 @@
 package kr.co.zumo.app.lifeplus.view.custom.category.banner;
 
 import android.content.Context;
-import android.graphics.PointF;
-import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
 import android.support.constraint.ConstraintLayout;
 import android.support.v7.widget.LinearLayoutManager;
-import android.support.v7.widget.LinearSmoothScroller;
-import android.support.v7.widget.LinearSnapHelper;
-import android.support.v7.widget.OrientationHelper;
 import android.support.v7.widget.RecyclerView;
 import android.support.v7.widget.SnapHelper;
 import android.util.AttributeSet;
-import android.util.DisplayMetrics;
 import android.util.Log;
 import android.view.LayoutInflater;
-import android.view.View;
-import android.view.animation.DecelerateInterpolator;
-import android.widget.Scroller;
 
 import java.util.List;
 
 import kr.co.zumo.app.R;
 import kr.co.zumo.app.lifeplus.bean.api.CategoryBannerBean;
 import kr.co.zumo.app.lifeplus.view.IEventListener;
+import kr.co.zumo.app.lifeplus.view.custom.Snapper;
 
 /**
  * MainBannerView
@@ -56,8 +47,8 @@ public class MainBannerView extends ConstraintLayout {
     LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
     inflater.inflate(R.layout.main_banner_view, this);
 
-    SnapHelper snapHelper = new Snapper(400);
     recyclerView = findViewById(R.id.recycler_view_main_banner_view);
+    SnapHelper snapHelper = new Snapper(recyclerView, 400);
     recyclerView.setNestedScrollingEnabled(false);
     recyclerView.setLayoutManager(new LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false));
 
@@ -82,273 +73,4 @@ public class MainBannerView extends ConstraintLayout {
     mainBannerAdapter = null;
   }
 
-  /***********************************
-   * Snapper
-   ***********************************/
-  public class Snapper extends LinearSnapHelper {
-
-    static final float MILLISECONDS_PER_INCH = 100f;
-
-    private static final float INVALID_DISTANCE = 1f;
-    @Nullable
-    private OrientationHelper mVerticalHelper;
-    @Nullable
-    private OrientationHelper mHorizontalHelper;
-
-    private int minVelocity = 200;
-
-    public Snapper(int minVelocity) {
-      if (minVelocity > this.minVelocity) {
-        this.minVelocity = minVelocity;
-      }
-    }
-
-    @Override
-    public boolean onFling(int velocityX, int velocityY) {
-      Log.w("APP# Snapper | onFling", "|" + "velociyX: " + velocityX);
-      Scroller mGravityScroller = new Scroller(recyclerView.getContext(), new DecelerateInterpolator());
-      mGravityScroller.fling(0, 0, velocityX, velocityY, Integer.MIN_VALUE, Integer.MAX_VALUE, Integer.MIN_VALUE, Integer.MAX_VALUE);
-//      Log.w("APP# MainBannerView | onFling", "| " + mGravityScroller.getFinalX());
-//      boolean result = super.onFling(velocityX, velocityY);
-//      Log.w("APP# Snapper | onFling", "|" + "result: " + result);
-      RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();
-      if (layoutManager == null) {
-        return false;
-      }
-      RecyclerView.Adapter adapter = recyclerView.getAdapter();
-      if (adapter == null) {
-        return false;
-      }
-      int minFlingVelocity = 0;
-      return (Math.abs(velocityY) > minFlingVelocity || Math.abs(velocityX) > minFlingVelocity)
-        && snapFromFling2(layoutManager, velocityX, velocityY);
-    }
-
-    boolean snapFromFling2(@NonNull RecyclerView.LayoutManager layoutManager, int velocityX, int velocityY) {
-      if (!(layoutManager instanceof RecyclerView.SmoothScroller.ScrollVectorProvider)) {
-        return false;
-      }
-
-      RecyclerView.SmoothScroller smoothScroller = createScroller(layoutManager);
-      if (smoothScroller == null) {
-        return false;
-      }
-
-      int targetPosition = findTargetSnapPosition(layoutManager, velocityX, velocityY);
-      Log.w("APP# Snapper | snapFromFling2", "|" + "targetPosition: " + targetPosition);
-      if (targetPosition == RecyclerView.NO_POSITION) {
-        return false;
-      }
-
-      smoothScroller.setTargetPosition(targetPosition);
-      layoutManager.startSmoothScroll(smoothScroller);
-      return true;
-    }
-
-    @Override
-    public int findTargetSnapPosition(RecyclerView.LayoutManager layoutManager, int velocityX, int velocityY) {
-      if (!(layoutManager instanceof RecyclerView.SmoothScroller.ScrollVectorProvider)) {
-        return RecyclerView.NO_POSITION;
-      }
-
-      final int itemCount = layoutManager.getItemCount();
-      if (itemCount == 0) {
-        return RecyclerView.NO_POSITION;
-      }
-
-      final View currentView = findSnapView(layoutManager);
-      if (currentView == null) {
-        return RecyclerView.NO_POSITION;
-      }
-
-      final int currentPosition = layoutManager.getPosition(currentView);
-      if (currentPosition == RecyclerView.NO_POSITION) {
-        return RecyclerView.NO_POSITION;
-      }
-
-      RecyclerView.SmoothScroller.ScrollVectorProvider vectorProvider =
-        (RecyclerView.SmoothScroller.ScrollVectorProvider) layoutManager;
-      // deltaJumps sign comes from the velocity which may not match the order of children in
-      // the LayoutManager. To overcome this, we ask for a vector from the LayoutManager to
-      // get the direction.
-      PointF vectorForEnd = vectorProvider.computeScrollVectorForPosition(itemCount - 1);
-      if (vectorForEnd == null) {
-        // cannot get a vector for the given position.
-        return RecyclerView.NO_POSITION;
-      }
-
-      int vDeltaJump, hDeltaJump;
-      if (layoutManager.canScrollHorizontally()) {
-        hDeltaJump = estimateNextPositionDiffForFling(layoutManager,
-          getHorizontalHelper(layoutManager), velocityX, 0);
-        if (vectorForEnd.x < 0) {
-          hDeltaJump = -hDeltaJump;
-        }
-      }
-      else {
-        hDeltaJump = 0;
-      }
-      if (layoutManager.canScrollVertically()) {
-        vDeltaJump = estimateNextPositionDiffForFling(layoutManager,
-          getVerticalHelper(layoutManager), 0, velocityY);
-        if (vectorForEnd.y < 0) {
-          vDeltaJump = -vDeltaJump;
-        }
-      }
-      else {
-        vDeltaJump = 0;
-      }
-
-      int deltaJump = layoutManager.canScrollVertically() ? vDeltaJump : hDeltaJump;
-      Log.i("APP# Snapper | findTargetSnapPosition", "|" + "deltaJump: " + deltaJump);
-      if (deltaJump == 0) {
-        return RecyclerView.NO_POSITION;
-      }
-
-      int targetPos = currentPosition + deltaJump;
-      if (targetPos < 0) {
-        targetPos = 0;
-      }
-      if (targetPos >= itemCount) {
-        targetPos = itemCount - 1;
-      }
-      return targetPos;
-    }
-
-    /**
-     * Estimates a position to which SnapHelper will try to scroll to in response to a fling.
-     *
-     * @param layoutManager The {@link RecyclerView.LayoutManager} associated with the attached
-     *                      {@link RecyclerView}.
-     * @param helper        The {@link OrientationHelper} that is created from the LayoutManager.
-     * @param velocityX     The velocity on the x axis.
-     * @param velocityY     The velocity on the y axis.
-     * @return The diff between the target scroll position and the current position.
-     */
-    private int estimateNextPositionDiffForFling(RecyclerView.LayoutManager layoutManager, OrientationHelper helper, int velocityX, int velocityY) {
-      int[] distances = calculateScrollDistance(velocityX, velocityY);
-      float distancePerChild = computeDistancePerChild(layoutManager, helper);
-      if (distancePerChild <= 0) {
-        return 0;
-      }
-      int distance = Math.abs(distances[0]) > Math.abs(distances[1]) ? distances[0] : distances[1];
-
-      int min = 0;
-      // 속도가 minVelocity 보다 크면 기본 1칸 이동
-      if (Math.abs(velocityX) > minVelocity || Math.abs(velocityY) > minVelocity) {
-        min = 1;
-      }
-      int result = Math.round(distance / distancePerChild);
-      if (result == 0 && min > 0) {
-        result = distance > 0 ? min : -min;
-      }
-
-      return result;
-    }
-
-    /**
-     * Computes an average pixel value to pass a single child.
-     * <p>
-     * Returns a negative value if it cannot be calculated.
-     *
-     * @param layoutManager The {@link RecyclerView.LayoutManager} associated with the attached
-     *                      {@link RecyclerView}.
-     * @param helper        The relevant {@link OrientationHelper} for the attached
-     *                      {@link RecyclerView.LayoutManager}.
-     * @return A float value that is the average number of pixels needed to scroll by one view in
-     * the relevant direction.
-     */
-    private float computeDistancePerChild(RecyclerView.LayoutManager layoutManager,
-                                          OrientationHelper helper) {
-      View minPosView = null;
-      View maxPosView = null;
-      int minPos = Integer.MAX_VALUE;
-      int maxPos = Integer.MIN_VALUE;
-      int childCount = layoutManager.getChildCount();
-      if (childCount == 0) {
-        return INVALID_DISTANCE;
-      }
-
-      for (int i = 0; i < childCount; i++) {
-        View child = layoutManager.getChildAt(i);
-        final int pos = layoutManager.getPosition(child);
-        if (pos == RecyclerView.NO_POSITION) {
-          continue;
-        }
-        if (pos < minPos) {
-          minPos = pos;
-          minPosView = child;
-        }
-        if (pos > maxPos) {
-          maxPos = pos;
-          maxPosView = child;
-        }
-      }
-      if (minPosView == null || maxPosView == null) {
-        return INVALID_DISTANCE;
-      }
-      int start = Math.min(helper.getDecoratedStart(minPosView),
-        helper.getDecoratedStart(maxPosView));
-      int end = Math.max(helper.getDecoratedEnd(minPosView),
-        helper.getDecoratedEnd(maxPosView));
-      int distance = end - start;
-      if (distance == 0) {
-        return INVALID_DISTANCE;
-      }
-      return 1f * distance / ((maxPos - minPos) + 1);
-    }
-
-    @NonNull
-    private OrientationHelper getVerticalHelper(@NonNull RecyclerView.LayoutManager layoutManager) {
-      if (mVerticalHelper == null || mVerticalHelper.getLayoutManager() != layoutManager) {
-        mVerticalHelper = OrientationHelper.createVerticalHelper(layoutManager);
-      }
-      return mVerticalHelper;
-    }
-
-    @NonNull
-    private OrientationHelper getHorizontalHelper(
-      @NonNull RecyclerView.LayoutManager layoutManager) {
-      if (mHorizontalHelper == null || mHorizontalHelper.getLayoutManager() != layoutManager) {
-        mHorizontalHelper = OrientationHelper.createHorizontalHelper(layoutManager);
-      }
-      return mHorizontalHelper;
-    }
-
-    /**
-     * Creates a scroller to be used in the snapping implementation.
-     *
-     * @param layoutManager The {@link RecyclerView.LayoutManager} associated with the attached
-     *                      {@link RecyclerView}.
-     * @return a {@link RecyclerView.SmoothScroller} which will handle the scrolling.
-     */
-    @Nullable
-    protected RecyclerView.SmoothScroller createScroller(RecyclerView.LayoutManager layoutManager) {
-
-      if (!(layoutManager instanceof RecyclerView.SmoothScroller.ScrollVectorProvider)) {
-        return null;
-      }
-      return new LinearSmoothScroller(recyclerView.getContext()) {
-        @Override
-        protected void onTargetFound(View targetView, RecyclerView.State state, RecyclerView.SmoothScroller.Action action) {
-          if (recyclerView == null) {
-            // The associated RecyclerView has been removed so there is no action to take.
-            return;
-          }
-          int[] snapDistances = calculateDistanceToFinalSnap(recyclerView.getLayoutManager(), targetView);
-          final int dx = snapDistances[0];
-          final int dy = snapDistances[1];
-          final int time = calculateTimeForDeceleration(Math.max(Math.abs(dx), Math.abs(dy)));
-          if (time > 0) {
-            action.update(dx, dy, time, mDecelerateInterpolator);
-          }
-        }
-
-        @Override
-        protected float calculateSpeedPerPixel(DisplayMetrics displayMetrics) {
-          return MILLISECONDS_PER_INCH / displayMetrics.densityDpi;
-        }
-      };
-    }
-  }
 }

+ 3 - 2
app/src/main/java/kr/co/zumo/app/lifeplus/view/custom/contents/CustomListicleImageView.java

@@ -14,6 +14,7 @@ import java.util.List;
 import kr.co.zumo.app.R;
 import kr.co.zumo.app.lifeplus.bean.TextImageBean;
 import kr.co.zumo.app.lifeplus.view.IEventListener;
+import kr.co.zumo.app.lifeplus.view.custom.Snapper;
 
 /**
  * CustomListicleImageView
@@ -57,7 +58,6 @@ public class CustomListicleImageView extends ConstraintLayout {
     textViewTitle = findViewById(R.id.text_view_title);
     textViewSubTitle = findViewById(R.id.text_view_sub_title);
 
-
     textViewTitleNumber.setText("05");
     textViewTitle.setText("Title");
     textViewSubTitle.setText("SubTitle");
@@ -66,6 +66,8 @@ public class CustomListicleImageView extends ConstraintLayout {
     textViewTotalPage.setText(String.valueOf(textImageBeanList.size()));
 
     recyclerView = findViewById(R.id.recycler_view_listicle_view);
+    Snapper snapper = new Snapper(recyclerView, 400);
+    snapper.attachToRecyclerView(recyclerView);
     LinearLayoutManager linearLayoutManager = new LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false);
     recyclerView.setLayoutManager(linearLayoutManager);
     adapter = new CustomListicleImageViewAdapter(context, inflater, textImageBeanList, event -> {
@@ -106,7 +108,6 @@ public class CustomListicleImageView extends ConstraintLayout {
       @Override
       public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
         textViewCurrentPage.setText(String.valueOf(linearLayoutManager.findFirstVisibleItemPosition() + 1));
-        //Log.e("APP#  CustomListicleImageView | onScrolled", "|" + linearLayoutManager.findFirstVisibleItemPosition());
       }
     });
   }

+ 3 - 0
app/src/main/java/kr/co/zumo/app/lifeplus/view/screen/contents/ContentsDetailFragment.java

@@ -13,6 +13,7 @@ import kr.co.zumo.app.R;
 import kr.co.zumo.app.lifeplus.helper.ActionBarHelper;
 import kr.co.zumo.app.lifeplus.view.Event;
 import kr.co.zumo.app.lifeplus.view.IEventListener;
+import kr.co.zumo.app.lifeplus.view.custom.Snapper;
 import kr.co.zumo.app.lifeplus.view.screen.FragmentBase;
 
 /**
@@ -43,6 +44,8 @@ public class ContentsDetailFragment extends FragmentBase<ContentsDetailPresenter
 
       }
     });
+    Snapper snapper = new Snapper(recyclerViewContentsDetail, 400);
+    snapper.attachToRecyclerView(recyclerViewContentsDetail);
     recyclerViewContentsDetail.setLayoutManager(new LinearLayoutManager(getActivity(), LinearLayoutManager.HORIZONTAL, false));
     recyclerViewContentsDetail.setAdapter(adapter);
   }