RecyclerView
内でNestedScrollView
を使用する方法RecyclerView
の内容はアダプタの設定後に表示されません。
_ update _ /レイアウトコードが更新されました。
<Android.support.v4.widget.NestedScrollView xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:layout_width="match_parent"
Android:layout_height="match_parent">
<LinearLayout
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:orientation="vertical">
<RelativeLayout
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:padding="@dimen/keyline_1">
</RelativeLayout>
<View
Android:id="@+id/separator"
Android:layout_width="match_parent"
Android:layout_height="1dp"
Android:background="#e5e5e5" />
<Android.support.v7.widget.RecyclerView
Android:id="@+id/conversation"
Android:layout_width="match_parent"
Android:layout_height="wrap_content" />
</LinearLayout>
</Android.support.v4.widget.NestedScrollView>
RecyclerViewをに置き換えます。
<Android.support.v7.widget.RecyclerView
Android:id="@+id/conversation"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
Android:layout_width="match_parent"
Android:layout_height="wrap_content" />
ここに、
app:layout_behavior="@string/appbar_scrolling_view_behavior"
残りのものを管理します。
もう1つのこと、あなたのrecyclerViewをNestedScrollViewの中に入れる必要がないこと
UPDATE 1
Android Support Library 23.2.0以降、LayoutManager用にメソッドsetAutoMeasureEnabled(true)
が追加されました。これはRecyclerViewにそのコンテンツをラップさせ、魅力のように機能します。
http://Android-developers.blogspot.ru/2016/02/Android-support-library-232.html
だからちょうどこのようなものを追加します。
LayoutManager layoutManager = new LinearLayoutManager(this);
layoutManager.setAutoMeasureEnabled(true);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setNestedScrollingEnabled(false);
アップデート2
27.1.0からsetAutoMeasureEnabled
は推奨されなくなったので、オーバーライドされたメソッドisAutoMeasureEnabled()
を使ってLayoutManagerのカスタム実装を提供するべきです
しかし、RecyclerViewを何度も使用した後は、折り返しモードで使用しないことを強くお勧めします。これが意図したものではないためです。いくつかのアイテムの種類を含む通常の単一のRecyclerViewを使用して、レイアウト全体をリファクタリングするようにしてください。または、最後の手段として以下に説明するLinearLayoutを使用したアプローチを使用してください。
古い答え(非推奨)
RecyclerView
内でNestedScrollView
を使用できます。まず第一にあなたはあなた自身のカスタムLinearLayoutManager
を実装するべきです、それはあなたのRecyclerView
をその内容を包むようにします。例えば:
public class WrappingLinearLayoutManager extends LinearLayoutManager
{
public WrappingLinearLayoutManager(Context context) {
super(context);
}
private int[] mMeasuredDimension = new int[2];
@Override
public boolean canScrollVertically() {
return false;
}
@Override
public void onMeasure(RecyclerView.Recycler recycler, RecyclerView.State state,
int widthSpec, int heightSpec) {
final int widthMode = View.MeasureSpec.getMode(widthSpec);
final int heightMode = View.MeasureSpec.getMode(heightSpec);
final int widthSize = View.MeasureSpec.getSize(widthSpec);
final int heightSize = View.MeasureSpec.getSize(heightSpec);
int width = 0;
int height = 0;
for (int i = 0; i < getItemCount(); i++) {
if (getOrientation() == HORIZONTAL) {
measureScrapChild(recycler, i,
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
heightSpec,
mMeasuredDimension);
width = width + mMeasuredDimension[0];
if (i == 0) {
height = mMeasuredDimension[1];
}
} else {
measureScrapChild(recycler, i,
widthSpec,
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
mMeasuredDimension);
height = height + mMeasuredDimension[1];
if (i == 0) {
width = mMeasuredDimension[0];
}
}
}
switch (widthMode) {
case View.MeasureSpec.EXACTLY:
width = widthSize;
case View.MeasureSpec.AT_MOST:
case View.MeasureSpec.UNSPECIFIED:
}
switch (heightMode) {
case View.MeasureSpec.EXACTLY:
height = heightSize;
case View.MeasureSpec.AT_MOST:
case View.MeasureSpec.UNSPECIFIED:
}
setMeasuredDimension(width, height);
}
private void measureScrapChild(RecyclerView.Recycler recycler, int position, int widthSpec,
int heightSpec, int[] measuredDimension) {
View view = recycler.getViewForPosition(position);
if (view.getVisibility() == View.GONE) {
measuredDimension[0] = 0;
measuredDimension[1] = 0;
return;
}
// For adding Item Decor Insets to view
super.measureChildWithMargins(view, 0, 0);
RecyclerView.LayoutParams p = (RecyclerView.LayoutParams) view.getLayoutParams();
int childWidthSpec = ViewGroup.getChildMeasureSpec(
widthSpec,
getPaddingLeft() + getPaddingRight() + getDecoratedLeft(view) + getDecoratedRight(view),
p.width);
int childHeightSpec = ViewGroup.getChildMeasureSpec(
heightSpec,
getPaddingTop() + getPaddingBottom() + getDecoratedTop(view) + getDecoratedBottom(view),
p.height);
view.measure(childWidthSpec, childHeightSpec);
// Get decorated measurements
measuredDimension[0] = getDecoratedMeasuredWidth(view) + p.leftMargin + p.rightMargin;
measuredDimension[1] = getDecoratedMeasuredHeight(view) + p.bottomMargin + p.topMargin;
recycler.recycleView(view);
}
}
その後、このLayoutManager
をあなたのRecyclerView
に使います。
recyclerView.setLayoutManager(new WrappingLinearLayoutManager(getContext()));
しかし、これら2つのメソッドも呼び出す必要があります。
recyclerView.setNestedScrollingEnabled(false);
recyclerView.setHasFixedSize(false);
ここではsetNestedScrollingEnabled(false)
がRecyclerView
のスクロールを無効にしているので、NestedScrollView
からのスクロールイベントをインターセプトしません。そしてsetHasFixedSize(false)
はアダプタの内容の変更がRecyclerView
のサイズを変更できると決定します
重要な注意: この解決法は場合によっては少しバグがありパフォーマンスに問題があるので、もしあなたがRecyclerView
にたくさんの項目があるなら、リストビューのカスタムLinearLayout
ベースの実装を使うことをお勧めします。それのためのアダプターの類似体そしてそれをListView
またはRecyclerView
のように振る舞わせる
1)上記のサポートライブラリ23.2.0(または)を使用する必要があります。
2)RecyclerView
の高さはwrap_content
になります。
3)recyclerView.setNestedScrollingEnabled(false)
しかしこれをすることによってリサイクル業者パターンは働かない。 (つまり、wrap_content
は完全なRecyclerView
の高さが必要なので、すべてのビューは一度にロードされます。したがって、すべての子View
が一度に描画されます。ビューはリサイクルされません)。本当に必要な場合以外は、このパターンutilを使用しないでください。 viewType
でRecyclerView
を使用するのではなく、RecyclerView
を使用し、Scrollview
にスクロールする必要がある他のすべてのビューを追加してください。パフォーマンスへの影響は非常に大きくなります。
わかりやすくするために、「すべての子ビューでLinearLayout
として機能する」
Android:fillViewport="true"
を使用して、NestedScrollView
にRecyclerView
を測定させることができます。 RecyclerView
は残りの高さを埋めます。したがって、NestScrollView
をスクロールしたい場合は、RecyclerView
のminHeight
を設定できます。
setAdapter
自体の前にrecyclerView.setNestedScrollingEnabled(false);
を追加するだけで私のために働きました。私はどこにもapp:layout_behavior="@string/appbar_scrolling_view_behavior"
を追加しませんでしたそしてカスタムレイアウトマネージャを設定しませんでした
<Android.support.v4.widget.NestedScrollView xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:layout_width="match_parent"
Android:layout_height="match_parent">
<LinearLayout
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:background="@color/white"
Android:orientation="vertical">
<LinearLayout
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:layout_marginLeft="15dp"
Android:layout_marginRight="15dp"
Android:orientation="vertical">
<TextView
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:textColor="@color/white"
Android:text="Some Text..."
Android:padding="15dp" />
</LinearLayout>
<LinearLayout
Android:orientation="vertical"
Android:padding="15dp"
Android:layout_marginTop="10dp"
Android:layout_width="match_parent"
Android:layout_height="wrap_content">
<TextView
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:text="Quick Links"
Android:textColor="@color/black"
Android:textStyle="bold"
Android:textAllCaps="true"
Android:paddingLeft="20dp"
Android:drawableLeft="@drawable/ic_trending_up_black_24dp"
Android:drawablePadding="10dp"
Android:layout_marginBottom="10dp"
Android:textSize="16sp"/>
<View
Android:layout_width="fill_parent"
Android:layout_height="1dp"
Android:background="#efefef"/>
<Android.support.v7.widget.RecyclerView xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:id="@+id/recyclerview"
Android:layout_width="match_parent"
Android:layout_height="match_parent" />
</LinearLayout>
</LinearLayout>
</Android.support.v4.widget.NestedScrollView>
これは私のために働いているものです
<Android.support.v4.widget.NestedScrollView
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:fillViewport="true"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<Android.support.v7.widget.RecyclerView
Android:id="@+id/rv_recycler_view"
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
app:layout_behavior="@string/appbar_scrolling_view_behavior"/>
</Android.support.v4.widget.NestedScrollView>
このライブラリを使ってみてください - https://github.com/serso/Android-linear-layout-manager 。
ライブラリのLayoutManagerはRecyclerViewにその内容をラップさせます。この場合、RecyclerViewは「内側のビューと同じくらいの大きさ」になるので、スクロールバーは表示されず、ユーザーはNestedScrollViewのスクロール機能を使用します。したがって、「スクロール可能な内側のスクロール可能」のようにあいまいになることはありません。
簡単なテストコードがあります。
<Android.support.v4.widget.NestedScrollView
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:fillViewport="true"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<Android.support.v7.widget.RecyclerView
Android:layout_width="match_parent"
Android:layout_height="match_parent"/>
</Android.support.v4.widget.NestedScrollView>
私は RecyclerView を NestedScrollView の中に使って、それは私のために働きました。私が留意しなければならなかった唯一の問題は、NestedScrollViewが1つの子ビューのみをとるということでした。だから私の場合私は自分のRecyclerViewを収納していたLienearLayoutビューグループと私が必要としていた他の多くのビューを使いました。
RecyclerViewをNestedScrollView内に配置するときに問題が1つ発生します。私はRecyclerViewのコンテンツをスクロールするのがゆるいことに気づきました。
私は後でRecyclerViewがスクロールイベントを受信していたため、NestedScrollViewのスクロール動作と競合していたことに気付きました。
そのため、この問題を解決するには、このメソッドでRecyclerViewのスクロール機能を無効にする必要がありましたmovieListNewRecyclerView.setNestedScrollingEnabled(false);
私のInstagramをチェックして、私が実際にしたことの短いビデオを見ることができます。これは私のInstagramのハンドルofelix03です
スクロールの問題を回避するために使用しているコードは次のとおりです。
mRecyclerView = (RecyclerView) view.findViewById(Android.R.id.list);
mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
mRecyclerView.getLayoutManager().setAutoMeasureEnabled(true);
mRecyclerView.setNestedScrollingEnabled(false);
mRecyclerView.setHasFixedSize(false);
NestedScrollViewの中にViewpagerとRecyclerViewがあります。以下の行を追加した後
recyclerView.setNestedScrollingEnabled(false);
recyclerView.setHasFixedSize(false);
私は遅いスクロールとスクロールラグの問題を解決しました。
RecyclerView-23.2.1
以降を使用している場合次の解決策はうまくいくでしょう。
あなたのレイアウトで、以下のようにRecyclerViewを追加してください。
<Android.support.v7.widget.RecyclerView
Android:id="@+id/review_list"
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:scrollbars="vertical" />
そしてあなたのJavaファイルで:
RecyclerView mRecyclerView = (RecyclerView) view.findViewById(R.id.recyclerView);
LinearLayoutManager layoutManager=new LinearLayoutManager(getContext());
layoutManager.setAutoMeasureEnabled(true);
mRecyclerView.setLayoutManager(layoutManager);
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setAdapter(new YourListAdapter(getContext()));
ここでlayoutManager.setAutoMeasureEnabled(true);
がうまくいくでしょう。
入れ子になったスクロールビュー内でリサイクラービューを使用することはできません。これはさらにスクロール可能なビューを含むことを意図したものではありませんが、ネストされたスクロールビューが必要なのは、スクロールレイアウト自体の子だからです。私は同じ問題を抱えていたが、結局私のテキストビューをリサイクラビュー内のヘッダビューにし、リサイクラビューをコーディネータレイアウトの直接の子にし、そしてネストされたスクロールビューを削除した。それから私の問題はすべてなくなりました。
良い答えがたくさんあります。重要なのは、nestedScrollingEnabled
をfalse
に設定する必要があるということです。前述のように、Javaコードでそれを行うことができます。
mRecyclerView.setNestedScrollingEnabled(false);
しかし、あなたはxmlコード(Android:nestedScrollingEnabled="false"
)で同じプロパティを設定する機会もあります。
<Android.support.v7.widget.RecyclerView
Android:id="@+id/recyclerview"
Android:nestedScrollingEnabled="false"
Android:layout_width="match_parent"
Android:layout_height="match_parent" />
androidx
の場合はandroidx.core.widget.NestedScrollView
と呼ばれます。そしてisScrollContainer
とmeasureAllChildren
が有効になっているバターも同様にスクロールします。
<!-- Scrolling Content -->
<androidx.core.widget.NestedScrollView
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:isScrollContainer="true"
Android:measureAllChildren="true"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<androidx.recyclerview.widget.RecyclerView
Android:id="@+id/recyclerview"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:fastScrollEnabled="true"
Android:scrollbarStyle="insideInset"
Android:scrollbars="vertical"
Android:splitMotionEvents="false"
Android:verticalScrollbarPosition="right"/>
</androidx.core.widget.NestedScrollView>
私はツールバーのスクロールを使ってCoordinatorLayoutを実装しなければなりませんでした。私はNestedScrollViewをまったく削除することで動作しています。だから私はルートでRelativeLayoutを使っています。
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:app="http://schemas.Android.com/apk/res-auto"
Android:layout_width="match_parent"
Android:layout_height="match_parent">
<Android.support.v7.widget.RecyclerView
Android:id="@+id/rv_nearby"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
</RelativeLayout>
nestedScrollView内でrecyclerViewを使用しないでください。カスケードの問題が発生する可能性があります!複数の種類のビューを処理するために、RecyclerViewでItemViewTypesを使用することをお勧めします。 match_parentの幅と高さでRecyclerViewを追加するだけです。次に、recyclerViewAdapterでgetItemViewTypeをオーバーライドし、位置を使用してどのレイアウトを拡張するかを処理します。その後、onBindViewHolderメソッドを使用してビューホルダーを処理できます。
RecyclerView ScrollListener inside NestedScrollViewを使用している場合、両方を使用するとaddOnScrollListenerリスナーが正しく機能しません。
このコードを使用してください。
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
......
}
});
このコードは正常に動作していますRecyclerView ScrollListener inside NestedScrollView.
ありがとう
Recyclerviewのリサイクル機能を維持し、すべてのデータをロードするのにrecyclerviewを回避するための1つの解決策は、recyclerview自体に固定の高さを設定することです。こうすることで、リサイクルビューは、その高さがユーザーに表示される分だけロードされるように制限されます。