티스토리 뷰
안드로이드 (Android) 리사이클러뷰(RecyclerView)와 스티키스크롤(sticky scrollview), 탭(Tabs) 세가지를 함께사용하기 | 내려가면서 딱 붙는 UI ,
15051015 2020. 2. 13. 13:20안드로이드 (Android)에서 리사이클러뷰(RecyclerView)와 스티키스크롤(sticky scrollview), 탭(Tabs) 세가지를 함께사용해보도록 하겠습니다.
우선 세가지를 함께 사용한 xml입니다.
chckendetail.xml
<?xml version="1.0" encoding="utf-8"?>
<com.amar.library.ui.StickyScrollView
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:id="@+id/scroll_view"
app:stickyHeader="@+id/tabs"
android:fillViewport="true"
android:orientation="vertical">
<LinearLayout
android:paddingRight="10px"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
<fragment
android:id="@+id/map"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="200dp" />
<com.google.android.material.tabs.TabLayout
android:id="@+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabGravity="center"
app:tabMode="fixed"
app:tabTextColor="#444444"
app:tabSelectedTextColor="#000000"
android:background="#FFFFFF"
>
<com.google.android.material.tabs.TabItem
android:text="@string/menu"
android:layout_height="20dp"
android:layout_width="20dp" />
<com.google.android.material.tabs.TabItem
android:text="@string/information"
android:layout_height="20dp"
android:layout_width="20dp" />
<com.google.android.material.tabs.TabItem
android:text="@string/review"
android:layout_height="20dp"
android:layout_width="20dp" />
</com.google.android.material.tabs.TabLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="699dp"
android:background="#dddddd"
/>
</LinearLayout>
</com.amar.library.ui.StickyScrollView>
아직 아이템에 대한 세부사항은 나누어 두지 않았고, sticky해더가 tabs를 고정시키게만 설정해둔 상태입니다.
app:stickyHeader="@+id/tabs" 를 통해서 고정시킵니다.
<com.amar.library.ui.StickyScrollView 를 통해서 스티키 스크롤뷰를 사용합니다.
아래의 라이브러리를 통해 구현하였습니다. (사용법은 아래에 들어가면 readMe에 임포트 방법이 적혀있음)
https://github.com/amarjain07/StickyScrollView
<com.google.android.material.tabs.TabLayout 을 통해서 탭을 사용합니다.
<com.google.android.material.tabs.TabItem
android:text="@string/menu"
android:layout_height="20dp"
android:layout_width="20dp" />
탭 아이템을 통해 탭 메뉴를 정의합니다.
<androidx.recyclerview.widget.RecyclerView 를 통해서 리사이클러뷰를 사용합니다.
https://dreamaz.tistory.com/345이 글을 참고하여 리사이클러뷰를 만들었습니다.
여기서
이렇게하면 문제가 생기는데, 리사이클러뷰와 스티키 스크롤이 둘다 스크롤이여서 리사이클러뷰에 손을대고 스크롤을 하면 리사이클러뷰만 내려가 스티키가 정상작동 하지 않습니다.
저는 이 상황을
chickendetail.java
mRecyclerView.setNestedScrollingEnabled(false);
mScroll_sv.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if(!mScroll_sv.canScrollVertically(1))
{//최하단일때
mRecyclerView.setNestedScrollingEnabled(true);
}
else if(!mScroll_sv.canScrollVertically(-1))
{//최상단일때
mRecyclerView.setNestedScrollingEnabled(false);
}
else if(!mRecyclerView.canScrollVertically(-1)) {
mRecyclerView.setNestedScrollingEnabled(false);
}
else if(!mRecyclerView.canScrollVertically(1)) {
mRecyclerView.setNestedScrollingEnabled(true);
}
else {
//idle?
mRecyclerView.setNestedScrollingEnabled(false);
}
return false;
}
});
mRecyclerView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if(!mScroll_sv.canScrollVertically(1))
{//최하단일때
mRecyclerView.setNestedScrollingEnabled(true);
}
else if(!mScroll_sv.canScrollVertically(-1))
{//최상단일때
mRecyclerView.setNestedScrollingEnabled(false);
}
else if(!mRecyclerView.canScrollVertically(-1)) {
mRecyclerView.setNestedScrollingEnabled(false);
}
else if(!mRecyclerView.canScrollVertically(1)) {
mRecyclerView.setNestedScrollingEnabled(true);
}
else {
//idle?
mRecyclerView.setNestedScrollingEnabled(false);
}
return false;
}
});
이 코드를 추가함으로써 해결하였습니다.
최초의 상태에서는
mRecyclerView.setNestedScrollingEnabled(false);
리사이클러뷰의 스크롤을 비활성화 시킵니다.
mScroll_sv.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if(!mScroll_sv.canScrollVertically(1))
{//최하단일때 리사이클러뷰의 스크롤을 사용가능하게 만듬 ( 리사이클러뷰가 돌아가게 )
mRecyclerView.setNestedScrollingEnabled(true);
}
else if(!mScroll_sv.canScrollVertically(-1))
{//최상단일때 리사이클러뷰의 스크롤을 사용불가능으로 만듬 (탭 스티키가 정상 작동하도록)
mRecyclerView.setNestedScrollingEnabled(false);
}
else if(!mRecyclerView.canScrollVertically(-1)) {
mRecyclerView.setNestedScrollingEnabled(false);
}
else if(!mRecyclerView.canScrollVertically(1)) {
mRecyclerView.setNestedScrollingEnabled(true);
}
else {
//idle?
mRecyclerView.setNestedScrollingEnabled(false);
}
이런식으로 해결하였습니다.
.canScrollVertically(1) 는 최하단일때 스크롤에 대한 정의이고
.canScrollVertically(-1) 는 최 상단일때 스크롤에 대한 정의입니다.