web-dev-qa-db-ja.com

サポートライブラリを「23.1.1」から「23.2.1」にアップグレードした後、リサイクルビュー項目がリサイクルビュー全体の高さを埋める

以前は、次の古いサポートライブラリ「23.1.1」を使用しています。

_compile 'com.Android.support:appcompat-v7:23.1.1'
compile 'com.Android.support:support-v4:23.1.1'
compile 'com.Android.support:preference-v7:23.1.1'
compile 'com.Android.support:preference-v14:23.1.1'
compile 'com.Android.support:design:23.1.1'
compile 'com.Android.support:recyclerview-v7:23.1.1'
_

それはかなりうまくいきます。 RecyclerViewは次のようになります

enter image description here

いくつかのバグ修正が行われたため、「23.2.1」に移行したいと思います。

_compile 'com.Android.support:appcompat-v7:23.2.1'
compile 'com.Android.support:support-v4:23.2.1'
compile 'com.Android.support:preference-v7:23.2.1'
compile 'com.Android.support:preference-v14:23.2.1'
compile 'com.Android.support:design:23.2.1'
compile 'com.Android.support:recyclerview-v7:23.2.1'
_

しかし、突然、すべてのRecyclerViewアイテムがRecyclerViewの高さ全体を埋めるように見えます。

enter image description here

enter image description here

レイアウトファイルのコードスニペットを次に示します。 https://Gist.github.com/yccheok/241a0d38d56305a1be24d09b54eb16

私を本当に困惑させているのは、リサイクラーのビューアイテムのレイアウトで_"wrap_content"_を使用しているにもかかわらず、期待どおりに機能しないことです。

RecyclerViewにカスタムレイアウトマネージャーを使用していません。

http://developer.Android.com/tools/support-library/index.html から、今度は23.2.1がRecyclerViewでかなりの数の変更を行っていることがわかります。

  • さまざまなmeasure-specメソッドに関連するバグを修正しました。 (問題201856)
  • RecyclerViewがレイアウトまたはスクロールの計算中にアダプターの変更を許可しないロックダウン期間を短縮しました。 (問題202046)。
  • 表示されていないアイテムでnotifyItemChanged()を呼び出すとクラッシュする問題を修正しました。 (問題202136)
  • _RecyclerView.LayoutManager_が同じ測定パスでビューを追加および削除するときに発生するクラッシュを修正しました。 (問題193958)

私が最も疑うのは https://code.google.com/p/Android/issues/detail?id=201856 です。これは、変更を伴うためですさまざまなmeasure-specメソッド

これまでのところ、23.2.1の単純なRecyclerViewプロジェクトで問題を再現しようとしましたが、失敗しました! 「アイテムがRecyclerView全高を埋める」問題はありません。私の推測では、私の単純なプロジェクトは、本番プロジェクトの複雑なレイアウト構造をシミュレートしていません。私の生産プロジェクトは次のレイアウトを持っています

_<Activity>
    <Fragment>
        <View Pager>
            <Fragment>
                <RecyclerView />
            </Fragment>
        </View Pager>
    </Fragment>
</Activity>
_

数時間デバッグした後でも、そのような問題の根本的な原因を見つけることができません、ヒントはありますか?

ありがとう。

私が試したこと

RecyclerViewを変更しようとしました

から

_<Android.support.v7.widget.RecyclerView
    Android:id="@+id/recycler_view"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
_

_<Android.support.v7.widget.RecyclerView
    Android:id="@+id/recycler_view"
    Android:layout_width="match_parent"
    Android:layout_height="wrap_content"
_

最初は良さそうです。ただし、スクロールを実行すると、期待どおりに動作しません: https://www.youtube.com/watch?v=U2EChFn6WkI

更新:最終的に根本原因を突き止めました

私の側では間違いです!最後の行項目に別のマージンを設定する必要があるため、ここに私のアダプターコードを示します。

_@Override
public void onBindViewHolder(ViewHolder holder, int position) {
    final List<TransactionSummary> transactionSummaries = buyArray.transactionSummaries;

    if (position == transactionSummaries.size() - 1) {
        holder.itemView.setLayoutParams(lastLayoutParams);
    } else {
        holder.itemView.setLayoutParams(normalLayoutParams);
    }
_

残念ながら、lastLayoutParamsnormalLayoutParamsは次のように初期化されています

_    normalLayoutParams = new LinearLayout.LayoutParams(
        LinearLayout.LayoutParams.MATCH_PARENT,
        LinearLayout.LayoutParams.MATCH_PARENT
    );

    lastLayoutParams = new LinearLayout.LayoutParams(
        LinearLayout.LayoutParams.MATCH_PARENT,
        LinearLayout.LayoutParams.MATCH_PARENT
    );
_

_LinearLayout.LayoutParams.WRAP_CONTENT_を使用して問題を解決します。

44
Cheok Yan Cheng

更新

LayoutParamViewAdapterを更新しているようです。

これは、スクロールを開始するまでUIがまったく問題なく表示されるためです。これは、XMLレイアウトファイルで定義されているXMLが正しいことを意味します。

スクロールの開始後に変化するという事実は、onBindViewHolder実装に論理エラーがあることを意味します。そのため、下にスクロールするとエラーが表示され、上にスクロールするとエラーが発生し続けます。

古い答え

問題は、仕切りが不正になったことです。

<View
    Android:layout_width="1px"
    Android:layout_height="match_parent"
    Android:background="?attr/buyPortfolioSeperatorBackground"
    Android:layout_marginRight="5dp"
    Android:layout_marginLeft="5dp" />

テストのために、次のように設定します。

<View
    Android:layout_width="1px"
    Android:layout_height="30dp"
    Android:background="?attr/buyPortfolioSeperatorBackground"
    Android:layout_marginRight="5dp"
    Android:layout_marginLeft="5dp" />

必ず両方を変更してください!

17
Knossos

同様の問題がありました。最終的には、リサイクル業者が問題ではなかったということになります。 CardViewアイテムの測定値が次のように変換されることを確認します。

<Android.support.v7.widget.CardView
    xmlns:card_view="http://schemas.Android.com/apk/res-auto"
    Android:layout_width="match_parent"
    Android:layout_height="wrap_content"
    ...
/>

CardViewを使用していない場合は、ビューのアダプターで使用する要素にAndroid:layout_height="wrap_content"およびmatch_parent

それでもうまくいかない場合は、ビューアイテムのminHeightまたはmaxHeightを設定する別の属性を追加できます。

10
Patrick W

朗報:

RecyclerViewの動作を変更した正確なバージョンを特定できます。23.2.1の変更ではなく、 23.2.0(2016年2月) の変更です。すなわち:

RecyclerView.LayoutManagerは、スクロール方向のMATCH_PARENTなどの一部のRecyclerView.LayoutParams設定を無視しなくなりました。

注:これらの解除された制限により、レイアウトで予期しない動作が発生する場合があります。正しいレイアウトパラメータを指定していることを確認してください。

実際、23.2.0ライブラリを起動すると、同じ動作が見られます。あなたの場合、その振る舞いは次のように単純化できます:

これで、RecyclerViewの子にAndroid:layout_x="match_parent"、RecyclerViewのAndroid:layout_x、これは23.1.1以前のバージョンには当てはまりませんでした。

悪いニュース:

これがあなたの問題の原因であると99%確信していても、あなたのコードに問題を見つけることはできません。実際には、LinearLayoutManagerを使用して、XML構造(色/背景パラメーターのみを変更)でRecyclerViewを設定しましたが、23.2.1で期待どおりに機能します。健全性チェックを実行する場合は、実装を共有できます。

アダプタの実装/操作が大幅に拡張されている場合でも、再確認する必要があります。

8
Sevle

このバグを修正するには、row_layoutに高さが必要ですfixedまたはwrap_content!私もこの問題を抱えていましたが、row_layoutの高さがmatch_parentであることがわかりました。

4
Liridon Sadiku

リサイクルビューの高さは「wrap_content」のみにする必要があります。セルのサイズが大きくなると、リサイクルビューは高さを処理します。

buy_portfolio_fragment.xml

 <Android.support.v7.widget.RecyclerView
        Android:id="@+id/recycler_view"
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content"
        Android:background="?attr/buyPortfolioListViewBackground"
        Android:requiresFadingEdge="none"
        Android:scrollbars="vertical"
        Android:paddingTop="@dimen/default_tab_layout_height"
        Android:clipToPadding="false" />
3

私はこれが問題のある行だと思う:

<View   Android:layout_width="1px"
            Android:layout_height="match_parent"    <!--change this to wrap_content-->
            Android:background="?attr/buyPortfolioSeperatorBackground"
            Android:layout_marginRight="5dp"
            Android:layout_marginLeft="5dp" />

レイアウトアイテムには、layout_height = "match_parent"がある2つの場所があります。両方をwrap_contentに変更する必要があります。

2
Tiago

ただrow_layout高さからwrap_contentそのため、すべてのアイテムに対して行の実際の高さスペースのみが使用されます。

1
Abhishek Kumar