Android 플러그 인 스크롤 Nested Scroll 의 실현 에 대해 알 아 보 세 요.
8103 단어 AndroidNestedScroll모자이크 스크롤
이 동 효 를 보면 모두 가 Coordinator Layout 로 실현 할 수 있다 는 것 을 알 수 있 습 니 다.사실 Coordinator Layout 는 Nested Scroll 체 제 를 바탕 으로 이 루어 진 것 이 고 우 리 는 Nested Scroll 체 제 를 통 해 이 동 효 를 직접 실현 할 수 있 습 니 다.
의 원리
Nested Scroll 은 사실 간단 합 니 다.
일반적인 터치 메시지 의 배 포 는 모두 외 향 적 이 고 외부 View Group 의 dispatch TouchEvent 방법 에서 내부 View 의 dispatch TouchEvent 방법 으로 호출 됩 니 다.
한편,Nested Scroll 은 역방향 체 제 를 제공 하고 내부 view 는 ACTION 을 받 습 니 다.MOVE 에 서 는 스크롤 메 시 지 를 바깥쪽 의 ViewGroup 에 먼저 전달 합 니 다.바깥쪽 의 ViewGroup 이 일부분 의 이동 을 소모 해 야 하 는 지 확인 한 다음 에 안쪽 의 View 가 나머지 이동 을 소모 합 니 다.안쪽 view 는 남 은 스크롤 의 일부분 을 소모 할 수 있 습 니 다.아직 소모 되 지 않 았 다 면 바깥쪽 의 view 는 마지막 남 은 스크롤 을 소모 하 는 것 을 선택 할 수 있 습 니 다.
위의 설명 이 약간 돌아 갈 수 있 으 니 아래 의 그림 을 보면 이 해 를 도 울 수 있다.
구체 적 실현
Nested Scroll 메커니즘 은 네 가지 종류 와 관련된다.
Nested Scrolling Child,Nested Scrolling ChildHelper 와 Nested Scrolling Parent,Nested Scrolling Parent Helper
Nested Scrolling Child 와 Nested Scrolling Parent 는 두 개의 인터페이스 입 니 다.먼저 그들의 성명 을 보 겠 습 니 다.
public interface NestedScrollingChild {
public void setNestedScrollingEnabled(boolean enabled);
public boolean isNestedScrollingEnabled();
public boolean startNestedScroll(int axes);
public void stopNestedScroll();
public boolean hasNestedScrollingParent();
public boolean dispatchNestedScroll(int dxConsumed, int dyConsumed,
int dxUnconsumed, int dyUnconsumed, int[] offsetInWindow);
public boolean dispatchNestedPreScroll(int dx, int dy, int[] consumed, int[] offsetInWindow);
public boolean dispatchNestedFling(float velocityX, float velocityY, boolean consumed);
public boolean dispatchNestedPreFling(float velocityX, float velocityY);
}
public interface NestedScrollingParent {
public boolean onStartNestedScroll(View child, View target, int nestedScrollAxes);
public void onNestedScrollAccepted(View child, View target, int nestedScrollAxes);
public void onStopNestedScroll(View target);
public void onNestedScroll(View target, int dxConsumed, int dyConsumed,
int dxUnconsumed, int dyUnconsumed);
public void onNestedPreScroll(View target, int dx, int dy, int[] consumed);
public boolean onNestedFling(View target, float velocityX, float velocityY, boolean consumed);
public boolean onNestedPreFling(View target, float velocityX, float velocityY);
public int getNestedScrollAxes();
}
여기 서 정말 중요 한 것 은 Nested Scrolling Parent 의 몇 가지 방법 입 니 다.다른 방법 은 Nested Scrolling ChildHelper 나 Nested Scrolling Parent Helper 를 직접 대리 할 수 있 기 때 문 입 니 다.
//NestedScrollingChild
private NestedScrollingChildHelper mHelper = new NestedScrollingChildHelper(this);
public boolean startNestedScroll(int axes) {
return mHelper.startNestedScroll(axes);
}
public boolean dispatchNestedScroll(int dxConsumed, int dyConsumed,
int dxUnconsumed, int dyUnconsumed, int[] offsetInWindow) {
return mHelper.dispatchNestedScroll(dxConsumed, dyConsumed,
dxUnconsumed, dyUnconsumed, offsetInWindow);
}
...
//NestedScrollingParent
private NestedScrollingParentHelper mHelper = new NestedScrollingParentHelper(this);
public void onNestedScrollAccepted(View child, View target, int axes) {
mHelper.onNestedScrollAccepted(child, target, axes);
}
public int getNestedScrollAxes() {
return mHelper.getNestedScrollAxes();
}
...
그러나 sdk 21 이상 버 전 을 사용 하면 Nested Scroll 체 제 는 View 에 직접 통합 되 었 습 니 다.View 의 대응 방법 을 직접 다시 쓰 면 됩 니 다.배치
레이아웃 파일 을 먼저 보 겠 습 니 다.
<me.linjw.nestedscrolldemo.NestedScrollParentView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<FrameLayout
android:id="@+id/header"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:layout_width="match_parent"
android:layout_height="200dp"
android:src="@mipmap/ic_launcher" />
</FrameLayout>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/colorAccent"
android:text="Title"
android:textAlignment="center"
android:textSize="20dp" />
<android.support.v7.widget.RecyclerView
android:id="@+id/list"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</me.linjw.nestedscrolldemo.NestedScrollParentView>
가장 바깥쪽 은 우리 가 사용자 정의 한 Nested Scroll Parent View 입 니 다.사실은 LinearLayout 입 니 다.내부 에 세 개의 키 view 가 세로 로 배열 되 어 있 습 니 다.frameLayout 에 소 포 된 ImageView1 개의 TextViewRecyclerView코드
간편 하 게 보기 위해 서,우 리 는 먼저 sdk 22 버 전 으로 View 방법 을 다시 쓰 는 방식 으로 그것 을 실현 합 니 다.
Nested Scroll ParentView 에서 두 가지 방법 이 비교적 중요 합 니 다.플러그 인 스크롤 은 기본적으로 이 두 가지 방법 으로 이 루어 집 니 다.
@Override
public boolean onStartNestedScroll(View child, View target, int nestedScrollAxes) {
return true;
}
@Override
public void onNestedPreScroll(View target, int dx, int dy, int[] consumed) {
super.onNestedPreScroll(target, dx, dy, consumed);
boolean headerScrollUp = dy > 0 && getScrollY() < mHeaderHeight;
boolean headerScrollDown = dy < 0 && getScrollY() > 0 && !target.canScrollVertically(-1);
if (headerScrollUp || headerScrollDown) {
scrollBy(0, dy);
consumed[1] = dy;
}
}
onStartNested Scroll 이 방법 은 true 로 돌아 가면 내부 에서 들 려 오 는 스크롤 메 시 지 를 받 아들 이 는 것 을 의미 합 니 다.저 희 는 true 로 돌아 가면 됩 니 다.그렇지 않 으 면 뒤의 메 시 지 를 받 아들 일 수 없습니다.onNested PreScroll 이 방법 은 내부 view 의 일부분 스크롤 을 소모 하 는 데 사 용 됩 니 다.소모 되 는 스크롤 을 counsumed 에 저장 하여 consumed 가 알 수 있 도록 해 야 합 니 다.예 를 들 어 우 리 는 상단 의 FrameLayout 가 이동 해 야 할 경우 모든 dy 를 소모 합 니 다.그러면 내부 view(즉 RecyclerView)가 스크롤 되 지 않 습 니 다.
여기 mHeader Height 는 상단 의 FrameLayout 높이 를 저장 합 니 다.
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mHeaderHeight = mHeader.getMeasuredHeight();
}
여기까지 기본적으로 움 직 이 는 효 과 를 실현 하 였 는데,매우 간단 하지 않 습 니까?전체 코드 는 참고 할 수 있 습 니 다https://github.com/bluesky466/NestedScrollDemo/tree/sdk22
이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Bitrise에서 배포 어플리케이션 설정 테스트하기이 글은 Bitrise 광고 달력의 23일째 글입니다. 자체 또는 당사 등에서 Bitrise 구축 서비스를 사용합니다. 그나저나 며칠 전 Bitrise User Group Meetup #3에서 아래 슬라이드를 발표했...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.