안 드 로 이 드 의 Nested Scrolling 메커니즘 을 자세히 설명 합 니 다.
12336 단어 androidnestedscrolling모자이크 슬라이딩
Android 는 슈퍼 port.v4 패키지 에서 두 가지 신기 한 종 류 를 제공 합 니 다.
이러한 효 과 는 Nested Scrolling 체 제 를 사용 하여 완성 하기에 매우 적합 하 다.또한 Coordinator Layout 뒤에 도 사실은 이 체 제 를 이용 하고 있다.그래서 나 는 네가 이 체 제 를 무엇 에 사용 할 수 있 는 지 이미 알 고 있다 고 믿는다.
하지만,나 는 네가 또 문제 가 있다 고 믿는다.
위의 그림 에 따 르 면:
만약 에 우리 가 전통 적 인 사건 에 따라 나 누 어 이해한다 면 먼저 우리 가 미 끄 러 진 것 은 아래 의 내용 구역 이 고 이동 은 외부의 View Group 이 이동 하고 있 기 때문에 전통 적 인 방식 으로 외부의 Parent 가 내부 의 Child 사건 을 차단 한 것 이 틀림없다.그러나 상기 효과 도 는 Parent 가 어느 정도 미 끄 러 졌 을 때 Child 가 다시 미 끄 러 지기 시 작 했 고 중간 전체 과정 이 중단 되 지 않 았 다.정상 적 인 사건 배포(수 동 으로 배포 사건 을 호출 하지 않 고 수 동 으로 사건 을 보 내지 않 음)측면 에서 하 는 것 은 불가능 하 다.왜냐하면 Parent 가 차단 한 후에 사건 을 Child 에 게 맡 길 수 없 기 때문이다.사건 을 배포 하 는 것 은 차단 에 있어 한 번 의 매매 에 해당 하기 때문에 차단 하면 현재 제스처 의 다음 사건 은 모두 Parent(차단 자)에 게 맡 길 것 이다.
그러나 Nested Scrolling 메커니즘 은 이 일 을 처리 하기 가 매우 쉽 기 때문에 이 메커니즘 에 대해 깊이 있 게 학습 하면 우리 가 플러그 인 슬라이딩 을 작성 할 때 특수 한 효과 에 도움 이 된다.둘 째 는 제 가 Coordinator Layout 를 분석 하기 위 한 쿠션 입 니 다.
ps:구체 적 으로 어떤 v4 버 전에 추 가 된 것 인지 깊이 연구 하지 않 겠 습 니 다.만약 에 v4 에 상기 두 가지 종류 가 없다 면 v4 버 전 을 업그레이드 하 십시오.Nested Scrolling 메커니즘 이라는 단 어 는 개인 적 인 호칭 으로 공식 적 으로 이렇게 부 르 는 지 잘 모 르 겠 으 니 깊이 연구 하지 마 세 요.
2.기대 효과
물론 이 두 가 지 를 설명 하려 면 반드시 사례 의 뒷받침 이 있어 야 한다.그렇지 않 으 면 너무 공허 하 다.다행히 저 에 게 아주 좋 은 사례 가 있 습 니 다.
아주 오래 전에 나 는 이런 글 을 쓴 적 이 있다.
Android 는 사용자 정의 컨트롤 을 통 해 360 소프트웨어 상세 페이지 효 과 를 실현 합 니 다.
완전히 전통 적 인 방식 으로 작 성 된 것 이 고 연속 적 으로 미 끄 러 지기 위해 매우 특수 한 처 리 를 했 습 니 다.예 를 들 어 DOWN 이벤트 류 를 수 동 으로 나 누 어 주 는 것 입 니 다.관심 이 있 으 면 읽 어 보 세 요.
효과 도 는 다음 과 같 습 니 다:
오늘 우 리 는 이 효 과 를 이용 하여 Nested Srill 체제 의 사례 로 서 마지막 으로 우 리 는 소스 코드 를 간단하게 분석 할 것 입 니 다.사실은 소스 코드 는 비교적 간단 합 니 다~
ps:Coordinator Layout 는 이 효 과 를 편리 하 게 실현 할 수 있 고 후속 적 인 글 도 Coordinator Layout 에 대해 분석 할 것 입 니 다.
실현
상기 효과 도 는 3 부분 으로 나 뉜 다.상단 레이아웃;가운데 ViewPager 표시 기;그리고 밑 에 있 는 RecyclerView;
RecyclerView 는 사실 Nested Srilling Child 의 실현 류 이기 때문에 본 사례 의 주요 역할 은 Nested Scrolling Parent 를 실현 하 는 것 이다.
(1)레이아웃 파일
먼저 레이아웃 파일 을 미리 봅 니 다.머 릿 속 에 대체적인 레이아웃 이 있 습 니 다.
<com.zhy.view.StickyNavLayout xmlns:tools="http://schemas.android.com/tools"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<RelativeLayout
android:id="@id/id_stickynavlayout_topview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#4400ff00" >
<TextView
android:layout_width="match_parent"
android:layout_height="256dp"
android:gravity="center"
android:text=" "
android:textSize="30sp"
android:textStyle="bold" />
</RelativeLayout>
<com.zhy.view.SimpleViewPagerIndicator
android:id="@id/id_stickynavlayout_indicator"
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="#ffffffff" >
</com.zhy.view.SimpleViewPagerIndicator>
<android.support.v4.view.ViewPager
android:id="@id/id_stickynavlayout_viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
</android.support.v4.view.ViewPager>
</com.zhy.view.StickyNavLayout>
Sticky NavLayout 는 LinearLayout 에서 직접 계승 하고 orientation='vertical'을 설정 하기 때문에 직관 적 인 것 은 컨트롤 이 순서대로 세로 로 배열 되 고 측정 에 대해 특별한 처 리 를 해 야 한다.본 고의 중점 이 아니 기 때문에 소스 코드 나 위 에서 언급 한 글 을 스스로 볼 수 있다.(2)NestedScrollingParent 실현
Nested Scrolling Parent 는 하나의 인터페이스 로 다음 과 같은 방법 이 필요 합 니 다.
public boolean onStartNestedScroll(View child, View target, int nestedScrollAxes);
public void onNestedScrollAccepted(View child, View target, int nestedScrollAxes);
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();
구체 적 인 실현 을 쓰기 전에 먼저 필요 한 상술 한 방법 에 대해 간단 한 소 개 를 한다.여기 서 내부 뷰 는 반드시 직접 서브 뷰 가 아니 라 내부 뷰 만 있 으 면 된다 는 뜻 이다.
다음은 우리 의 구체 적 인 실현 을 살 펴 보 자.
public class StickyNavLayout extends LinearLayout implements NestedScrollingParent
{
@Override
public boolean onStartNestedScroll(View child, View target, int nestedScrollAxes)
{
return (nestedScrollAxes & ViewCompat.SCROLL_AXIS_VERTICAL) != 0;
}
@Override
public void onNestedPreScroll(View target, int dx, int dy, int[] consumed)
{
boolean hiddenTop = dy > 0 && getScrollY() < mTopViewHeight;
boolean showTop = dy < 0 && getScrollY() > 0 && !ViewCompat.canScrollVertically(target, -1);
if (hiddenTop || showTop)
{
scrollBy(0, dy);
consumed[1] = dy;
}
}
@Override
public boolean onNestedPreFling(View target, float velocityX, float velocityY)
{
if (getScrollY() >= mTopViewHeight) return false;
fling((int) velocityY);
return true;
}
}
fling 방법 에 대해 우 리 는 OverScroll 의 fling 방법 을 이용 하여 경계 검 측 에 대해 scrollTo 방법 을 다시 썼 습 니 다.
public void fling(int velocityY)
{
mScroller.fling(0, getScrollY(), 0, velocityY, 0, 0, 0, mTopViewHeight);
invalidate();
}
@Override
public void scrollTo(int x, int y)
{
if (y < 0)
{
y = 0;
}
if (y > mTopViewHeight)
{
y = mTopViewHeight;
}
if (y != getScrollY())
{
super.scrollTo(x, y);
}
}
상세 한 설명 은 위 에서 언급 한 문장 을 볼 수 있 는데,여 기 는 중복 되 지 않 는 다.여기까지 입 니 다.Nested Scrolling 메커니즘 을 볼 수 있 습 니 다.아주 간단 합 니 다.
바로 Nested Scrolling Parent 내부 의 View 입 니 다.미 끄 러 질 때 먼저 dx,dy 를 Nested Scrolling Parent 에 전달 합 니 다.Nested Scrolling Parent 는 이 를 소모 할 지 여 부 를 결정 할 수 있 습 니 다.보통 수요 에 따라 소모 부분 이나 전 부 를 소모 할 수 있 습 니 다.(그러나 여 기 는 실제 적 인 제약 이 없 기 때문에 얼마 가 소모 되 는 지 마음대로 쓸 수 있 고 내부 View 에 어느 정도 영향 을 줄 수 있 습 니 다).
백화 와 원래 의 사건 분배 기 제작 을 비교 해 보면 이렇다(정상 적 인 절차 에 대한 다음 제스처).
원리
원 리 는 내부 View 가 언제 Nested Scrolling Parent 로 되 돌아 가 는 지 보 는 것 입 니 다.내부 View 의 onTouch Event 로 직접 위 치 를 정 하 는 것 입 니 다.
@Override
public boolean onTouchEvent(MotionEvent e) {
switch (action) {
case MotionEvent.ACTION_DOWN: {
int nestedScrollAxis = ViewCompat.SCROLL_AXIS_NONE;
if (canScrollHorizontally) {
nestedScrollAxis |= ViewCompat.SCROLL_AXIS_HORIZONTAL;
}
if (canScrollVertically) {
nestedScrollAxis |= ViewCompat.SCROLL_AXIS_VERTICAL;
}
startNestedScroll(nestedScrollAxis);
} break;
case MotionEvent.ACTION_MOVE: {
if (dispatchNestedPreScroll(dx, dy, mScrollConsumed, mScrollOffset)) {
dx -= mScrollConsumed[0];
dy -= mScrollConsumed[1];
vtev.offsetLocation(mScrollOffset[0], mScrollOffset[1]);
}
} break;
case MotionEvent.ACTION_UP: {
fling((int) xvel, (int) yvel);
resetTouch();
} break;
case MotionEvent.ACTION_CANCEL: {
cancelTouch();
} break;
}
return true;
}
볼 수 있 습 니 다:ACTION_DOWN 에서 startNested Scroll 을 호출 했 습 니 다.ACTION_MOVE 에서 dispatchNested PreScroll 을 호출 했 습 니 다.ACTION_UP 는 resetTouch 를 호출 하기 위해 fling 을 촉발 할 수 있 습 니 다.
startNested 스크롤 내부 실제:
#NestedScrollingChildHelper
public boolean startNestedScroll(int axes) {
if (hasNestedScrollingParent()) {
// Already in progress
return true;
}
if (isNestedScrollingEnabled()) {
ViewParent p = mView.getParent();
View child = mView;
while (p != null) {
if (ViewParentCompat.onStartNestedScroll(p, child, mView, axes)) {
mNestedScrollingParent = p;
ViewParentCompat.onNestedScrollAccepted(p, child, mView, axes);
return true;
}
if (p instanceof View) {
child = (View) p;
}
p = p.getParent();
}
}
return false;
}
Nested Scrolling Parent 를 찾 아 onStart Nested Scroll 과 onNested Scroll Accepted 를 되 돌려 줍 니 다.dispatchNested PreScroll 에 서 는 onNested PreScroll 방법 을 되 돌려 주 고 내부 scrollByInternal 에 서 는 onNested Scroll 방법 을 되 돌려 줍 니 다.
fling 에 서 는 onNested PreFling 과 onNested Fling 방법 을 되 돌려 줍 니 다.
resetTouch 에 서 는 onStopNested Scroll 을 되 돌려 줍 니 다.
코드 는 사실 붙 일 것 이 별로 없습니다.여러분 이 직접 onTouchEvent 를 찾 으 면 한눈 에 볼 수 있 습 니 다.호출 방법 명 은 모두 dispatchNestedXXX 방법 이 고 실제 내 부 는 Nested Scrolling ChildHelper 를 통 해 이 루어 집 니 다.
따라서 Nested Scrolling Parent 와 합작 하 는 내부 View 를 실현 하려 면 Nested Scrolling Child 를 실현 한 다음 에 내부 에서 Nested Scrolling Child Helper 라 는 보조 류 를 빌려 핵심 적 인 방법 을 모두 봉 인 했 습 니 다.적당 한 실제 적 으로 매개 변수 호출 방법 을 전달 하면 됩 니 다.
ok,이런 메커니즘 은 반드시 시험 해 봐 야 한다.많은 미끄럼 과 관련 된 효과 가 이 를 통 해 실 현 될 수 있다.
원본 주소:
github 주소:https://github.com/hongyangAndroid/Android-StickyNavLayout
로 컬 다운로드:http://xiazai.jb51.net/201705/yuanma/Android-StickyNavLayout(jb51.net).rar
총결산
이상 은 이 글 의 전체 내용 입 니 다.본 논문 의 내용 이 여러분 의 학습 이나 업무 에 어느 정도 도움 이 되 기 를 바 랍 니 다.궁금 한 점 이 있 으 시 면 댓 글 을 남 겨 주 셔 서 저희 에 대한 지지 에 감 사 드 립 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Kotlin의 기초 - 2부지난 글에서는 Kotlin이 무엇인지, Kotlin의 특징, Kotlin에서 변수 및 데이터 유형을 선언하는 방법과 같은 Kotlin의 기본 개념에 대해 배웠습니다. 유형 변환은 데이터 변수의 한 유형을 다른 데이터...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.