AdapterView_ViewPager2&Fragment&Tab

소정·2023년 2월 20일
1

Android_with_Java

목록 보기
12/33

[1] ViewPager2

하나의 화면에 하나의 Item만 들어간다
화면을 항목으로 본다, 한 화면에 항목 하나가 온다는 개념
책 넘기는 느낌이 나는 것
가로페이지만 지원하던 것이었는데 ViewPager2가 나오면서 세로도 지원

사용방법

결과 화면!

0. mainLayout에 ViewPager 준비

ViewPager2 로 Layout 만들어야함!
가로세로 정할 수 있어서 orientation 설정

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
    android:orientation="vertical"
    tools:context=".MainActivity">

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

    <Button
        android:id="@+id/btn_prev"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="PREV"/>

    <Button
        android:id="@+id/btn_next"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:text="NEXT"
        />


</RelativeLayout>

1. 아답터에서 보여줄 대량의 데이터 임의로 준비

package com.bsj0420.ex29viewpager;

import java.util.ArrayList;

public class MainActivity extends AppCompatActivity {

    ArrayList<Integer> imgIds = new ArrayList<>(); //그림 식별자 넣을것

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        //데이터 임의로 넣기
        imgIds.add(R.drawable.bg_one01);
        imgIds.add(R.drawable.bg_one02);
        imgIds.add(R.drawable.bg_one03);
        imgIds.add(R.drawable.bg_one04);
        imgIds.add(R.drawable.bg_one05);
        imgIds.add(R.drawable.bg_one06);
        imgIds.add(R.drawable.bg_one07);
        imgIds.add(R.drawable.bg_one08);
        imgIds.add(R.drawable.bg_one09);
        imgIds.add(R.drawable.bg_one10);

    }
}

2. ViewPager에 보여질 모양 layout 만들기

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ImageView
        android:id="@+id/iv"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scaleType="centerCrop"
        android:src="@drawable/bg_one01" />

</RelativeLayout>

3. adpter (extends RecyclerView.Adapter<ViewHolder.>)

adpter 만들어서 데이터와 레이아웃을 합치기
1.Adapter 상속받기 (extends RecyclerView.Adapter<제네릭>)
2.제네릭으로 쓸 뷰홀더 이너클래스로 ViewHolder 클래스 만들기

🧨 ViewHolder : View페이지 안의 나열되어 있는 아이템들을 참조변수로 가지고 있는 애

  1. context와 데이터 받아올 변수 준비 + 생성자 초기화
  2. onCreateViewHolder : 아이템뷰를 xml시안대로 만드는 곳
  3. onBindViewHolder : 불러온 layout과 뷰홀더 합체, 셋팅 당담
package com.bsj0420.ex29viewpager;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

import java.util.ArrayList;

//1. extends Adapter
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.VH> {
    //3. context와 데이터 받아올 변수 준비 + 생성자 초기화
     Context context;

     ArrayList<Integer> imgIds;

    public MyAdapter(Context context, ArrayList<Integer> imgIds) {
        this.context = context;
        this.imgIds = imgIds;
    }

    //4. 아이템뷰를 xml시안대로 만드는 곳
    @NonNull
    @Override
    public VH onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        //3-1) xml에 Layout을 LayoutInflater로 쭉쭉 읽어 와서 View로 리턴받기
        View itemView = LayoutInflater.from(context).inflate(R.layout.page, parent,false);

        //4-2) 
        VH holder = new VH(itemView); //뷰 홀더는 itemView의 안의 아이템들을 참조변수로 가지 고 있는 애
        
        return holder;
    }

    //5. 셋팅 당담
    @Override
    public void onBindViewHolder(@NonNull VH holder, int position) {
        holder.iv.setImageResource(imgIds.get(position)); 
        // holder = 현재 레이아웃을 붙잡고 있는 애
    }

    @Override
    public int getItemCount() {
        return imgIds.size();
    }

    //2.제네릭으로 쓸 뷰홀더 이너클래스로 ViewHolder 클래스 만들기
    class VH extends RecyclerView.ViewHolder {

        //2-1 ) 아이템 페이지에 있는 View 나열
        ImageView iv;

        public VH(@NonNull View itemView) { //무조건 itemView하나는 받도록 해서 implement
            super(itemView);

            iv = itemView.findViewById(R.id.iv); //연결해주기
        }
    }

}

4. 메인.java에서 출력

아답터 나와야 하는 adaperView와 내가 만든 아답터 참조변수로 가져와서 set해주기!

이전페이지와 다음페이지 보여주는 버튼도 붙여보자

package com.bsj0420.ex29viewpager;

import androidx.appcompat.app.AppCompatActivity;
import androidx.viewpager2.widget.ViewPager2;

import android.os.Bundle;
import android.view.View;
import android.widget.Button;

import java.util.ArrayList;

public class MainActivity extends AppCompatActivity {

    ArrayList<Integer> imgIds = new ArrayList<>(); //그림 식별자 넣을것

    //4. 아답터 페이지에 보이기
    //아답터 나와야 하는 adaperView와 내가 만든 아답터 가져오기
    ViewPager2 pager2;

    MyAdapter adapter;

    Button btn_prev, btn_next;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        //데이터 임의로 넣기
        imgIds.add(R.drawable.bg_one01);
        imgIds.add(R.drawable.bg_one02);
        imgIds.add(R.drawable.bg_one03);
        imgIds.add(R.drawable.bg_one04);
        imgIds.add(R.drawable.bg_one05);
        imgIds.add(R.drawable.bg_one06);
        imgIds.add(R.drawable.bg_one07);
        imgIds.add(R.drawable.bg_one08);
        imgIds.add(R.drawable.bg_one09);
        imgIds.add(R.drawable.bg_one10);

        pager2 = findViewById(R.id.pager);
        adapter = new MyAdapter(this, imgIds);
        pager2.setAdapter(adapter);



        //
        btn_prev = findViewById(R.id.btn_prev);

        btn_prev.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //뷰페이저의 현재 위치 인덱스 얻어오기
                int position = pager2.getCurrentItem();

                //현재 위치 이전 번호로 지정
                pager2.setCurrentItem(position-1, true);
            }
        });

        btn_next = findViewById(R.id.btn_next);

        btn_next.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                int position = pager2.getCurrentItem();

                pager2.setCurrentItem(position+1, false);
            }
        });

    }
}

[2] Fragment

페이지를 넘겼을때마다 viewLayout의 모양이 다르게 할때 사용

Fragment는 뷰의 특징을 가지고 있음
Fragment가 리턴해주는 걸 액티비티가 보여준다 뷰를 여러개 만들면 그것을 제어할 참조변수들을 나열해야하는데 별도의 xml 에 따로 만들어서 제어

Fragment가 Activity의 일부분처럼 자리를 차지하는데 참조변수를 제어할 수 있는 java를 가질수 있다 메인 Activity에서 분리해서 역할 분담을 하는 느낌
Activity 안엔 다른 Activity가 들어갈 수 없음

사용방법

1) Fragment를 MainActivity에 XML로 만들기

1. Fagment 화면 xml 파일을 layout 폴더에 만듦


2. Fagment 화면을 별도로 제어할 .java 파일 만들기

이 Fragment가 화면에 보여줄 뷰를 만들어서 리턴해주면 액티비티가 보여줌

1) extends Fragment 하기
2) 콜백메소드 onCreateView() 만들기

package com.bsj0420.ex30fragment;

import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;

public class MyFragment extends Fragment {

    TextView tv;
    Button btn;

    //이 Fragment가 화면에 보여줄 뷰를 만들어서 리턴해주면 액티비티가 보여줌
    //이를 위해 자동으로 호출되는 콜백메소드 : onCreateView
    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        //fragment_my.xml 에 설계한 뷰를 객체를 생성하여 리턴
        //ViewGroup container = 플래그먼트가 붙을 곳
        View view = inflater.inflate(R.layout.fagment_my, container, false);
        
        return view;
    }
}

3. Fagment가 자리할 Activity.xml에 <fragmet'/> 키워드로 자리 만들어놓기

  • android:name="com.bsj0420.ex30fragment.MyFragment"
    fragment 태그의 name속성에 플래그먼트 클래스 지정
<?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"
    android:orientation="vertical"
    android:padding="16dp"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/tv"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="TextView inside MainAtivity"
        android:textColor="@color/black"
        android:padding="8dp"
        />

    <Button
        android:id="@+id/btn"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="chage Text"/>

    <!--
     fragment로 화면의 한 조각을 만들기
     -->
    <fragment
        android:id="@+id/frag_my"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:name="com.bsj0420.ex30fragment.MyFragment
        tools:layout="@layout/fagment_my""/>


</LinearLayout>

💡 플래그먼트 미리보기 속성
tools:layout="@layout/fagment_my"


4 Fragment 참조변수 제어하기

Fragment.java 에 가서 내거 제어

package com.bsj0420.ex30fragment;

import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;

public class MyFragment extends Fragment {

    TextView tv;
    Button btn;

    //이 Fragment가 화면에 보여줄 뷰를 만들어서 리턴해주면 액티비티가 보여줌
    //이를 위해 자동으로 호출되는 콜백메소드 : onCreateView
    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        //fragment_my.xml 에 설계한 뷰를 객체를 생성하여 리턴
        //ViewGroup container = 플래그먼트가 붙을 곳
        View view = inflater.inflate(R.layout.fagment_my, container, false);
        //view = LinearLayout

        tv = view.findViewById(R.id.tv);
        btn = view.findViewById(R.id.btn);

        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                tv.setText("플래그먼트 나 바뀐다");
            }
        });
        
        return view;
    }
}

메인액티비티에 있는 viewItem 를 제어해보기

MainActivity ma = (MainActivity) getActivity();
플래그 먼트 안에서 액티비티 부르는 법

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="16dp"
    android:background="#FFFFFF00">

    <TextView
        android:id="@+id/tv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="TextView inside MyFragment"
        android:textColor="@color/black"
        android:padding="8dp"/>

    <Button
        android:id="@+id/btn"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="change Text"/>

    <Button
        android:id="@+id/btn2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="chage Text for MainActivity"
        android:backgroundTint="@color/black"/>

</LinearLayout>
package com.bsj0420.ex30fragment;

import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;

public class MyFragment extends Fragment {

    TextView tv;
    Button btn, btn2;

    //이 Fragment가 화면에 보여줄 뷰를 만들어서 리턴해주면 액티비티가 보여줌
    //이를 위해 자동으로 호출되는 콜백메소드 : onCreateView
    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        //fragment_my.xml 에 설계한 뷰를 객체를 생성하여 리턴
        //ViewGroup container = 플래그먼트가 붙을 곳
        View view = inflater.inflate(R.layout.fagment_my, container, false);
        //view = LinearLayout

        tv = view.findViewById(R.id.tv);
        btn = view.findViewById(R.id.btn);

        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                tv.setText("플래그먼트 나 바뀐다");
            }
        });

        //Main에 있는 Text 바꾸기
        btn2 = view.findViewById(R.id.btn2);
        btn2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //플래그먼트.java 안에서 액티비티를 소환해야한다
                MainActivity ma = (MainActivity) getActivity(); //플래그 먼트 안에서 액티비티 부르는 법

                ma.tv.setText("Good");

            }
        });
        
        return view;
    }
}

메인액티비티에서 Fragment 거 제어하기

FragmentManager manager = getSupportFragmentManager();
반드시 서포트 버전!

<?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"
    android:orientation="vertical"
    android:padding="16dp"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/tv"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="TextView inside MainAtivity"
        android:textColor="@color/black"
        android:padding="8dp"
        />

    <Button
        android:id="@+id/btn"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="chage Text"/>

    <!--
    fragment의 것 제어하기 위한 버튼
    -->
    <Button
        android:id="@+id/btn2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="change my Fragment"
        android:backgroundTint="#FFFF0000"
        />

    <!--
     fragment로 화면의 한 조각을 만들기 : XML에 붙이기
     => 이 액티비티와 완전 한몸이 돼서 뜯어낼 수 없다, 동적제어 불가
     add, remove, replace 안됨
     -->
    <fragment
        android:id="@+id/frag_my"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:name="com.bsj0420.ex30fragment.MyFragment"
        tools:layout="@layout/fagment_my"/>

</LinearLayout>
package com.bsj0420.ex30fragment;

import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;


import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {

    TextView tv;
    Button btn, btn2;

    //플래그먼트
    MyFragment myFragment;

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

        tv = findViewById(R.id.tv);
        btn = findViewById(R.id.btn);

        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                tv.setText("Nice to meet you");
            }
        });

        //플래그먼트 제어하기
        btn2 = findViewById(R.id.btn2);
        btn2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //내 플래그먼트 찾아서 참조
                //플래그먼트는 새로 추가된 기능임 화면에 보여줄 것들이 많이지면서 뷰를 여러개 나눠 제어 할 필요성 때문에 나옴
                //액티비티는 플래그먼트와 완전 분리, 그래서 플래그먼트 관리하는 별도의 관리자 따로 줌

                //Fragment 관리자 소환 : FragmentManager
                FragmentManager manager = getSupportFragmentManager(); //반드시 서포트 버전!

                myFragment = (MyFragment) manager.findFragmentById(R.id.frag_my);

                myFragment.tv.setText("메인에서 바꾸기!");

            }
        });

    }
}



2) Fragment를 액티비티.java에서 출력

  • 코드에서 플래그먼트 객체 생성하여 화면에 출력하기
  • 코드에서 플래그먼트를 동적으로 제어(add, remove, replace) 하여면 FragmentManager로 만든 FragmentTransation 클래스 함수를 사용해야됨!

💡 Transaction
롤백 기능이 있는 프로세스
중간에 코드가 실행이 안되면 처음으로 돌아감
ex) 송금


작업 순서

activity_main.xml

fragment 보일 공간 ViewGrop으로 준비****

<?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:orientation="vertical"
    android:padding="16dp"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <Button
        android:id="@+id/btn"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="추가"
        android:textAllCaps="false"/>

    <!--
        프래그먼트가 보여질 ViewGrop 준비
     -->
    <LinearLayout
        android:id="@+id/container_fragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

    </LinearLayout>

</LinearLayout>

fragment_my.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <AnalogClock
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

</RelativeLayout>

MyFragment.java

package com.bsj0420.ex31fragmentwithjava;

import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;

public class MyFragment extends Fragment {

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {

            View view = inflater.inflate(R.layout.fragment_my, container, false);

            return view;
    }
}

MainActivity.java

순서

① 프래그 먼트 시작
FragmentTransaction transaction =manager.beginTransaction();
② 하고 싶은 프래그 먼트 동작 추가 (add, remove, replace)
③ 작업 완료
transaction.commit();

package com.bsj0420.ex31fragmentwithjava;

import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;

import android.os.Bundle;
import android.view.View;
import android.widget.Button;

public class MainActivity extends AppCompatActivity {

    Button btn;

    //플래그먼트 제어용 매니저
    FragmentManager manager ;

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

        //프래그먼트 관리자 소환
        manager = getSupportFragmentManager();

        btn = findViewById(R.id.btn);

        //버튼 누르면 플래그 먼트 추가!
        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //아이디가 container_fragment인 뷰 그룹에 myFragment붙이기
                //프래그먼트에 동적(add, remove, replace) 작업 시작
                //add 해보기
                FragmentTransaction transaction =manager.beginTransaction(); //롤백 기능이 있는 프로세스

                //프래그 먼트 동작 추가
                transaction.add(R.id.container_fragment, new MyFragment());
                //(프래그먼트 붙을곳, 내가 만든 프래그먼트 객체)

                //뒤로가기 버튼 눌렀을 떄 추가 이전 상태로 돌아가려면
                transaction.addToBackStack(null);

                //작업 완료
                transaction.commit();

            }
        });



    }
}



[3] FragmentStateAdapter 사용해보기!

  • FragmentStateAdapter Adapter에서 프래그먼트 화면 각각 layout 조합해주는 extends 키워드~!
  • 항목을 프래그먼트로 작성하였다면 FragmentStateAdapter로 뷰페이저2를 구현해야한다!

작업 순서


① tab누르면 나올 Fragment 화면과 자바파일 만들기
② FragmentStateAdapter 를 상속받은 Adapter.java 만들기
③ MainActivity.layout에서 Adapter로 만든 Fragment 들어올 자리 만들어주기
④ TabLayoutMediator (tab레이아웃과 pager의 중재자)를 이용해서 화면 set하기
tab레이아웃과 pager의 중재자

결과화면

1.FragmeFragment 화면과 자바파일 생성

현재 각각 3개씩 생성

FragmeFragment.java

① extends Fragment
② onCreateView() 메소드에서 inflater로 xml 파일 읽어옴
③ onCreateView가 실행 된 후 만들어진 view에 여러가지 설정 작업을 위해 실행되는 콜백 메소드 :: onViewCreated()

package com.bsj0420.ex32fragmentpager;

import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;

public class Tab1Fragment extends Fragment {

    TextView tv;
    Button btn;

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {

        View view = inflater.inflate(R.layout.fragment_tab1, container,false);

        return view;
    }

    //onCreateView가 실행 된 후 만들어진 view에 여러가지 설정 작업을 위해 실행되는 콜백 메소드 :: onViewCreated
    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        tv = view.findViewById(R.id.tv);
        btn = view.findViewById(R.id.btn);

        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                tv.setText("안녕하세요");
            }
        });
    }
}

2. Adapter만들기 (extends FragmentStateAdapter)

  • 반드시 생성자로 FragmentMAnager를 꼭 받아야함!!!!
package com.bsj0420.ex32fragmentpager;

import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.viewpager2.adapter.FragmentStateAdapter;

public class MyAdapter extends FragmentStateAdapter {
    //bind는 필요없음
    //반드시 생성자로 FragmentMAnager를 꼭 받아야함!!!!

    //현재 이 코드는 대량의 데이터를 만드는 게 아니고 프래그먼트 3개만 생성하는 adapter 
    //프래그먼트 3개 받을 배열 만들어 놓기
    Fragment[] fragments = new Fragment[3];
    
    public MyAdapter(@NonNull FragmentActivity fragmentActivity) {
        super(fragmentActivity);
		// 생성자에서 배열 초기화 
        // 탭화면을 각각 연결해줌!
        fragments[0] = new Tab1Fragment();
        fragments[1] = new Tab2Fragment();
        fragments[2] = new Tab3Fragment();

    }

    @NonNull
    @Override
    public Fragment createFragment(int position) {
        return fragments[position]; //position 은 현재 만들어야할 index번호
    }

    @Override
    public int getItemCount() {
        return fragments.length;
    }
}

3. Main.xml 동적으로 플래그먼트 생성할 자리 정하기

또한 Tab레이아웃 (com.google.android.material.tabs.TabLayout) 키워드를 통해 탭 레이아웃 지정

<?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"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <!-- Tab만들기   -->
    <com.google.android.material.tabs.TabLayout
        android:id="@+id/tab_layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        />

    <!-- 프레그먼트 들어올 곳 -->
    <androidx.viewpager2.widget.ViewPager2
        android:id="@+id/pager"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="horizontal"/>

</LinearLayout>

4. main.java 만들어둔 fragment들과 어답터를 호출

  • 탭 버튼을 누를 때 화면 변경 작업 또한 해줌

① 참조변수로 불러오기
② 참조변수와 layout id 연결
TabLayoutMediator 탭 레이아웃과 뷰 페이저를 연동
onConfigureTab() 메소드는 탭의 숫자만큼 호출된다
④ mediator.attach(); 탭과 뷰 붙여주기!

package com.bsj0420.ex32fragmentpager;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.viewpager2.widget.ViewPager2;

import android.os.Bundle;

import com.google.android.material.tabs.TabLayout;
import com.google.android.material.tabs.TabLayoutMediator;

public class MainActivity extends AppCompatActivity {

    ViewPager2 pager2;
    MyAdapter adapter;

    TabLayout tabLayout;

    //문자열 배열 만들기 (탭의 타이틀 넣을 배열)
    String[] tabTitle = {"TAB1","TAB2","TAB3"};

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

        pager2 = findViewById(R.id.pager);

        adapter = new MyAdapter(this);

        pager2.setAdapter(adapter);

        tabLayout= findViewById(R.id.tab_layout);

        //*** 탭 레이아웃과 뷰 페이저를 연동하기 - 중재자(TabLayoutMediator) 객체이용
        TabLayoutMediator mediator = new TabLayoutMediator(tabLayout, pager2, new TabLayoutMediator.TabConfigurationStrategy() {
            @Override
            public void onConfigureTab(@NonNull TabLayout.Tab tab, int position) { //pager가 만든 탭 숫자만큼 호출
                //탭 이름 설정 하는 곳
                tab.setText(tabTitle[position]);

            }
        });

        //중재자 객체를 붙이기
        mediator.attach();

    }
}
profile
보조기억장치

0개의 댓글