CardView layout_width =“ match_parent”は、親のRecyclerViewの幅と一致しません


123

私はlayout_width = "match_parent"のRecyclerViewを含むフラグメントを持っています:

<android.support.v7.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_gravity="center"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin"
    tools:context=".MainActivity$PlaceholderFragment" />

RecyclerView内の項目は、同じくlayout_width = "match_parent"が設定されたCardViewです。

<android.support.v7.widget.CardView
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    android:id="@+id/card_view"
    android:layout_gravity="center"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_margin="20dp"
    card_view:cardCornerRadius="4dp">

    <TextView
        android:layout_gravity="center"
        android:id="@+id/info_text"
        android:layout_width="match_parent"
        android:gravity="center"
        android:layout_height="match_parent"
        android:textAppearance="?android:textAppearanceLarge"/>
</android.support.v7.widget.CardView>

以下のようにアイテムビューを膨らませます。

public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,
                                                   int viewType) {
        CardView v = (CardView) LayoutInflater.from(parent.getContext())
                .inflate(R.layout.card_listitem, null, true);

        ViewHolder vh = new ViewHolder(v);
        return vh;
    }

しかし、アプリを実行すると、CardViewは次のようにwrap_contentとしてレンダリングされます。

カードバグ

これは実際のデバイスではなくエミュレータで実行されたことに注意してください。

私は何か間違ったことをしていますか、それともバグですか?


CardViewを拡張するとき、親ビューにtrueパラメータを指定していますか?
nhaarman 2014

こんにちは@NiekHaarman、編集をご覧ください。膨張コードを追加しました。そして、はい、私は本当のパラメータを渡しました。
ProgrAmmar 2014

回答:


291

のドキュメントinflate

指定されたxmlリソースから新しいビュー階層を膨らませます。エラーが発生した場合、InflateExceptionをスローします。

ロードするXMLレイアウトリソースのパラメーター
リソース ID(たとえば、R.layout.main_page)は、生成された階層の親となるルート
ビュー(attachToRootがtrueの場合)、または単にルートのLayoutParams値のセットを提供するオブジェクト返される階層(attachToRootがfalseの場合)
。attachToRootインフレートされ た階層をルートパラメータにアタッチするかどうか。falseの場合、ルートはXMLのルートビューのLayoutParamsの正しいサブクラスを作成するためにのみ使用されます。戻り値インフレートされた階層のルートビュー。ルートが指定され、attachToRootがtrueの場合、これはルートです。それ以外の場合は、インフレートされたXMLファイルのルートです。

することがここで重要なのではない本当の供給、しかしない親を供給します:

LayoutInflater.from(parent.getContext())
            .inflate(R.layout.card_listitem, parent, false);

供給parentビューは、使用にlayoutparams何インフレータのノウハウをすることができます。供給falseパラメータは、それがするように指示していないだけで、まだ親に取り付けます。それがRecyclerViewあなたのために何をするかです。


4
ListViewがlayout_widthだったので、このソリューションは私にはうまくいきませんでしたwrap_content。これはリストビューに影響を与えないため、奇妙です。したがって、私の理解では、layoutinflaterのパラメーターとしてfalseを指定すると、ListViewは、ListView自体に一致するレイアウトパラメーターでリストアイテムをListViewに追加します。:0
reubenjohn 2015年

1
私は同じことをやっていると思うが、実際には機能していないので、あなたは、もう少しコードを投稿できる
ローディ

1
私はあなたの提案を膨らませており、match_parentは私のために働いていません。
Zapnologica 2015年

3
attachToRootをfalseに設定すると、LayoutParams値が定義されたオブジェクトを提供する必要があるというのが正しい理解だと思います。そのオブジェクトは必ずしも親ではありません。「...単に、返された階層のルートのLayoutParams値のセットを提供するオブジェクト(attachToRootがfalseの場合)...」しかし、インフレータがCardViewで定義されているLayoutParamsを読み取れないが必要な理由がわかりませんそれを通知する別のオブジェクトパラメータ?
hjchin

1
カスタムビューを使用している場合、それをどのように処理しますか?私が意味するViewHolder onCreateViewHolder(...) { View v = new MyItemView(parent.getContext); return new ViewHolder(v); }
Krossを

64

CardViewの直接の親としてRelativeLayoutを使用します。

<RelativeLayout 
    android:layout_width="match_parent" ... >
    <CardView 
        android:layout_width="match_parent" ... >
    </CardView>
</RelativeLayout>

はい、これは私にとってもうまくいったようです。私はLinearLayoutを使用していましたが、すでに正確に実行しているため(つまり、ルートに接続せず、親を提供しているため)、上記の提案は機能しませんでした。RelativeLayout +親のアタッチではなく、どちらか一方を提供する必要があります。
chubbsondubs 2016年

1
それは私にとってはうまくいきますが、なぜこれが問題を解決できるのか分かりません。なぜ誰かが説明できますか?
Johnny

1
それは古くからあり、android xは生産中ですが、まだバグは修正されていません!
ムハンマドナデリ

最も簡単な方法。
Abdurahman Popal

同様の問題があり、カードビューの幅を修正するのに役立ちましたが、高さに同様の問題がありますか?そのために何か提案してもらえますか?

12

これは私のために働いた、

 View viewHolder= LayoutInflater.from(parent.getContext())
            .inflate(R.layout.item, null, false);
 viewHolder.setLayoutParams(new RecyclerView.LayoutParams(RecyclerView.LayoutParams.MATCH_PARENT, RecyclerView.LayoutParams.WRAP_CONTENT));
 return new ViewOffersHolder(viewHolder);

6

私がそれをした方法は:

View view = mInflater.inflate(R.layout.row_cardview, null, true);
            WindowManager windowManager = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);
            int width = windowManager.getDefaultDisplay().getWidth();
            view.setLayoutParams(new RecyclerView.LayoutParams(width, RecyclerView.LayoutParams.MATCH_PARENT));

説明: カードビューを取得したら、onCreateViewHoldeで画面の幅を取得し、それに応じてレイアウトビューをカードビューに設定します。


1
これを少し改善してください。基本的には「これを試してみてください」と書かれています
Drew

説明を追加。確認してください。さらにヘルプが必要な場合は、ここにコメントしてください。
Rahul


4

新しいレイアウトパラメータを設定するだけ

view.setLayoutParams(new RecyclerView.LayoutParams(
    RecyclerView.LayoutParams.MATCH_PARENT,
    RecyclerView.LayoutParams.WRAP_CONTENT
));

onBindViewHolder()でこれを行うと、ConstraintLayoutから継承するカスタムビュークラスを使用するときに便利です。
Rasmusob 2017

レイアウトに設定されているマージンに影響を与えるため、良い答えではありません。
Emi Raz

4

デフォルトの実装では、デフォルトのレイアウトマネージャーでwrap_contentを強制的に使用します。

  @Override
public LayoutParams generateDefaultLayoutParams() {
    return new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
            ViewGroup.LayoutParams.WRAP_CONTENT);
}

次のように、LayoutManagerでこのメソッドをオーバーライドするだけです。

  @Override
public LayoutParams generateDefaultLayoutParams() {
    return new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
            ViewGroup.LayoutParams.WRAP_CONTENT);
}

2

これは私のために働く

View view = inflator.inflate(R.layout.layout_item, ***null***, false);

1

負の値でcard_view:contentPaddingを使用します

<android.support.v7.widget.CardView
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    card_view:contentPadding="-4dp"
    card_view:cardElevation="0dp"
    android:layout_height="wrap_content">

それは私のために働いた


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.