私は2つの問題に直面しています:
RecyclerView
は、NestedScrollView
にアタッチされている場合、ビューをリサイクルすることはありません。 ScrollView内の線形レイアウトのように機能します。大量のメモリを使用し、ラグを作成します。リサイクラービュー内にフラグメントを配置できないため、リサイクラービューの上にYouTubeプレーヤーフラグメントを添付しています。私のコードでは、フレームレイアウトがあることがわかります。
私のレイアウトは次のようになります。
_ <Android.support.v4.widget.NestedScrollView xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:app="http://schemas.Android.com/apk/res-auto"
Android:id="@+id/nestedScroll"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:background="#ffffff"
Android:orientation="vertical">
<LinearLayout
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:background="#ffffff"
Android:orientation="vertical">
<LinearLayout
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:orientation="vertical">
<FrameLayout
Android:layout_width="match_parent"
Android:layout_height="240dp"
Android:layout_alignParentTop="true"/>
</LinearLayout>
<Android.support.v7.widget.RecyclerView
Android:id="@+id/recycler_view"
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:layout_below="@+id/youtube_layout"
Android:visibility="visible"/>
</LinearLayout>
</Android.support.v4.widget.NestedScrollView>
_
スクロールリスナーを使用してさらにアイテムをロードしたいので、次のことを試しました。
_@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
Log.i(TAG, "onScrolled: ");
// bail out if scrolling upward or already loading data
if (dy < 0 || dataLoading.isDataLoading()) return;
final int visibleItemCount = recyclerView.getChildCount();
final int totalItemCount = layoutManager.getItemCount();
final int firstVisibleItem = layoutManager.findFirstVisibleItemPosition();
if ((totalItemCount - visibleItemCount) <= (firstVisibleItem )) {
onLoadMore();
}
}
_
しかし、layoutManager.findFirstVisibleItemPosition()==0
なので機能せず、recyclerview.setNestedScrollingEnabled(false)を設定してから_onScrolled never called twice
_以上になります
だから私はこのようにonBindView
で試しました
_ public void onBindViewHolder(RecyclerView.ViewHolder customViewHolder, int i) {
Log.w("d","inside bind view");
if(i>=getItemCount()-1 && !datamanager.isDataLoading()){
datamanager.loadmoreData();
}
_
しかし、recylerviewは、スクロールを開始する前に一度にすべてのビューをバインドするため、この方法も機能しません。
リサイクラービューは、ネストされたスクロールビューにアタッチされている場合、ビューをリサイクルすることはありません。スクロールビュー内の線形レイアウトで設定されたとおりに機能します。巨大なメモリを作成し、画面を遅らせます。
丁度。 RecyclerViewを別のスクロールビュー内に配置することはできません。
ラッピングビューはRecyclerViewの全高を知る必要があり、RecyclerViewはそのアイテムのすべてallを測定してレイアウトすることによってのみ全高を知ることができるため、機能しません。
RecyclerViewを別のスクロールビュー内に配置しないでください。
ヘッダーまたはフッターが必要な場合は、それをRecyclerViewに追加し、RecyclerViewに表示させる必要があります。 ScrollViewを削除し、ヘッダーをRecyclerViewの内部に移動します。
技術的には、RecyclerView内にフラグメントをロードすることも可能ですが、これを正しく機能させるには少し注意が必要です。
プロセスを容易にするライブラリもたくさんあります。私の個人的なお気に入りは Epoxy AirBnb製ですが、 Groupie などもあります。
私はこのような状況に対処しました。 recyclerviewがあります。リサイクラービューにはビューページャーがあります。ビューページャーにはフラグメントがあり、フラグメント内にリサイクラービューがあります。
完全にスクロールするには、タッチをハックする必要があります。
private boolean interceptTouch = true;
private static final int MIN_DISTANCE = 200;
private float downX = 0, downY = 0, moveX = 0, moveY = 0, upX = 0, upY;
public TouchInterceptRecyclerView(Context context) {
super(context);
}
public TouchInterceptRecyclerView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
if (getRvTop() == 0) {
onTouchEvent(ev);
}
return interceptTouch;
}
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
downX = event.getX();
downY = event.getY();
break;
case MotionEvent.ACTION_MOVE:
moveX = event.getX();
moveY = event.getY();
break;
case MotionEvent.ACTION_UP:
upX = event.getX();
upY = event.getY();
break;
}
float deltaX = upX - downX;
if (getViewTop() == 0 && moveY > downY && Math.abs(moveY - downY) > MIN_DISTANCE) { // moving down
interceptTouch = true;
}else if (Math.abs(deltaX) > MIN_DISTANCE) {
if (upX > downX) { // Left to Right swipe action
interceptTouch = false;
}else { // Right to left swipe action
interceptTouch = false;
}
} else { // screen tap
interceptTouch = false;
}
return super.onTouchEvent(event);
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
return super.dispatchTouchEvent(ev);
}
@Override
protected void onScrollChanged(int l, int t, int oldl, int oldt) {
super.onScrollChanged(l, t, oldl, oldt);
}
@Override
public void onScrolled(int dx, int dy) {
if (getViewTop() <= 0) {
interceptTouch = false; // dispatch the touch to child when reached top
} else {
interceptTouch = true; // do not dispatch the touch event
}
super.onScrolled(dx, dy);
}
public int getViewTop() {
int top = 0;
View v = this.getChildAt(1);
if (v == null) {
v = this.getChildAt(0);
}
if (v != null && v instanceof LinearLayout) {
top = v.getTop();
}
return top;
}
public int getRvTop() {
int top = -1;
View v = this.getChildAt(1);
if (v == null) {
v = this.getChildAt(0);
}
if (v != null && v instanceof LinearLayout) {
ViewPager vp = (ViewPager) v.findViewById(R.id.single_tribe_pager);
if (vp != null) {
int currentPos = vp.getCurrentItem();
RecyclerView rv = (RecyclerView) vp.findViewWithTag("recyclerview" + currentPos);
if (rv != null) {
View v1 = rv.getChildAt(0);
if (v1 != null && v1 instanceof CardView) {
top = v1.getTop() - ResourceUtils.getDimensionPixelOffset(R.dimen.padding_20); // deducting 20 as we have give top margin as 20 to the top layout
}
}
}
}
return top;
}