Android #9 - ViewPager, Fragment (국비35일차)

 

오늘은 AdapterView의 종류 중 하나인

Viewpager와 Fragment에 대해서 공부할 예정이다.

 

목차

1. ViewPager
2. Fragment(xml)
3. Fragment(java로)
4. Tab과 Pager 붙이기

 

 

 

 

 

 

 

 

 

 

1. ViewPager

 

뷰페이저는 한 페이지에 하나의

사진 혹은 아이템뷰가 있는 형태로

틴더 같은 형태라고 생각하면 

이해하기 쉬울 것이다.
(스와이프를 통해 다음 페이지로 이동)

 

etc-image-0

새로운 프로젝트를 만들어서

activity_main에 레이아웃을 설정하고

뷰페이저를 코딩하자.

Viewpager2 (2번째 버전이다.)

 

 

etc-image-1

그 후 자바파일에

데이터를 넣어둘 

ArrayList를 만들고

데이터를 추가한다.
(실무에선 서버나 db에서 읽어옴)

 

etc-image-2

그리고 새로운 레이아웃 파일을 만들어준다.
(뷰페이지의 형태를 설정하기 위해)

 

etc-image-3

그 후 뷰페이저에 넣을

이미지 뷰를 만들어주고

etc-image-4

새로운 자바 클래스를 만들자.

어답터를 만들 것이다.

 

etc-image-5

우선 이너클래스로

VH 클래스를 만들고 ViewHolder를 상속받아준다.

그리고 뷰홀더엔 내가 레이아웃에 넣은

뷰들을 넣어야 한다.

etc-image-6

VH 이너클래스를 만든 후

마이아답터 클래스에도

adapter를 상속받아준 후
(뷰페이저도 리사이클러뷰 아답터를 쓴다.)

<> 안에 방금 만든 VH를 넣어주자.

 

etc-image-7

그 후 아답터를 상속받았으니

추상메소드를 구현시켜야 한다.

빨간 줄 부분에 마우스를 올려 implement를 해서

위의 화면처럼 나오면 다 선택 후 ok 해주자.

etc-image-8

아답터에선

항상 context와 ArrayList를 만들고 시작하는 거 잊지 말자!

 

etc-image-9

그리고 생성자 역시 만들어줘야 한다.
(alt + insert 클릭)

 

etc-image-10
생성자

 

 

 

etc-image-11

그리고 저번 시간에 배운 것처럼

각각의 메소드

필요한 것들을 써주고

 

etc-image-12

메인 자바 파일로 와서

참조변수를 작성 후

etc-image-13

setAdapter 코딩을 해주면

 

etc-image-14

한 페이지씩 넘길 수 있는

뷰페이저를 사용할 수 있다.

 

 

 

2. Fragment

 

 

Fragment : View + Activity (별도 XML, 별도 Java)

 

원래 activity 에는

뷰들만 놓을 수 있었다.

그러나 Fragment도 놓을 수 있게 되었다.

그럼 Fragment가 하는 역할은 무엇일까?

바로 화면을 유동적으로 구사해 주게 도와준다.
(화면을 조각으로 분리해서 관리)

 

예제를 한번 해보자.

etc-image-15
etc-image-16

메인 액티비티 xml에

간단하게 뷰들을 넣어주고

etc-image-17

자바에 와서

버튼을 클릭했을 때

텍스트뷰에 보이는 글자가 바뀌게

설정을 했다.

 

etc-image-18

그리고 화면의 한 부분을 

나눠서 커스텀하기 위해

새로운 레이아웃 xml을 만들어준다.

이름은 fragment_my.xml

 

etc-image-19

그 부분에 내가 넣을

뷰들을 넣어주자.

etc-image-20

미리 보기를 보면 위와 같이 나타난다.

etc-image-21

이제 저 프레그먼트를 다룰

자바 클래스를 하나 만들어주자.

etc-image-22

이 자바 클래스는 꼭

Fragment를 상속받아야 한다.

etc-image-23

그리고 MainActivity에선 onCreat 메소드를 쓰지만

여기선 onCreateView 메소드를 사용한다.

 

etc-image-24

이 메소드 안에는 어답터에서도 했듯

inflater를 써주면 된다.

etc-image-25

그리고 Activity_main.xml로 와서

내가 fragment를 넣을 부분에

<fragment를 만들고

id 등 속성을 부여하고

name값을 넣어주면 된다.
(name에 방금 만든 MyFragment 자바 파일을 써주자)

 

etc-image-26

그럼 xml 미리 보기에

이렇게 나온다.

etc-image-27

실행을 해보면 내가 의도한 대로

잘 나오는 모습을 볼 수 있다.

etc-image-28

그런데 개발자들은 미리 보기가 회색으로 나오니까

답답할 수 있다. 

이때 layout 속성을 써서 fragment를 써주면

etc-image-29

미리보기 화면에서

바로 볼 수 있게 된다.

etc-image-30

 

 

근데 만일

프레그먼트 안에 있는 버튼으로

메인 액티비티의 변화를 주고 싶다면??

 

etc-image-31

우선 프레그먼트 xml에

버튼을 만들고

 

etc-image-32

프레그먼트 자바 파일에서

setOnClickListener를 만들어서

MainActivity를 소환해서

set을 해주면 된다.

 

 

반대로 메인액티비티에 있는

버튼에서 프레그먼트의 텍스트 뷰를

조정하려면?

etc-image-33

액티비티 메인 xml에

새로운 버튼을 만들고

자바로 와서

리스너를 만들어준다.

이때 FragmentManager를 만들어줘야 하는데

getSupportFragmentManager을 사용해야 한다.!!!
(이게 최신버전.. 그냥 매니저는 이전버전)

 

etc-image-34

그리고 매니저를 통해

finFragmentById로 Fragment를 가져와서

set 해주면 된다.

 

etc-image-35

 

하지만 이렇게

xml로 만들면

동적제어가 불가능하다 ㅜㅜ

 

 

3. Fragment(java로)

 

 

그럼 동적제어를 가능케 하려면

어떻게 해야 할까?

바로 Fragment를 자바로 구현해야 한다.

etc-image-36

우선 새로운 프로젝트를 만들고

메인 xml에 

프레그먼트가 놓일 뷰그룹을 만들어두자.
(여기선 LinearLayout으로 만들어둠)

etc-image-37

그리고 fragment를 위한 xml을 만들어서

뷰든 뭐든 내가 추가하거나 할 것을

넣어주자.
(이번 예제엔 시계를 넣어주었다.)

etc-image-38

그 후 MyFragment 자바 클래스 파일을 만들어서

Fragment를 상속받아주고

onCreateView를 만들어서

inflater를 해준다.

 

etc-image-39

메인 자바 파일로 와서

참조변수를 선언하고

setonClickListener를 익명클래스로 만든다.

그리고 프레그먼트의 동적 작업을 하기 위해

fragmentManager의 Transation이란

기능을 사용해야 한다.
(Transaction은 후에 더 자세히 다루겠다)

 

그리고 add를 통해 프레그먼트를 추가할 수 있는 능력을 주고

 commit까지 해주면 끝!

 

 

etc-image-40

근데 내비게이션 바를 눌렀을 때

추가한 프레그먼트를 줄이고 싶다면

addtoBackStack 메소드를 써주자.

 

 

그럼 위와 같은 결과물이 나온다.

 

 

 

 

4. Tab과 Pager 붙이기

 

etc-image-41

 

앱들을 보면

위와 같이

탭과 페이지가 붙어서 

탭을 누르거나 옆으로 스와이프 하면

페이지가 바뀌는 앱들이 있다.

이것을 한번 만들어보자.

 

 

우선 새로운 프로젝트를 만들자.

etc-image-42

새로운 fragment_tab1이라는

레이아웃 xml을 만들어주고

위와 같이 적당히 속성을 설정해 주자.

 

etc-image-43

그리고 똑같은 것을 2개 더 만들려고 하니

좌측 레이아웃 폴더에 있는

fragment_tab1.xml을 눌러서

컨트롤 c 누르고 바로 컨트롤 v

눌러서

이름만 바꿔서 복사해 준다.

 

etc-image-44

똑같은 방법으로 3까지 만들어주자.

etc-image-45

그리고 자바 클래스를 만들어주고

etc-image-46

inflate 해주자.!!!

etc-image-47

그 후 xml과 개수를 맞추기 위해서

이 자바 클래스 역시 눌러서

컨트롤 + c 해서

바로 컨트롤 + v 해주자.

etc-image-48

그리고 새로 아답터 클래스를 만들어주자.

etc-image-49

Fragment를 위한 아답터엔

FragmentStateAdapter를

상속해줘야 한다.

 

etc-image-50

상속받으면 추상메소드가 없어서

빨간 줄이 날 텐데

마우스를 그 부분에 올려서 implement를 해준다.

 

 

etc-image-51

그리고 alt + insert를 눌러서

생성자 또한 만들어주자.
(제일 위에 거)

 

etc-image-52

이제 프레그먼트가 3개니

배열로 객체를 만들어주고

MyAdapter 생성자 안에 각각의

Tab을 넣어주자.

 

etc-image-53

그 후 CreateFragment에서

return 값을 fragments[position]을
(각각의 순서에 맞는 프레그먼트를 주기 위해)

 

getItemCount엔

fragment의 배열 길이를 넣어주자.

 

etc-image-54

그리고 액티비티 메인으로 와서

TabLayout을 만들어주고

뷰페이저 역시 만들어준다.
(뷰페이저는 양 옆으로 스와이프 할 예정이라 horizontal을 속성으로 갖는다.)

 

etc-image-55

그 후 각종 참조변수를 선언해 준 다음

제일 먼저 setAdapter를 해주자.

 

그리고 tabLayout 참조변수에 뷰를 넣어주고

탭과 페이저를 연동하기 위해

TabLayoutMediator 객체를 만들어준다.

파라미터는 각각

1 - tabLayout을 넣는 곳이고
2 - 페이저를 넣는 곳이다.
3 - 익명 클래스를 만들어줘야 한다.

그리고 익명클래스 안엔 tab.setText( tabTitle[position] )을 하여

미리 만들어둔 탭 이름들을

탭에 넣어준다.

 

마지막으로 mediator.attach() 
(서로 붙이기)

를 해준다.

 

 

etc-image-56

그럼 탭과 페이저가 연결된 결과물이 나타난다.