본문 바로가기
공부기록/안드로이드

안드로이드 프래그먼트 안에 프래그먼트 - 인스타그램처럼 만들기

by 책읽는 개발자 ami 2021. 1. 25.
728x90
반응형

지금 프로젝트를 하고 있는 앱은 크게 home, 레시피, 재료나눔, 마이페이지 탭으로 구성되어 있다. (왼쪽)

인스타그램은 어떻게 구성되어 있는지는 모르겠지만, (오른쪽) 인스타그램 사진처럼 구성하고 싶었다.

한 프래그먼트 안에 또 3개의 프래그먼트(내글, 좋아요 누른 글, 스크랩한 글)로 페이지를 스와핑하여 게시물을 보여주는 방식이 목표!


mypage_layout.xml : TabLayout과 ViewPager 로 구성된 레이아웃

<?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:orientation="vertical"
    android:padding="20dp"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1">
        <com.google.android.material.tabs.TabLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:tabGravity="fill"
            app:tabMode="fixed"
            android:id="@+id/myPagetabLayout"
            />
    </LinearLayout>
    <LinearLayout
        android:layout_marginTop="10dp"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="8">
        <androidx.viewpager.widget.ViewPager
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:id="@+id/myPageviewPager"/>
    </LinearLayout>
</LinearLayout>

- TabLayout과 Viewpager의 비율은 1:8로 설정하였다.

Fragment_4.java : Fragment를 상속받는 클래스

public class Fragment_4 extends Fragment {
	private MyPageAdapter myPageAdapter;
	private TabLayout tabLayout;
    private ViewPager viewPager;
    private int tabCurrentIdx = 0;
    
	@Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
   		view = inflater.inflate(R.layout.mypage_layout, null, false);
        tabLayout = view.findViewById(R.id.myPagetabLayout);
        viewPager = view.findViewById(R.id.myPageviewPager);
        //피드 구성하는 탭레이아웃 + 뷰페이저
        tabLayout.addTab(tabLayout.newTab().setCustomView(customTabView(R.drawable.gallery)));
        tabLayout.addTab(tabLayout.newTab().setCustomView(customTabView(R.drawable.emptyheart)));
        tabLayout.addTab(tabLayout.newTab().setCustomView(customTabView(R.drawable.favorite)));
        //커스텀 어댑터 생성
        myPageAdapter = new MyPageAdapter(getChildFragmentManager(),tabLayout.getTabCount());
        viewPager.setAdapter(myPageAdapter);
        viewPager.setCurrentItem(tabCurrentIdx);
        viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
        tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener(){
                @Override
                public void onTabSelected(TabLayout.Tab tab) {
                    viewPager.setCurrentItem(tab.getPosition());
                    tabCurrentIdx = tab.getPosition();
                }
                @Override
                public void onTabUnselected(TabLayout.Tab tab) {

                }
                @Override
                public void onTabReselected(TabLayout.Tab tab) {

                }
            });
    }
}

- 탭을 해서 View를 변경하기 때문에 TabLayout을 사용한다.

- 여기서 제일 중요한건 getChildFragmentManager() 이다. 이걸 몰라서 헤맸었음..

android developer

공식 홈페이지에 나와있는 설명인데, 중요한 부분은 이거다. "Fragments inside of this Fragment" 보통 프래그먼트 매니저를 쓸 땐 getFragmentManager를 쓰는데, 프래그먼트 안에 프래그먼트를 관리할 때는 꼭 Child가 붙은 매니저를 써야한다.

제가 계속 getFragmentManager를 쓰다가 뭔가 되는데, 어떤 경우에는 안 뜨고 그러는 경험을 계속 했기 때문에 강조합니다..ㅎㅎ

- addOnPageChangeListner(new TabLayout.TabLayoutOnPageChangeListener(tabLayout))도 꼭 필요하다.

android developer
android developer

 

뷰페이저와 탭레이아웃이 sync 되어 관리되려면 위와 같이 써야한다고 한다.


MypageAdapter.java : FragmentStatePagerAdapter 상속받은 클래스

public class MyPageAdapter extends FragmentStatePagerAdapter {
    private int numberOfFragment;
    public MyPageAdapter(FragmentManager fm, int numberOfFragment){
        super(fm, FragmentStatePagerAdapter.BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT);
        this.numberOfFragment = numberOfFragment;
    }

    @NonNull
    @Override
    public Fragment getItem(int position) {
        switch (position){
            case 0: return new Fragment_4_Mypost();
            case 1: return new Fragment_4_Likepost();
            default: return new Fragment_4_ScrapRecipe();
        }
    }

    @Override
    public int getCount() {
        return numberOfFragment;
    }
}

Fragment_4_Mypost, Likepost, ScrapRecipe 에는 본인이 보여주고 싶은 페이지를 만들면 된다.

이와 관련해서는 다음글에서 다뤄보겠다.

 

 

 

728x90
반응형