• 안드로이드 스튜디오 ViewPager2를 활용한 가로 슬라이더

    2021. 7. 27.

    by. 하루플스토리

    반응형

    안녕하세요, 하루플 입니다.

    Viewpager2

    위 이미지와 같은 가로 슬라이더 앱 만지면서 많이 보셨죠!

    단순히 RecyclerView를 쓰면 원하는 이미지에서 멈추지 않습니다.

    그냥 ListView를 가로로 돌린 것 뿐이죠.

    그래서 원하는 부분의 이미지를 슬라이딩하듯이 사용할 수 있도록 만들어보겠습니다.

    어려우시다면 아래 링크 Github를 이용하세요!

    완성된 Viewpager2 슬라이더 오픈소스 라이브러리 다운로드하기!

     

    Viewpager2는 Viewpager 라이브러리의 개선된 버전으로 , 향상된 기능을 제공하며 그냥 viewpager를 사용 시 발생하는 일반적인 문제를 해결할 수 있습니다.

    ViewPager2로 이전하여 얻을 수 있는 이점
    Viewpager2는 적극적인 개발 지원을 받고 있지만, Viewpager는 그렇지 않기 때문입니다.

    다음은 추가적인 Viewpager의 이점 입니다.
    - 세로 방향 지원
    - 오른쪽에서 왼쪽 지원
    - 수정 가능한 프래그먼트 컬랙션

    Viewpager2 더 살펴보기

     

     


    1. 종속성 추가

    build.gradle(Module)

    dependencies {
        implementation 'androidx.viewpager2:viewpager2:1.0.0'
        implementation 'me.relex:circleindicator:2.1.4'
        }

    꼭 Sync 해줍시다.

     

     

     

    2. Viewpager2 화면 제작

    activity_main.xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity"
        android:gravity="center">
    
        <FrameLayout
            android:layout_gravity="center"
            android:layout_width="400dp"
            android:layout_height="400dp">
    
            <androidx.viewpager2.widget.ViewPager2
                android:id="@+id/viewpager"
                android:layout_gravity="center"
                android:clipToPadding="false"
                android:clipChildren="false"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:scaleType="fitXY"
                android:layout_marginBottom="10dp"/>
    
            <me.relex.circleindicator.CircleIndicator3
                android:id="@+id/indicator"
                android:layout_width="match_parent"
                android:layout_height="48dp"
                android:layout_marginBottom="10dp"
                android:layout_gravity="bottom"/>
    
        </FrameLayout>
    
    </LinearLayout>

    FrameLayout으로 보일 이미지(ViewPager)와 CircleIndicator를 겹쳐주었습니다.

    CircleIndicator는 이미지를 넘길 때 이미지의 위치를 표시하는 효과 입니다.

     

     

     

     

    3. 들어갈 이미지 레이아웃 제작

    해당 부분에는 이미지를 넣거나 텍스트 등 넣고 싶은 대로 넣으시면 됩니다.

    다만, activity_main에서 FrameLayout과 크기가 동일해야 합니다.

    저는 단순히 여러분들에게 보여주기 위해 TextView 1개와 background에 컬러를 지정하였습니다.

     

    frame_1.xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"
        android:orientation="vertical">
    
        <TextView
            android:text="1"
            android:layout_width="400dp"
            android:layout_height="400dp"
            android:textSize="50dp"
            android:gravity="center"
            android:textColor="#000000"
            android:background="#FFCDD2"
            />
    
    </LinearLayout>

    저는 frame_1.xml ~ frame_4.xml 까지 4개의 레이아웃을 생성하였습니다.

    1~4의 레이아웃은 넘기면서 보일 원하는 화면을 만들면 됩니다.

     

     

     

     

    4. ViewPager2, CircleIndicator3 설정

    변수는 전역변수로 선언해주었습니다.

    여기서 MyAdapter 클래스가 없어 오류가 날 겁니다.

     

    MainActivity.java

    public class MainActivity extends AppCompatActivity {
    
        private ViewPager2 mPager;
        private FragmentStateAdapter pagerAdapter;
        private int num_page = 4;
        private CircleIndicator3 mIndicator;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            /**
             * 가로 슬라이드 뷰 Fragment
             */
    
            //ViewPager2
            mPager = findViewById(R.id.viewpager);
            //Adapter
            pagerAdapter = new MyAdapter(this, num_page);
            mPager.setAdapter(pagerAdapter);
            //Indicator
            mIndicator = findViewById(R.id.indicator);
            mIndicator.setViewPager(mPager);
            mIndicator.createIndicators(num_page,0);
            //ViewPager Setting
            mPager.setOrientation(ViewPager2.ORIENTATION_HORIZONTAL);
    
            /**
             * 이 부분 조정하여 처음 시작하는 이미지 설정.
             * 2000장 생성하였으니 현재위치 1002로 설정하여
             * 좌 우로 슬라이딩 할 수 있게 함. 거의 무한대로
             */
    
            mPager.setCurrentItem(1000); //시작 지점
            mPager.setOffscreenPageLimit(4); //최대 이미지 수
    
            mPager.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
                @Override
                public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
                    super.onPageScrolled(position, positionOffset, positionOffsetPixels);
                    if (positionOffsetPixels == 0) {
                        mPager.setCurrentItem(position);
                    }
                }
    
                @Override
                public void onPageSelected(int position) {
                    super.onPageSelected(position);
                    mIndicator.animatePageSelected(position%num_page);
                }
            });
        }
    
    }

    여기서 Circleindicator의 위치를 이미지의 위치와 동일하게 설정합니다.

    이제 MyAdapter.java 클래스를 생성해봅시다.

     

     

     

     

    5. 어탭터 설정

    어탭터에서 이미지 갯수를 리턴해줍니다. 이미지를 약 2000장 생성하여 사실상 무한대로 만들어줍시다. 2000번이나 한 방향으로 스크롤 하는 사람은 거의 없을테니까요..

    그래서 방금 MainActivity에서 이미지 시작 위치를 중간인 1000으로 설정한겁니다.

    저는 이미지가 4장이여서 1000으로 했지만 만약 6장이라면 6의 배수인 1002로 설정해야 첫번째 이미지가 올바르게 설정 됩니다. 즉, 본인의 이미지 갯수에 따라 유동적으로 값을 변경해주시면 됩니다.

     

    MyAdapter.java

    public class MyAdapter extends FragmentStateAdapter {
    
        public int mCount;
    
        public MyAdapter(FragmentActivity fa, int count) {
            super(fa);
            mCount = count;
        }
    
        @NonNull
        @Override
        public Fragment createFragment(int position) {
            int index = getRealPosition(position);
    
            if(index==0) return new Fragment_1();
            else if(index==1) return new Fragment_2();
            else if(index==2) return new Fragment_3();
            else return new Fragment_4();
        }
    
        @Override
        public int getItemCount() {
            return 2000;
        }
    
        public int getRealPosition(int position) { return position % mCount; }
    
    }

     

     

     

    6. Fragment 생성

    각 이미지를 받고 화면에 뷰를 표시해주는 Fragment를 생성해보겠습니다.

    저는 4장의 레이아웃을 아까 만들었으니 4개의 Fragment를 생성해보겠습니다.

    오류나는 부분은 import가 되지 않았기 때문이므로 Alt+ Enter를 통해 import 해줍시다!

     

    Fragment_1.java

    public class Fragment_1 extends Fragment {
    
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                                 Bundle savedInstanceState) {
            ViewGroup rootView = (ViewGroup) inflater.inflate(
                    R.layout.frame_1p, container, false);
    
            return rootView;
        }
    
    }

    이런게 R.layout.frame_1p 레이아웃만 원하는 xml과 매칭하면서 Fragment_1 ~ Fragment_4 까지 생성하였습니다.

    만약 Fragment_2.java 는 frame_2.xml 과 매칭하는 것이죠.

    이제 다 했습니다! 실행해보시면

    Viewpager2

     

    이렇게 가로 슬라이더가 올바르게 작동하는 것을 확인할 수 있습니다.

     

    어려우시다면 아래 링크 Github를 이용하세요!

    완성된 Viewpager2 슬라이더 오픈소스 라이브러리 다운로드하기!

     

    GitHub - haruple97/Open-Source-Library: 혼자 만든 오픈소스 공간 (Feel free to use it!)

    혼자 만든 오픈소스 공간 (Feel free to use it!). Contribute to haruple97/Open-Source-Library development by creating an account on GitHub.

    github.com

     

    반응형

    댓글