어제는 안드로이드에서 collapsingToolbarLayout을 이용하여 움직이는 상단바를 만들어보았다.
움직이는 상단바를 위해 필요한 xml 구조
<CoordinatorLayout> << CollapsingToolbarLayout을 사용하기 위해서는 꼭 CoordinatorLayout을 사용해야함
<AppBarLayout> << appBarLayout 안에 CollapsingToolbarLayout을 넣음
<CollapsingToolbarLayout> << 스크롤시 접히거나 나타날 부분을 넣는 layout
<ImageView/> << 접히거나 나타날 이미지
<Toolbar/> << 접혔을 때에도 남아있을 툴바
</CollapsingToolbarLayout>
</AppBarLayout>
<ViewPager2/> << 스크롤할 뷰 (NestedScrollView나, RecyclerView도 가능)
</CoordinatorLayout>
기본적으로 LinearLayout의 속성을 가지는 layout이다.
기본적으로 FrameLayout의 속성을 가지는 layout이다. 따라서 내부에 ImageView와 Toolbar를 넣으면 두 개의 뷰가 겹쳐보인다.
화면에 스크롤에 반응하여 접히거나 나타날 뷰들을 넣으면 된다.
xml 코드
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.google.android.material.appbar.CollapsingToolbarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:contentScrim="?attr/colorPrimary"
app:layout_scrollFlags="scroll|exitUntilCollapsed">
<!-- parallax: 스크롤 시 접힘 -->
<androidx.appcompat.widget.AppCompatImageView
android:src="@drawable/bts"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
app:layout_collapseMode="parallax"/>
<!-- pin: 스크롤 시 고정 -->
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
app:menu="@menu/menu_home_toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_collapseMode="pin"/>
</com.google.android.material.appbar.CollapsingToolbarLayout>
<!-- 뷰페이저와 연결할 탭 -->
<com.google.android.material.tabs.TabLayout
android:id="@+id/tabLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</com.google.android.material.appbar.AppBarLayout>
<!-- 뷰페이저 (layout_behavior를 "@string/appbar_scrolling_view_behavior"로 설정해야함! ) -->
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/viewPager2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_behavior="@string/appbar_scrolling_view_behavior"/>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
layout_scrollFlags="scroll|exitUntilCollapsed"
layout_scrollFlags는 화면을 스크롤 할 때, CollapsingToolbarLayout을 얼마나 가리고 보일 것인지 정하는 속성이며, 가질 수 있는 속성으로는 아래와 같은 것들이 있다.
이미지 구조는 아래 사진과 같다.
JAVA 코드
public class ExampleFragment extends Fragment {
Fragment fragment1, fragment2;
final int NUM_PAGES = 2;
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_example, container, false);
fragment1 = new FeedFragment();
fragment2 = new ArtistFragment();
// 툴바에 타이틀 넣기
Toolbar toolbar = view.findViewById(R.id.toolbar);
toolbar.setTitle("BTS");
// 뷰페이저에 어댑터 연결
ViewPager2 viewPager2 = view.findViewById(R.id.viewPager2);
viewPager2.setAdapter(new viewPagerAdapter(this));
viewPager2.setCurrentItem(0);
// 탭과 뷰페이저 연결
TabLayout tabLayout = view.findViewById(R.id.tabLayout);
TabLayoutMediator tabLayoutMediator = new TabLayoutMediator(tabLayout, viewPager2, new TabLayoutMediator.TabConfigurationStrategy() {
@Override
public void onConfigureTab(@NonNull TabLayout.Tab tab, int position) {
if(position == 0) {
tab.setText("Feed");
} else {
tab.setText("Artist");
}
}
});
tabLayoutMediator.attach();
return view;
}
// 뷰페이저2 어댑터
private class viewPagerAdapter extends FragmentStateAdapter {
public viewPagerAdapter(Fragment fragment) {
super(fragment);
}
@NonNull
@Override
public Fragment createFragment(int position) {
if(position == 0) {
return fragment1;
} else {
return fragment2;
}
}
@Override
public int getItemCount() {
return NUM_PAGES;
}
}
}
뷰페이저의 height를 wrap_content로 지정하면 오류가 생기네요... match_parent로 지정 했을 때는 정상작동이 되던데 혹시 이유를 알 수 있을 까요 ?