Android에서 NestedScrolling을 구현하는 방법은 무엇입니까?
support-v4 라이브러리 22.1.0을 사용하면 Android는 중첩 스크롤 (Android 5.0 이전)을 지원합니다. 불행히도이 기능은 문서화되어 있지 않습니다. 두 개의 인터페이스 ( NestedScrollingParent
및 NestedScrollingChild
)와 두 개의 개의 도우미 대리자 클래스 ( NestedScrollingChildHelper
및 NestedScrollingParentHelper
)가 있습니다.
Android에서 NestedScrolling으로 작업 한 사람이 있습니까?
나는 설치에 내가 사용하는 약간의 예를 시도 NestedScrollView 구현 모두 NestedScrollingParent
와 NestedScrollingChild
.
내 레이아웃은 다음과 달라집니다.
<android.support.v4.widget.NestedScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/parent"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<View
android:id="@+id/header"
android:layout_width="match_parent" android:layout_height="100dp"
android:background="#AF1233"/>
<android.support.v4.widget.NestedScrollView
android:id="@+id/child"
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#12AF33"
android:text="@string/long_text"/>
</FrameLayout>
</android.support.v4.widget.NestedScrollView>
</LinearLayout>
</android.support.v4.widget.NestedScrollView>
(id = parent)에 a header view
와 다른 NestedScrollView
(id = child) 을 표시하고 싶습니다 NestedScrollView
.
아이디어는 다음을 사용하여 구동에 마이너 스크롤 뷰의 높이를 조정하는 것입니다 OnPredrawListener
.
public class MainActivity extends Activity {
@Override protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final NestedScrollView parentScroll = (NestedScrollView) findViewById(R.id.parent);
final NestedScrollView nestedScroll = (NestedScrollView) findViewById(R.id.child);
parentScroll.setNestedScrollingEnabled(false);
final View header = findViewById(R.id.header);
parentScroll.getViewTreeObserver()
.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
@Override public boolean onPreDraw() {
if (parentScroll.getHeight() > 0) {
parentScroll.getViewTreeObserver().removeOnPreDrawListener(this);
nestedScroll.getLayoutParams().height = parentScroll.getHeight() - 40;
nestedScroll.setLayoutParams(nestedScroll.getLayoutParams());
nestedScroll.invalidate();
return false;
}
return true;
}
});
}
}
따라서 뷰 헤더는 부분적으로 스크롤되고 중첩 된 스크롤 스크롤 뷰의 높이를 설정하기 때문에 40 픽셀이 계속 표시 parentScroll.getHeight() - 40
됩니다. 좋습니다. 작동에 높이를 설정하고 상위 스크롤 뷰를 스크롤하면 예상대로 작동합니다 (헤더가 스크롤되고 40 픽셀이 계속 표시되고 하위 스크롤 뷰가 헤더 아래 화면의 나머지 부분을 채).
"NestedScrolling"은 화면의 아무 곳에서나 스크롤 제스처를 만들 수 있습니다. (부모 스크롤보기에서 잡은 터치 이벤트) 스크롤보기가 도달하면 거기에있는 스크롤보기가 스크롤을 시작한다는 것을 의미합니다. 그것은 사실이 아닌 것입니다 (간단한 스크롤 제스처 나 플링 제스처도 마찬가지입니다).
터치 이벤트가 경계에서 시작되면 터치 이벤트는 항상 중첩 된 스크롤 뷰에 의해 처리되고, 스크롤 뷰에 의해 처리되고 있습니다.
"중첩 스크롤"의 예상되는 동작입니까, 아니면 해당 동작을 의미 수있는 옵션이 있습니까?
또한 중첩 된 스크롤 스크롤 뷰를 NestedRecyclerView
. 나는 모든 메소드를 위임 RecyclerView
하는 NestedScrollingChild
곳에서 하위 클래스를 만들고 구현 했습니다 NestedScrollingChildHelper
.
public class NestedRecyclerView extends RecyclerView implements NestedScrollingChild {
private final NestedScrollingChildHelper scrollingChildHelper =
new NestedScrollingChildHelper(this);
public void setNestedScrollingEnabled(boolean enabled) {
scrollingChildHelper.setNestedScrollingEnabled(enabled);
}
public boolean isNestedScrollingEnabled() {
return scrollingChildHelper.isNestedScrollingEnabled();
}
public boolean startNestedScroll(int axes) {
return scrollingChildHelper.startNestedScroll(axes);
}
public void stopNestedScroll() {
scrollingChildHelper.stopNestedScroll();
}
public boolean hasNestedScrollingParent() {
return scrollingChildHelper.hasNestedScrollingParent();
}
public boolean dispatchNestedScroll(int dxConsumed, int dyConsumed, int dxUnconsumed,
int dyUnconsumed, int[] offsetInWindow) {
return scrollingChildHelper.dispatchNestedScroll(dxConsumed, dyConsumed, dxUnconsumed,
dyUnconsumed, offsetInWindow);
}
public boolean dispatchNestedPreScroll(int dx, int dy, int[] consumed, int[] offsetInWindow) {
return scrollingChildHelper.dispatchNestedPreScroll(dx, dy, consumed, offsetInWindow);
}
public boolean dispatchNestedFling(float velocityX, float velocityY, boolean consumed) {
return scrollingChildHelper.dispatchNestedFling(velocityX, velocityY, consumed);
}
public boolean dispatchNestedPreFling(float velocityX, float velocityY) {
return scrollingChildHelper.dispatchNestedPreFling(velocityX, velocityY);
}
}
그러나 NestedRecyclerView
전혀 전혀 스크롤되지 않았습니다. 모든 터치 이벤트는 상위 스크롤보기에서 이루어집니다.
NestedScrollView에서 무슨 일이 일어나는지 알아 내려고 안드로이드 코드를 보는 데 상당한 시간을 보였습니다. 다음이 작동합니다.
public abstract class ParentOfNestedScrollView extends NestedScrollView{
public ParentOfNestedScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
}
/*
Have this return the range you want to scroll to until the
footer starts scrolling I have it as headerCard.getHeight()
on most implementations
*/
protected abstract int getScrollRange();
/*
This has the parent do all the scrolling that happens until
you are ready for the child to scroll.
*/
@Override
public void onNestedPreScroll(View target, int dx, int dy, int[] consumed){
if (dy > 0 && getScrollY() < getScrollRange()) {
int oldScrollY = getScrollY();
scrollBy(0, dy);
consumed[1] = getScrollY() - oldScrollY;
}
}
/*
Sometimes the parent scroll intercepts the event when you don't
want it to. This prevents this from ever happening.
*/
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
return false;
}
}
내 코드 중 일부는이 질문 에서 빌려온 것 입니다. 여기에서 필요에 따라이 클래스를 확장합니다. 내 xml에는 자식이 NestedScrollView 자식으로 있고 부모는 이것으로 있습니다. 이것은 내가 원하는 것만 큼 잘 처리하지 못합니다. 그것은 진행중인 작업입니다.
참조 URL : https://stackoverflow.com/questions/29885067/how-to-implement-nestedscrolling-on-android
'ProgramingTip' 카테고리의 다른 글
연결 실패 [ilink32 오류] 치명적 : 'TYPES.OBJ'파일을 열 수 없습니다. (0) | 2021.01.08 |
---|---|
Windows Phone 8의 UDP 멀티 캐스트 그룹 (0) | 2021.01.08 |
브라우저에서 애플리케이션을 시작하는 방법은 무엇입니까? (0) | 2021.01.08 |
NSWindowCollectionBehaviorStationary가있는 NSWindow는 대시 보드에 표시됩니다. (0) | 2021.01.08 |
트리보기 위젯이있는 백본 (0) | 2021.01.08 |