Với thư viện hỗ trợ-v4 22.1.0 android hỗ trợ cuộn lồng nhau (pre android 5.0). Thật không may, tính năng này không thực sự được ghi lại. Có hai giao diện (NestedScrollingParent
và NestedScrollingChild
) cũng như hai lớp đại biểu trợ giúp (NestedScrollingChildHelper
và NestedScrollingParentHelper
).Cách triển khai NestedScrolling trên Android?
Có ai đã làm việc với NestedScrolling trên Android không?
Tôi đã cố gắng thiết lập một ví dụ nhỏ, nơi tôi sử dụng NestedScrollView thực hiện cả hai NestedScrollingParent
và NestedScrollingChild
.
bố trí của tôi trông như thế này:
<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>
Tôi muốn hiển thị một header view
và một NestedScrollView
(id = con) trong một NestedScrollView
(id = mẹ).
Ý tưởng là, để điều chỉnh chiều cao của xem di chuyển con trong thời gian chạy bằng cách sử dụng một 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;
}
});
}
}
Vì vậy, quan điểm tiêu đề sẽ được cuộn đi một phần, 40 pixel sẽ vẫn nhìn thấy kể từ khi tôi đặt chiều cao của chế độ xem cuộn con lồng nhau đến parentScroll.getHeight() - 40
. Được rồi, đặt chiều cao lúc chạy và cuộn chế độ xem cuộn chính sẽ hoạt động như mong đợi (tiêu đề cuộn ra, 40 pixel vẫn hiển thị và sau đó cuộn con sẽ lấp đầy phần còn lại của màn hình bên dưới tiêu đề). Tôi mong rằng "NestedScrolling" có nghĩa là tôi có thể tạo một cử chỉ di chuyển ở bất cứ nơi nào trên màn hình (sự kiện chạm được bắt bởi chế độ xem cuộn phụ huynh) và nếu chế độ xem cuộn chính đã đến cuối màn hình cuộn con lồng nhau bắt đầu cuộn . Tuy nhiên, có vẻ như không phải là trường hợp (không cho cử chỉ di chuyển đơn giản hay cử chỉ trượt).
Sự kiện liên lạc luôn được xử lý bởi cuộn con lồng nhau nếu sự kiện chạm bắt đầu trong ranh giới của nó, nếu không, bằng cách cuộn theo chế độ xem chính.
Đó có phải là hành vi mong đợi của "cuộn lồng nhau" hay không có tùy chọn để thay đổi hành vi đó?
Tôi cũng đã cố gắng thay thế chế độ xem cuộn con lồng nhau bằng NestedRecyclerView
. Tôi subclassed RecyclerView
và thực hiện NestedScrollingChild
nơi tôi giao toàn bộ phương pháp để 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);
}
}
nhưng NestedRecyclerView
không di chuyển chút nào. Tất cả các sự kiện cảm ứng đều bị bắt bởi chế độ xem cuộn của bố mẹ.
Tôi phải đối mặt với cùng một vấn đề và nghĩ rằng tiện ích con này sẽ được cải thiện để cho phép phụ huynh gửi di chuyển không mong muốn đến con của nó. –
Tôi nghĩ việc tạo ra chế độ xem tái chế là một lồng nhauScrollingChild không phải là dễ dàng, vì nó sử dụng LayoutManager để cuộn và định vị mục của nó. Do đó, chỉ thực hiện NestedScrollingChild với NestedScrollingChildHelper sẽ không hoạt động vì những hàm này không được gọi trong khi cuộn. –
Tôi không chắc chắn. Tôi đoán rằng NestedScrollingParent/NestedScrollingChild được sử dụng để chuyển tiếp sự kiện cảm ứng. Tôi hy vọng rằng 'NestedScrollingChild' nội bộ làm điều đó, tôi không thể thấy bất kỳ lý do tại sao nó sẽ làm việc cho' ScrollView' nhưng không cho 'RecyclerView' ...' LayoutManager' không phải là một vấn đề ... – sockeqwe