wake-up-neo.com

CardView layout_width = "match_parent" stimmt nicht mit der übergeordneten RecyclerView-Breite überein

Ich habe ein Fragment mit einem RecyclerView mit layout_width = "match_parent":

<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" />

Das Element in der RecyclerView ist eine CardView, auch mit layout_width = "match_parent":

<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>

Ich blase die Artikelansicht wie folgt auf:

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;
    }

Wenn ich die App ausführe, wird CardView wie folgt als wrap_content gerendert:

CardsBug

Beachten Sie, dass dies auf einem Emulator ausgeführt wurde, nicht auf einem echten Gerät.

Mache ich etwas falsch oder ist es ein Fehler?

116
ProgrAmmar

Die Dokumente für inflate:

Erstellen Sie eine neue Ansichtshierarchie aus der angegebenen XML-Ressource. Löst InflateException aus, wenn ein Fehler vorliegt.

Parameter
resource ID für eine XML-Layout-Ressource zum Laden des Stammverzeichnisses (z. B. R.layout.main_page)
view Übergeordnetes Element der generierten Hierarchie sein (wenn attachToRoot true ist) oder einfach ein Objekt, das eine Reihe von LayoutParams-Werten für das Stammverzeichnis der zurückgegebenen Hierarchie bereitstellt (wenn attachToRoot true ist) falsch.)
attachToRoot Soll die aufgeblähte Hierarchie an den root-Parameter angehängt werden? Wenn false, wird root nur verwendet, um die richtige Unterklasse von LayoutParams für die Stammansicht in der XML zu erstellen. Rückgabe Die Stammansicht der aufgeblasenen Hierarchie. Wenn root angegeben wurde und attachToRoot true ist, ist dies root. Andernfalls ist es das Stammverzeichnis der aufgeblasenen XML-Datei.

Hier ist es wichtig, dass nicht true, sondern do den Elternteil liefert :

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

Wenn Sie die parent -Ansicht angeben, wird dem Inflater mitgeteilt, welche Layoutparameter verwendet werden sollen. Wenn der Parameter false angegeben wird, darf er noch nicht an das übergeordnete Element angehängt werden. Das ist es, was der RecyclerView für Sie tun wird.

279
nhaarman

Verwenden Sie RelativeLayout als unmittelbares übergeordnetes Element von CardView.

<RelativeLayout 
    Android:layout_width="match_parent" ... >
    <CardView 
        Android:layout_width="match_parent" ... >
    </CardView>
</RelativeLayout>
57
Ganesh Kanna

Das hat bei mir funktioniert,

 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);
11
anurag_dake

So habe ich es gemacht:

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));

Erklärung: Wenn Sie in Ihrem onCreateViewHolde die Kartenansicht erhalten haben, ermitteln Sie die Bildschirmbreite und stellen Sie die Layoutparameter entsprechend für die Kartenansicht ein.

6
Rahul

Dies scheint in 'com.Android.support:recyclerview-v7:23.2.1' Behoben zu sein.

Siehe: RecyclerView wrap_content für weitere Diskussionen.

5
speedynomads

Legen Sie einfach neue Layoutparameter fest

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

Die Standardimplementierung erzwingt die Verwendung von wrap_content im Standardlayout-Manager:

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

Alles was Sie tun müssen, ist diese Methode in Ihrem LayoutManager wie folgt zu überschreiben:

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

Das funktioniert bei mir

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

Verwenden Sie card_view: contentPadding mit einem negativen Wert

<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">

Es hat bei mir funktioniert

1