Android(Java) - (2/2) ViewPager2를 이용하여 슬라이드로 프래그먼트 화면 전환하기 응용편

반응형

 

Overview

ViewPager2를 이용하여 프래그먼트간 슬라이드 화면 전환을 할 때

화면 아래의 텍스트 뷰(버튼 기능) 객체를 통해 ViewPager2의 현재 페이지가

어떤 프래그먼트인지 표현해주는 간이 BottomNavigationBar를 만드는 것을 목표로 합니다.

또한, 텍스트 뷰를 클릭하였을 때, ViewPager2의 화면이 해당 프래그먼트로 이동되는 버튼 기능을 구현합니다.

  • 총 2개의 뷰페이지, 2개의 프래그먼트로 앱 구성

 

기본편에서는...

  • 뷰페이저2를 이용하여 프래그먼트를 슬라이드로 화면 전환하는 기능을 구현하는 것을 목표로 합니다.
  • 응용편의 소스 코드보다 더 간단하게 구성되어 있으니 이해가 어렵다면 기본편을 참고해주세요.

Android(Java) - (1/2) ViewPager2를 이용하여 슬라이드로 프래그먼트 화면 전환하기 기본편

 

 

프로젝트 소스코드 다운로드

  • 이 포스팅에서 설명하는 프로젝트 소스 코드는 아래의 깃허브에서 다운로드 가능합니다.

https://github.com/luvris2/android-viewpager2-example

 

GitHub - luvris2/android-viewpager2-example

Contribute to luvris2/android-viewpager2-example development by creating an account on GitHub.

github.com


ViewPager 라이브러리 추가

build.gradle (Module)

  • dependencies에 viewpager2 라이브러리 추가
 
dependencies {
	...
    // ViewPager2
    implementation "androidx.viewpager2:viewpager2:1.1.0-beta01"
    ...
}

UI 디자인

activity_main (MainActivity)

  • 디자인

 

  • XML 코드
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <androidx.viewpager2.widget.ViewPager2
        android:id="@+id/viewPager2"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:orientation="horizontal">

        <TextView
            android:id="@+id/textView0"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:background="#4DFFFFFF"
            android:backgroundTint="#E29EFF"
            android:padding="20dp"
            android:text="Fragment1"
            android:textAlignment="center"
            android:textStyle="bold" />

        <TextView
            android:id="@+id/textView1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:background="#1AFFFFFF"
            android:backgroundTint="#E29EFF"
            android:padding="20dp"
            android:text="Fragment2"
            android:textAlignment="center"
            android:textStyle="bold" />
    </LinearLayout>
</RelativeLayout>

fragment_first (FirstFragment)

  • 디자인

 

  • XML 코드
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".FirstFragment">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal|center_vertical"
        android:text="Frag1"
        android:textSize="60sp" />
</FrameLayout>

fragment_second (SecondFragment)

  • 디자인

 

  • XML 코드
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".SecondFragment">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal|center_vertical"
        android:text="Frag2"
        android:textSize="60sp" />
</FrameLayout>

구현 (코딩)

MainActivity

  • 뷰페이저2를 보여주고 슬라이드 할 메인 화면
  • 뷰페이저2 슬라이드 콜백 함수 구현 
    • 슬라이드 시 해당 프래그먼트에 맞는 텍스트뷰 색상을 진하게 변경
  • 하단의 BottomNavigationBar 역할을 하는 텍스트뷰 클릭 이벤트 구현
    • 클릭 시 지정한 프래그먼트를 뷰페이저2 화면에서 이동
import android.graphics.Color;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
import androidx.viewpager2.widget.ViewPager2;

public class MainActivity extends AppCompatActivity {
    // 뷰페이저2 인스턴스
    private ViewPager2 viewPager2;
    // 뷰페이저2를 보여줄 어댑터
    private ViewPager2Adapter adapter;

    // 텍스트뷰 버튼 객체 생성 : tvBtn1(왼쪽버튼), tvBtn2(오른쪽버튼)
    // 현재 뷰페이저2의 페이지 위치를 확인하기 위함
    TextView tvBtn1;
    TextView tvBtn2;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // 뷰페이저2 어댑터 설정
        viewPager2 = findViewById(R.id.viewPager2);
        adapter = new ViewPager2Adapter(this); // 어댑터 생성
        viewPager2.setAdapter(adapter);

        // 뷰페이저2의 페이지 전환 시 콜백 함수
        viewPager2.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
            @Override
            public void onPageSelected(int position) {
                super.onPageSelected(position);
                // 뷰페이저2의 페이지 인덱스를 확인하여 텍스트뷰 버튼 색상 변경
                CurrentPositionChk(position);
            }
        });

        // 텍스트뷰 버튼 객체 연결 : tvBtn1(왼쪽버튼), tvBtn2(오른쪽버튼)
        tvBtn1 = findViewById(R.id.textView0);
        tvBtn2 = findViewById(R.id.textView1);

        // 왼쪽 텍스트뷰 클릭 이벤트 : ViewPager2에서 Fragment1의 화면으로 이동
        tvBtn1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                viewPager2.setCurrentItem(0);
            }
        });

        // 오른쪽 텍스트뷰 클릭 이벤트 : ViewPager2에서 Fragment2의 화면으로 이동
        tvBtn2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                viewPager2.setCurrentItem(1);
            }
        });
    }

    // 뷰페이저2의 페이지 변경 시 페이지에 맞게 버튼의 색상을 변경해주는 함수
    public void CurrentPositionChk(int position) {
        // 프래그먼트 화면 인덱스 저장 함수
        int currentFragmentId = 0;

        // 페이지 인덱스 정보 저장
        if (currentFragmentId != position) { currentFragmentId = position; }

        // 텍스트뷰 버튼 객체 연결 : tvBtn1(왼쪽버튼), tvBtn2(오른쪽버튼)
        tvBtn1 = findViewById(R.id.textView0);
        tvBtn2 = findViewById(R.id.textView1);

        // 텍스트뷰 버튼 색상 정의 : 보라색, 현재 페이지의 위치를 구분하기 위해 선택된 페이지의 투명도를 더 높게 설정
        String BaseHexColor = "#E29EFF";
        int rgbColor = Color.parseColor(BaseHexColor);
        int selectedAlpha = 128;
        int deselectedAlpha = 25;

        // 첫번째 화면일 경우 왼쪽 버튼 활성화 표시 (배경색을 진하게 함)
        if (currentFragmentId == 0) {
            tvBtn1.setBackgroundColor(
                    Color.argb(selectedAlpha, Color.red(rgbColor), Color.green(rgbColor), Color.blue(rgbColor))
            );
            tvBtn2.setBackgroundColor(
                    Color.argb(deselectedAlpha, Color.red(rgbColor), Color.green(rgbColor), Color.blue(rgbColor))
            );
        }
        // 두번째 화면일 경우 오른쪽 버튼 활성화 표시 (배경색을 진하게 함)
        else if (currentFragmentId == 1) {
            tvBtn1.setBackgroundColor(
                    Color.argb(deselectedAlpha, Color.red(rgbColor), Color.green(rgbColor), Color.blue(rgbColor))
            );
            tvBtn2.setBackgroundColor(
                    Color.argb(selectedAlpha, Color.red(rgbColor), Color.green(rgbColor), Color.blue(rgbColor))
            );
        }
    }
}

ViewPager2Adapter

  • 뷰 페이저2의 화면을 보여줄 어댑터
  • 뷰 페이저2에 보여줄 화면의 개수와 보여줄 프래그먼트 설정
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.viewpager2.adapter.FragmentStateAdapter;

public class ViewPager2Adapter extends FragmentStateAdapter {
    // 뷰페이저에 보여줄 페이지 개수 설정
    private static final int NUM_PAGES = 2;

    // 프래그먼트로 구성된 어댑터일 경우 MainActivity가 아닌 Fragment로 초기화하여야 함
    public ViewPager2Adapter(@NonNull MainActivity mainActivity) {
        super(mainActivity);
    }

    @NonNull
    @Override
    public Fragment createFragment(int position) {
        // 반환할 프래그먼트 인스턴스 생성 및 초기화
        Fragment fragment = new FirstFragment();

        // 해당 위치(position)에 따라 프래그먼트 반환
        if (position == 0) // 첫번째 위치일 경우 FirstFragment 화면 반환
            fragment = new FirstFragment();
        else if (position ==1) // 첫번째 위치일 경우 FirstFragment 화면 반환
            fragment = new SecondFragment();

        // 위치에 따른 프래그먼트 반환
        return fragment;
    }

    @Override
    public int getItemCount() {
        return NUM_PAGES; // 전체 아이템 수 반환
    }
}

FirstFragment / SecondFragment

  • 뷰 페이저2에 표시될 프래그먼트
  • 두 개의 프래그먼트가 뷰 페이저에 구성되어 슬라이드로 화면 전환
// 추가 소스 코드 없음
// Fragment 생성 그대로의 소스 코드에서 건들지 않음

참고

Android developers - 가이드 - ViewPager2를 사용하여 탭으로 스와이프 뷰 만들기

반응형