감자주먹밥

[Java] TabLayout ViewPager2를 이용한 바텀네비게이션 ! 본문

Android

[Java] TabLayout ViewPager2를 이용한 바텀네비게이션 !

JustHm 2021. 6. 28. 22:38
728x90

 

 

그림 그리기 귀찮아서 이상해요..

완성 화면이긴 한데 이미지 넣기도 귀찮고해서 좀 아가장난 같다..

Fragment를 사용하여 페이징했다.

일단 밑에는

레이아웃

	<androidx.viewpager2.widget.ViewPager2
        android:id="@+id/viewPager2"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        app:layout_constraintBottom_toTopOf="@+id/tabLayout"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <com.google.android.material.tabs.TabLayout
        android:id="@+id/tabLayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:tabMode="fixed"
        app:tabGravity="fill"
        android:background="@color/gray"
        app:tabIndicatorHeight="0dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent">
    </com.google.android.material.tabs.TabLayout>

tabIndicatorHeight 속성은 기본적으로 탭 아래쪽 선택되었을때 있는 구분선을 0dp로 설정해서 안보이게 한 것

 

ViewPager2 어댑터 설정

public class FspAdapter extends FragmentStateAdapter {
    public FspAdapter(@NonNull FragmentActivity fragmentActivity) {
        super(fragmentActivity);
    }

    @NonNull
    @Override
    public Fragment createFragment(int position) {
        // Return a NEW fragment instance in createFragment
        switch(position){
            case 0:
                return boardFragment.newInstance();
            case 1:
                return SettingFragment.newInstance();
            case 2:
                return ChatFragment.newInstance();
            default:
                return null;
        }
    }

    @Override
    public int getItemCount() {
        return 3;
    }
}

 

어댑터 설정은 사람마다 다 하는법이 다른 줄 알았다.. 근데 RecyclerAdapter를 쓰는 것은 레이아웃만 사용할때?

Fragment를 사용할 땐 FragmentStateAdapter를 상속받아 쓴다고 하던데.. 맞는지는 모르겠다.

일단 Android Docs랑 가장 비슷한 블로그 두 개 번갈아 가며 만들어봤다.

 

FragmentStateAdapter 상속받은 후

createFragment에 생성할 Fragment를 return해준다.

ItemCount가 몇개인지 따라 createFragment 호출 횟수가 정해지는거 같다.

 

newInstance는 Fragment에서 설정해준다.

public class boardFragment extends Fragment {

    public static boardFragment newInstance() {
        Bundle args = new Bundle();
        boardFragment fragment = new boardFragment();
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

    }


    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        return LayoutInflater.from(inflater.getContext()).inflate(R.layout.board_layout, container, false);
    }
}

 

https://m.blog.naver.com/PostView.nhn?blogId=tpgns8488&logNo=220989078813&proxyReferer=https:%2F%2Fwww.google.com%2F

Android Fragment newInstance()로 생성하는 이유

newInstance를 해 주는 이유는 이 블로그에서 참고

 

 

유의해야 할 점도 있다. 밑 블로그 참고

https://black-jin0427.tistory.com/250

[Android, FragmentFactory] framgnet에서 newInstance() 쓰지 말라고?

 

 

마지막으로 Activity에서 설정 !

protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main_layout);

        TabLayout tabLayout = findViewById(R.id.tabLayout);
        ViewPager2 viewPager = findViewById(R.id.viewPager2);

        FspAdapter fspAdapter = new FspAdapter(this);
        viewPager.setAdapter(fspAdapter);

        new TabLayoutMediator(tabLayout, viewPager, new TabLayoutMediator.TabConfigurationStrategy() {
            @Override
            public void onConfigureTab(@NonNull TabLayout.Tab tab, int position) {
                ImageView imageView = new ImageView(MainActivity.this);
                imageView.setImageResource(R.drawable.settings_selection);
                tab.setCustomView(imageView);
            }
        }).attach();

    }

 

TabLayout, ViewPager2 연결부터 시켜주고 아까만든 어댑터를 viewpager에 연결시켜준다.

 

TabLayoutMediator를 통해 Tab을 생성하여준다. 알아서 fragment랑 연결이 되는 것 같다..

 

onConfigureTab 안에 코드를 보면

ImageView를 통해 tab의 customView를 설정해주었다.

이렇게 하면 Indicator 적용이 안되어 탭을 눌러도 이미지 색이 바뀌지 않았다.

 

해결방법은 두 가지.

1. setCustomView 말고 setIcon으로 설정해주기

setIcon(R.drawable.~~) 넣어줘서 해 보니 Indicator 색에따라 잘 변했다.

 

2. 그대로 ImageView를 사용하면서 drawable에 xml을 정의해준다.

<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!--    <item android:drawable="@drawable/selection_settings_small"-->
<!--        android:state_pressed="true" />-->
    <item android:drawable="@drawable/selection_settings_small"
        android:state_selected="true" />
    <item android:drawable="@drawable/settings_small" />
</selector>

 

주석처리 된 건 누른 상태일때 바뀌는 이미지다.

state_selected = true로 되어있으면 상태를 확인하고 일치하면 이미지를 바꿔준다.

 

이렇게 하면 완성 !

 

 

 

728x90
Comments