내부 CoordinatorLayout과 함께 BottomSheetBehavior 사용
코디네이터의 자식이 하단 시트 (화면 하단에서 드래그 할 수있는 뷰) 역할을 할 수 있는 디자인 지원 라이브러리가 v. 23.2
도입되었습니다 BottomSheetBehavior
.
내가하고 싶은 것은 하단 시트 뷰로 다음 뷰 (일반 코디네이터 + 축소 항목)를 갖는 것입니다.
<CoordinatorLayout
app:layout_behavior=“@string/bottom_sheet_behavior”>
<AppBarLayout>
<CollapsingToolbarLayout>
<ImageView />
</CollapsingToolbarLayout>
</AppBarLayout>
<NestedScrollView>
<LinearLayout>
< Content ... />
</LinearLayout>
</NestedScrollView>
</CoordinatorLayout>
안타깝게도 하단 시트보기는 중첩 스크롤을 구현해야합니다. 그렇지 않으면 스크롤 이벤트를받지 못합니다. 기본 활동으로 시도한 다음이보기를 하단 시트로로드하면 스크롤 이벤트가 종이의 "시트"에서만 작동하며 계속 읽는 경우 알 수 있듯이 이상한 동작이 있음을 알 수 있습니다.
나는 이것이 서브 클래 싱 CoordinatorLayout
또는 서브 클래 싱에 의해 더 잘 처리 될 수 있다고 확신한다 BottomSheetBehavior
. 힌트가 있습니까?
몇 가지 생각
requestDisallowInterceptTouchEvent()
일부 조건에서 부모의 이벤트를 훔치기 위해 사용되어야합니다.- 시
AppBarLayout
오프셋> 0 AppBarLayout
오프셋이 == 0 일 때, 우리는 위로 스크롤하고 있습니다 (잠시 동안 생각해 보면 알 수 있습니다)
- 시
첫 번째 조건
OnOffsetChanged
은를 내부 앱 바에 설정하여 얻을 수 있습니다 .두 번째는 몇 가지 이벤트 처리가 필요합니다. 예를 들면 다음과 같습니다.
switch (MotionEventCompat.getActionMasked(event)) { case MotionEvent.ACTION_DOWN: startY = event.getY(); lastY = startY; userIsScrollingUp = false; break; case MotionEvent.ACTION_CANCEL: case MotionEvent.ACTION_UP: userIsScrollingUp = false; break; case MotionEvent.ACTION_MOVE: lastY = event.getY(); float yDeltaTotal = startY - lastY; if (yDeltaTotal > touchSlop) { // Moving the finger up. userIsScrollingUp = true; } break; }
이슈
말할 필요도없이 지금은이 일을 할 수 없습니다. 조건이 충족되면 이벤트를 잡을 수없고 다른 경우에는 잡을 수 없습니다. 아래 이미지에서 표준 CoordinatorLayout에서 어떤 일이 발생하는지 확인할 수 있습니다.
앱바에서 아래로 스크롤하면 시트가 닫히지 만 중첩 된 콘텐츠에서 아래로 스크롤하면 닫힙니다. 중첩 된 스크롤 이벤트가 Coordinator 동작으로 전파되지 않는 것 같습니다.
내부 앱 바에도 문제가 있습니다. 중첩 된 스크롤 콘텐츠가 축소 될 때 앱 바를 따르지 않습니다.
이러한 문제를 보여주는 github에 샘플 프로젝트를 설정했습니다 .
명확하게 말하면 원하는 동작은 다음과 같습니다.
시트 내 앱바 / 스크롤보기의 올바른 동작;
시트가 확장되면 아래로 스크롤하면 축소 될 수 있지만 내부 앱 바도 완전히 확장 된 경우에만 가능합니다 . 지금은 앱바 상태와 상관없이 앱 바를 드래그하는 경우에만 축소됩니다.
시트가 축소되면 스크롤 업 제스처로 확장됩니다 (내부 앱 바에는 영향을주지 않음).
연락처 앱의 예 (아마도 BottomSheetBehavior를 사용하지 않지만 이것이 내가 원하는 것입니다) :
마침내 구현을 릴리스했습니다. Github에서 또는 jcenter에서 직접 찾으십시오 .
compile 'com.otaliastudios:bottomsheetcoordinatorlayout:1.0.0’
해야 할 일은 BottomSheetCoordinatorLayout
하단 시트의 루트 뷰로 사용하는 것입니다 . 자동으로 작동하는 동작을 부풀 리므로 걱정하지 마십시오.
나는 이것을 오랫동안 사용해 왔으며 스크롤 문제가 없어야하며 ABL에서 드래그를 지원합니다.
방금 위의 질문을 한 방식을 따랐고 더 많은 설명이 필요한 솔루션을 찾았습니다. 샘플 코드를 따르고 xml에 추가 부분을 통합하여 BottomSheeet 동작처럼 동작하도록 만드십시오.
<CoordinatorLayout>
<AppBarLayout>
<Toolbar
app:layout_collapseMode="pin">
</Toolbar>
</AppBarLayout>
<NestedScrollView
app:layout_behavior=“@string/bottom_sheet_behavior” >
<include layout="@layout/items" />
</NestedScrollView>
<!-- Bottom Sheet -->
<BottomSheetCoordinatorLayout>
<AppBarLayout
<CollapsingToolbarLayout">
<ImageView />
<Toolbar />
</CollapsingToolbarLayout>
</AppBarLayout>
<NestedScrollView">
<include layout="@layout/items" />
</NestedScrollView>
</BottomSheetCoordinatorLayout>
</CoordinatorLayout>
참고 : 나를 위해 일한 솔루션은 이미 귀하의 질문의 마지막 댓글에서 설명했습니다.
더 나은 explantion : https://github.com/laenger/BottomSheetCoordinatorLayout
첫 번째 자녀가 있으면 nestedscroll
다른 문제가 발생합니다. 이 솔루션은 내 문제가 해결되었습니다.
<CoordinatorLayout
app:layout_behavior=“@string/bottom_sheet_behavior”>
<AppBarLayout>
<CollapsingToolbarLayout>
<ImageView />
</CollapsingToolbarLayout>
</AppBarLayout>
</LinearLayout>
<NestedScrollView>
<LinearLayout>
< Content ... />
</LinearLayout>
</NestedScrollView>
</LinearLayout>
</CoordinatorLayout>
NestedScrollView
와 함께 사용하지 마십시오 LinearLayout
. 내 앱에서도 문제가 발생했습니다. LinearLayout
대신 사용 하십시오.
다음을 시도하십시오.
<CoordinatorLayout
app:layout_behavior=“@string/bottom_sheet_behavior”>
<AppBarLayout>
<CollapsingToolbarLayout>
<ImageView />
</CollapsingToolbarLayout>
</AppBarLayout>
<LinearLayout>
<!--don't forget to addd this line-->
app:layout_behavior="@string/appbar_scrolling_view_behavior">
< Content ... />
</LinearLayout>
나는이 문제와 관련하여 laenger의 초기 github 테스트 프로젝트를 따랐으며, 내 앱에서도이 동작이 필요했기 때문에 그의 문제에 대한 해결책을 공유하게되어 기쁩니다.
이것은 그의 문제에 대한 해결책입니다. ❌ 툴바가 때때로 너무 일찍 축소됩니다.
이를 방지하려면 사용자 정의를 만들어야합니다 . 스크롤 동작을 가져 AppBarLayout.Behavior
오는 동안 드래그하는 동안 위로 스크롤 할 때이기 때문입니다 AppBarLayout.behavior
. STATE_DRAGGING인지 감지하고 툴바를 너무 일찍 숨기거나 접는 것을 피하기 위해 돌아와야합니다.
public class CustomAppBarLayoutBehavior extends AppBarLayout.Behavior {
private CoordinatorLayoutBottomSheetBehavior behavior;
public CustomAppBarLayoutBehavior() {
}
public CustomAppBarLayoutBehavior(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public boolean onStartNestedScroll(CoordinatorLayout parent, AppBarLayout child, View directTargetChild, View target, int nestedScrollAxes) {
behavior = CoordinatorLayoutBottomSheetBehavior.from(parent);
return super.onStartNestedScroll(parent, child, directTargetChild, target, nestedScrollAxes);
}
@Override
public void onNestedPreScroll(CoordinatorLayout coordinatorLayout, AppBarLayout child, View target, int dx, int dy, int[] consumed) {
if(behavior.getState() == CoordinatorLayoutBottomSheetBehavior.STATE_DRAGGING){
return;
}else {
super.onNestedPreScroll(coordinatorLayout, child, target, dx, dy, consumed);
}
}
@Override
public void setDragCallback(@Nullable DragCallback callback) {
super.setDragCallback(callback);
}
}
다른 문제를 해결하는 방법에 대한 좋은 시작이 될 수 있습니다.
❌ 툴바는 드래그로 축소 할 수 없습니다.
❌ 메인 코디네이터 레이아웃이 스크롤을 사용합니다.
나는 실제로 좋은 UI / 애니메이션 사람은 아니지만, 열심히 노력하면 때때로 코드를 이해하고 구현할 올바른 콜백 / 오버라이드 함수를 찾는 데 도움이됩니다.
이것을 appbarlayout에 대한 동작으로 설정하십시오.
<android.support.design.widget.AppBarLayout
android:id="@+id/bottom_sheet_appbar"
style="@style/BottomSheetAppBarStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_behavior="your.package.CustomAppBarLayoutBehavior">
앱바 레이아웃의 전체 화면 레이아웃은 다음과 같습니다.
<android.support.design.widget.AppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="@dimen/detail_backdrop_height"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
android:fitsSystemWindows="true">
<android.support.design.widget.CollapsingToolbarLayout
android:id="@+id/collapsing_toolbar"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_scrollFlags="scroll|exitUntilCollapsed"
android:fitsSystemWindows="true"
app:contentScrim="?attr/colorPrimary"
app:expandedTitleMarginStart="48dp"
app:expandedTitleMarginEnd="64dp">
<ImageView
android:id="@+id/backdrop"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
android:fitsSystemWindows="true"
app:layout_collapseMode="parallax" />
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
app:layout_collapseMode="pin" />
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingTop="24dp">
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="@dimen/card_margin">
<LinearLayout
style="@style/Widget.CardContent"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Info"
android:textAppearance="@style/TextAppearance.AppCompat.Title" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/cheese_ipsum" />
</LinearLayout>
</android.support.v7.widget.CardView>
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/card_margin"
android:layout_marginLeft="@dimen/card_margin"
android:layout_marginRight="@dimen/card_margin">
<LinearLayout
style="@style/Widget.CardContent"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Friends"
android:textAppearance="@style/TextAppearance.AppCompat.Title" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/cheese_ipsum" />
</LinearLayout>
</android.support.v7.widget.CardView>
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/card_margin"
android:layout_marginLeft="@dimen/card_margin"
android:layout_marginRight="@dimen/card_margin">
<LinearLayout
style="@style/Widget.CardContent"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Related"
android:textAppearance="@style/TextAppearance.AppCompat.Title" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/cheese_ipsum" />
</LinearLayout>
</android.support.v7.widget.CardView>
</LinearLayout>
</android.support.v4.widget.NestedScrollView>
<android.support.design.widget.FloatingActionButton
android:layout_height="wrap_content"
android:layout_width="wrap_content"
app:layout_anchor="@id/appbar"
app:layout_anchorGravity="bottom|right|end"
android:src="@drawable/ic_discuss"
android:layout_margin="@dimen/fab_margin"
android:clickable="true"/>
그런 다음 클래스에서 AppBarLayout.OnOffsetChangedListener를 구현하고 화면의 오프셋을 설정해야합니다.
'programing' 카테고리의 다른 글
브라우저에서 Colorbox의 일관성 (0) | 2021.01.16 |
---|---|
장면 전환 애니메이션의 JNI 오류-레이어가 최대 값을 초과합니다. (0) | 2021.01.16 |
Abysmal OpenCL ImageSampling 성능 대 OpenGL TextureSampling (0) | 2021.01.16 |
백만 개가 넘는 테스트 케이스가있는 테스트 스위트 실행 (0) | 2021.01.16 |
ADT 23으로 업데이트 한 후 annotations.jar을 찾지 못함 (0) | 2021.01.15 |