{"id":1329,"date":"2019-06-04T10:07:32","date_gmt":"2019-06-04T01:07:32","guid":{"rendered":"https:\/\/www.charlezz.com\/?p=1329"},"modified":"2019-06-04T10:07:32","modified_gmt":"2019-06-04T01:07:32","slug":"recyclerview%ec%99%80-pagersnaphelper%eb%a1%9c-viewpager-%eb%a7%8c%eb%93%a4%ea%b8%b0","status":"publish","type":"post","link":"https:\/\/charlezz.com\/?p=1329","title":{"rendered":"RecyclerView\uc640 PagerSnapHelper\ub85c ViewPager \ub9cc\ub4e4\uae30"},"content":{"rendered":"<h1>ViewPager\ub9cc\ub4e4\uae30<\/h1>\n<p><a href=\"https:\/\/www.charlezz.com\/?p=1037\">ViewPager2<\/a>\uc640 \ubc29\uc2dd\uc740 \ube44\uc2b7\ud558\uc9c0\ub9cc, \uc544\uc9c1 \uc815\uc2dd \ub9b4\ub9ac\uc988\uac00 \ub098\uc624\uc9c0 \uc54a\uc558\uc2b5\ub2c8\ub2e4.<\/p>\n<p>\uae30\uc874\uc5d0 RecyclerView\uac00 \uad6c\ud604\uc774 \ub418\uc5b4\uc788\ub2e4\uba74 PagerSnapHelper\ub9cc \ucd94\uac00\ud558\uba74 \ub41c\ub2e4.<\/p>\n<pre class=\"lang:java decode:true\">MyAdapter adapter = ...\r\n\r\nrecyclerView.setAdapter(adapter);\r\nrecyclerView.setLayoutManager(new LinearLayoutManager(context,\r\n        LinearLayoutManager.HORIZONTAL, false));\r\n\r\n\/\/ PagerSnapHelper \ucd94\uac00\r\nPagerSnapHelper snapHelper = new PagerSnapHelper();\r\nsnapHelper.attachToRecyclerView(recyclerView);<\/pre>\n<p><a href=\"https:\/\/www.charlezz.com\/?attachment_id=1330\" rel=\"attachment wp-att-1330\"><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/www.charlezz.com\/wordpress\/wp-content\/uploads\/2019\/06\/bland-pager.gif\" alt=\"\" width=\"600\" height=\"144\" class=\"aligncenter size-full wp-image-1330\" \/><\/a><\/p>\n<p>&nbsp;<\/p>\n<h2>Indicator \ucd94\uac00\ud558\uae30<\/h2>\n<p>RecyclerView\uc5d0\ub294 ItemDecoration\uc744 \uc774\uc6a9\ud574\uc11c Indicator\ub97c \uadf8\ub9b4\uc218 \uc788\uc2b5\ub2c8\ub2e4.\u00a0<br \/>\n\uc800\ub294 <a href=\"https:\/\/github.com\/bleeding182\/recyclerviewItemDecorations\/blob\/master\/app\/src\/main\/java\/com\/github\/bleeding182\/recyclerviewdecorations\/viewpager\/LinePagerIndicatorDecoration.java\"><span>LinePagerIndicatorDecoration<\/span><\/a> \ucc38\uace0\ud574\uc11c \uadf8\ub824\ubcf4\uc558\uc2b5\ub2c8\ub2e4.<\/p>\n<pre class=\"lang:java decode:true\">recyclerView.addItemDecoration(new LinePagerIndicatorDecoration());<\/pre>\n<p><a href=\"https:\/\/www.charlezz.com\/?attachment_id=1331\" rel=\"attachment wp-att-1331\"><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/www.charlezz.com\/wordpress\/wp-content\/uploads\/2019\/06\/viewpagerdecoration.gif\" alt=\"\" width=\"600\" height=\"169\" class=\"aligncenter size-full wp-image-1331\" \/><\/a><\/p>\n<h2>SnapPagerScrollListener \ucd94\uac00\ud558\uae30<\/h2>\n<p>ViewPager\uc640\ub294 \ub2e4\ub974\uac8c RecyclerView\ub294 \ud398\uc774\uc9c0 \ubcc0\uacbd \ub9ac\uc2a4\ub108\uac00 \uc5c6\uc73c\ubbc0\ub85c, \uc2a4\ud06c\ub864 \ub9ac\uc2a4\ub108\ub97c \uc774\uc6a9\ud558\uc5ec \ud398\uc774\uc9c0 \ubcc0\uacbd \uc774\ubca4\ud2b8\ub97c \ubc1b\uc544\uc57c\ud569\ub2c8\ub2e4. SnapPagerScrollListener\ub294 \uc2a4\ud0dd\uc624\ubc84\ud50c\ub85c\uc758 TreyWurm\uc758 <a href=\"https:\/\/stackoverflow.com\/questions\/52083768\/from-to-page-changed-listener-in-pagersnaphelper\">\ub2f5\ubcc0<\/a>\uc744 \ucc38\uace0\ud588\uc2b5\ub2c8\ub2e4.<\/p>\n<pre class=\"lang:java decode:true\">public class SnapPagerScrollListener extends RecyclerView.OnScrollListener {\r\n\r\n    \/\/ Constants\r\n    public static final int ON_SCROLL = 0;\r\n    public static final int ON_SETTLED = 1;\r\n\r\n    @IntDef({ON_SCROLL, ON_SETTLED})\r\n    public @interface Type {\r\n    }\r\n\r\n    public interface OnChangeListener {\r\n        void onSnapped(int position);\r\n    }\r\n\r\n    \/\/ Properties\r\n    private final PagerSnapHelper snapHelper;\r\n    private final int type;\r\n    private final boolean notifyOnInit;\r\n    private final OnChangeListener listener;\r\n    private int snapPosition;\r\n\r\n    \/\/ Constructor\r\n    public SnapPagerScrollListener(PagerSnapHelper snapHelper, @Type int type, boolean notifyOnInit, OnChangeListener listener) {\r\n        this.snapHelper = snapHelper;\r\n        this.type = type;\r\n        this.notifyOnInit = notifyOnInit;\r\n        this.listener = listener;\r\n        this.snapPosition = RecyclerView.NO_POSITION;\r\n    }\r\n\r\n    \/\/ Methods\r\n    @Override\r\n    public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {\r\n        super.onScrolled(recyclerView, dx, dy);\r\n        if ((type == ON_SCROLL) || !hasItemPosition()) {\r\n            notifyListenerIfNeeded(getSnapPosition(recyclerView));\r\n        }\r\n    }\r\n\r\n    @Override\r\n    public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {\r\n        super.onScrollStateChanged(recyclerView, newState);\r\n        if (type == ON_SETTLED &amp;&amp; newState == RecyclerView.SCROLL_STATE_IDLE) {\r\n            notifyListenerIfNeeded(getSnapPosition(recyclerView));\r\n        }\r\n    }\r\n\r\n    private int getSnapPosition(RecyclerView recyclerView) {\r\n        RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();\r\n        if (layoutManager == null) {\r\n            return RecyclerView.NO_POSITION;\r\n        }\r\n\r\n        View snapView = snapHelper.findSnapView(layoutManager);\r\n        if (snapView == null) {\r\n            return RecyclerView.NO_POSITION;\r\n        }\r\n\r\n        return layoutManager.getPosition(snapView);\r\n    }\r\n\r\n    private void notifyListenerIfNeeded(int newSnapPosition) {\r\n        if (snapPosition != newSnapPosition) {\r\n            if (notifyOnInit &amp;&amp; !hasItemPosition()) {\r\n                listener.onSnapped(newSnapPosition);\r\n            } else if (hasItemPosition()) {\r\n                listener.onSnapped(newSnapPosition);\r\n            }\r\n\r\n            snapPosition = newSnapPosition;\r\n        }\r\n    }\r\n\r\n    private boolean hasItemPosition() {\r\n        return snapPosition != RecyclerView.NO_POSITION;\r\n    }\r\n}<\/pre>\n<p>SnapPagerScrollListener \ud074\ub798\uc2a4\ub97c \ub9cc\ub4e4\uc5c8\uc73c\ub2c8 \uc774\uc81c RecyclerView\uc5d0 \uc2a4\ud06c\ub864 \ub9ac\uc2a4\ub108\ub97c \ucd94\uac00 \ud574\ubcf4\uaca0\uc2b5\ub2c8\ub2e4.<\/p>\n<pre class=\"lang:java decode:true\">SnapPagerScrollListener listener = new SnapPagerScrollListener(\r\n    pagerSnapHelper,\r\n    SnapPagerScrollListener.ON_SCROLL,\r\n    true,\r\n    new SnapPagerScrollListener.OnChangeListener() {\r\n        @Override\r\n        public void onSnapped(int position) {\r\n            \/\/position \ubc1b\uc544\uc11c \uc774\ubca4\ud2b8 \ucc98\ub9ac                        \r\n        }\r\n    }\r\n);\r\nrecyclerView.addOnScrollListener(listener);<\/pre>\n<p>Callback\uc774 \ud2b8\ub9ac\uac70 \ub418\ub294 \uc2dc\uc810\uc744 \uc870\uc808\ud558\ub294 \ub450\uac00\uc9c0 Type\uc774 \uc788\uc2b5\ub2c8\ub2e4.<\/p>\n<ul>\n<li>ON_SCROLL : \uc2a4\ud06c\ub864\uc774 \ub420\ub54c \ucf5c\ubc31\uc744 \ubc1b\uace0 \uc2f6\ub2e4\uba74 \uc774 \ud0c0\uc785\uc744 \uc0ac\uc6a9<\/li>\n<li>ON_SETTLED : RecyclerView\uc758 State\uac00 SCROLL_STATE_IDLE\uc77c\ub54c, \uc989 \ud398\uc774\uc9c0\uac00 \ubcc0\uacbd\ub418\uace0 \uc644\uc804\ud788 \uba48\ucd9c\ub54c \uc774\ubca4\ucf5c\ubc31\uc744 \ubc1b\uace0 \uc2f6\ub2e4\uba74 \uc774 \ud0c0\uc785\uc744 \uc0ac\uc6a9\ud569\ub2c8\ub2e4.<\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>ViewPager\ub9cc\ub4e4\uae30 ViewPager2\uc640 \ubc29\uc2dd\uc740 \ube44\uc2b7\ud558\uc9c0\ub9cc, \uc544\uc9c1 \uc815\uc2dd \ub9b4\ub9ac\uc988\uac00 \ub098\uc624\uc9c0 \uc54a\uc558\uc2b5\ub2c8\ub2e4. \uae30\uc874\uc5d0 RecyclerView\uac00 \uad6c\ud604\uc774 \ub418\uc5b4\uc788\ub2e4\uba74 PagerSnapHelper\ub9cc \ucd94\uac00\ud558\uba74 \ub41c\ub2e4. MyAdapter adapter = &#8230; recyclerView.setAdapter(adapter); recyclerView.setLayoutManager(new LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false)); \/\/ PagerSnapHelper \ucd94\uac00 PagerSnapHelper snapHelper = new PagerSnapHelper(); snapHelper.attachToRecyclerView(recyclerView); &nbsp; Indicator \ucd94\uac00\ud558\uae30 RecyclerView\uc5d0\ub294 ItemDecoration\uc744 \uc774\uc6a9\ud574\uc11c Indicator\ub97c \uadf8\ub9b4\uc218 \uc788\uc2b5\ub2c8\ub2e4.\u00a0 \uc800\ub294 LinePagerIndicatorDecoration \ucc38\uace0\ud574\uc11c \uadf8\ub824\ubcf4\uc558\uc2b5\ub2c8\ub2e4. recyclerView.addItemDecoration(new LinePagerIndicatorDecoration()); SnapPagerScrollListener [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"om_disable_all_campaigns":false,"inline_featured_image":false,"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0},"categories":[25],"tags":[],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/charlezz.com\/index.php?rest_route=\/wp\/v2\/posts\/1329"}],"collection":[{"href":"https:\/\/charlezz.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/charlezz.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/charlezz.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/charlezz.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1329"}],"version-history":[{"count":1,"href":"https:\/\/charlezz.com\/index.php?rest_route=\/wp\/v2\/posts\/1329\/revisions"}],"predecessor-version":[{"id":1332,"href":"https:\/\/charlezz.com\/index.php?rest_route=\/wp\/v2\/posts\/1329\/revisions\/1332"}],"wp:attachment":[{"href":"https:\/\/charlezz.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1329"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/charlezz.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1329"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/charlezz.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1329"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}