Die Ansichtshöhe des verschachtelten Recyclers umschließt seinen Inhalt nicht

Lesezeit: 17 Minuten

Die Ansichtshohe des verschachtelten Recyclers umschliest seinen Inhalt nicht
Twibit

Ich habe eine Anwendung, die Sammlungen von Büchern (wie Wiedergabelisten) verwaltet.

Ich möchte eine Sammlungsliste mit einer vertikalen RecyclerView und in jeder Zeile eine Liste mit Büchern in einer horizontalen RecyclerView anzeigen.

Wenn ich die layout_height der inneren horizontalen RecyclerView auf 300dp setze, wird sie aber korrekt angezeigt Wenn ich es auf wrap_content setze, wird nichts angezeigt.
Ich muss wrap_content verwenden, weil ich in der Lage sein möchte, den Layout-Manager programmgesteuert zu ändern, um zwischen vertikaler und horizontaler Anzeige zu wechseln.

Geben Sie hier die Bildbeschreibung ein

Weißt du was ich falsch mache?

Mein Fragment-Layout:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:background="@color/white">

    <com.twibit.ui.view.CustomSwipeToRefreshLayout
        android:id="@+id/swipe_container"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical">

            <android.support.v7.widget.RecyclerView
                android:id="@+id/shelf_collection_listview"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:paddingTop="10dp"/>

        </LinearLayout>

    </com.twibit.ui.view.CustomSwipeToRefreshLayout>
</LinearLayout>

Sammlungselement-Layout:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="match_parent"
              android:layout_height="wrap_content"
              android:orientation="vertical">

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:background="#FFF">

        <!-- Simple Header -->

    </RelativeLayout>

    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <TextView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:text="@string/empty_collection"
            android:id="@+id/empty_collection_tv"
            android:visibility="gone"
            android:gravity="center"/>

        <android.support.v7.widget.RecyclerView
            android:id="@+id/collection_book_listview"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/> <!-- android:layout_height="300dp" -->

    </FrameLayout>

</LinearLayout>

Artikel der Buchliste:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="180dp"
              android:layout_height="220dp"
              android:layout_gravity="center">

        <ImageView
            android:id="@+id/shelf_item_cover"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:maxWidth="150dp"
            android:maxHeight="200dp"
            android:src="https://stackoverflow.com/questions/26649406/@drawable/placeholder"
            android:contentDescription="@string/cover"
            android:adjustViewBounds="true"
            android:background="@android:drawable/dialog_holo_light_frame"/>

</FrameLayout>

Hier ist mein Sammeladapter:

private class CollectionsListAdapter extends RecyclerView.Adapter<CollectionsListAdapter.ViewHolder> {
    private final String TAG = CollectionsListAdapter.class.getSimpleName();
    private Context mContext;

    // Create the ViewHolder class to keep references to your views
    class ViewHolder extends RecyclerView.ViewHolder {

        private final TextView mHeaderTitleTextView;
        private final TextView mHeaderCountTextView;

        private final RecyclerView mHorizontalListView;
        private final TextView mEmptyTextView;

        public ViewHolder(View view) {
            super(view);

            mHeaderTitleTextView = (TextView) view.findViewById(R.id.collection_header_tv);
            mHeaderCountTextView = (TextView) view.findViewById(R.id.collection_header_count_tv);

            mHorizontalListView = (RecyclerView) view.findViewById(R.id.collection_book_listview);
            mEmptyTextView = (TextView) view.findViewById(R.id.empty_collection_tv);
        }
    }


    public CollectionsListAdapter(Context context) {
        mContext = context;
    }


    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int i) {
        Log.d(TAG, "CollectionsListAdapter.onCreateViewHolder(" + parent.getId() + ", " + i + ")");
        // Create a new view by inflating the row item xml.
        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.shelf_collection, parent, false);

        // Set the view to the ViewHolder
        ViewHolder holder = new ViewHolder(v);

        holder.mHorizontalListView.setHasFixedSize(false);
        holder.mHorizontalListView.setHorizontalScrollBarEnabled(true);

        // use a linear layout manager
        LinearLayoutManager mLayoutManager = new LinearLayoutManager(mContext);
        mLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
        holder.mHorizontalListView.setLayoutManager(mLayoutManager);

        return holder;
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, int i) {
        Log.d(TAG, "CollectionsListAdapter.onBindViewHolder(" + holder.getPosition() + ", " + i + ")");

        Collection collection = mCollectionList.get(i);
        Log.d(TAG, "Collection : " + collection.getLabel());

        holder.mHeaderTitleTextView.setText(collection.getLabel());
        holder.mHeaderCountTextView.setText("" + collection.getBooks().size());

        // Create an adapter if none exists
        if (!mBookListAdapterMap.containsKey(collection.getCollectionId())) {
            mBookListAdapterMap.put(collection.getCollectionId(), new BookListAdapter(getActivity(), collection));
        }

        holder.mHorizontalListView.setAdapter(mBookListAdapterMap.get(collection.getCollectionId()));

    }

    @Override
    public int getItemCount() {
        return mCollectionList.size();
    }
}

Und schließlich der Book-Adapter :

private class BookListAdapter extends RecyclerView.Adapter<BookListAdapter.ViewHolder> implements View.OnClickListener {
    private final String TAG = BookListAdapter.class.getSimpleName();

    // Create the ViewHolder class to keep references to your views
    class ViewHolder extends RecyclerView.ViewHolder {
        public ImageView mCoverImageView;

        public ViewHolder(View view) {
            super(view);
            mCoverImageView = (ImageView) view.findViewById(R.id.shelf_item_cover);
        }
    }

    @Override
    public void onClick(View v) {
        BookListAdapter.ViewHolder holder = (BookListAdapter.ViewHolder) v.getTag();
        int position = holder.getPosition();
        final Book book = mCollection.getBooks().get(position);

        // Click on cover image
        if (v.getId() == holder.mCoverImageView.getId()) {
            downloadOrOpenBook(book);
            return;
        }
    }

    private void downloadOrOpenBook(final Book book) {
        // do stuff
    }

    private Context mContext;
    private Collection mCollection;

    public BookListAdapter(Context context, Collection collection) {
        Log.d(TAG, "BookListAdapter(" + context + ", " + collection + ")");
        mCollection = collection;
        mContext = context;
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int i) {
        Log.d(TAG, "onCreateViewHolder(" + parent.getId() + ", " + i + ")");
        // Create a new view by inflating the row item xml.
        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.shelf_grid_item, parent, false);

        // Set the view to the ViewHolder
        ViewHolder holder = new ViewHolder(v);
        holder.mCoverImageView.setOnClickListener(BookListAdapter.this); // Download or Open

        holder.mCoverImageView.setTag(holder);

        return holder;
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, int i) {
        Log.d(TAG, "onBindViewHolder(" + holder.getPosition() + ", " + i + ")");

        Book book = mCollection.getBooks().get(i);

        ImageView imageView = holder.mCoverImageView;
        ImageLoader.getInstance().displayImage(book.getCoverUrl(), imageView);
    }

    @Override
    public int getItemCount() {
        return mCollection.getBooks().size();
    }
}

  • Warum müssen Sie wrap_content verwenden, um den Layoutmanager zwischen vertikal und horizontal zu ändern?

    – AmaJayJB

    30. Oktober 2014 um 9:47 Uhr

  • Wenn ich die layout_height auf einen bestimmten Wert setze (sagen wir die Höhe eines Elements für den horizontalen Layout-Manager), wird nur die erste Zeile der Liste mit dem vertikalen Layout-Manager angezeigt.

    – Twibit

    30. Oktober 2014 um 9:52 Uhr

  • Aber recyclerView hat eine eingebaute ScrollView, sodass Sie einfach durch die Elemente scrollen können … oder verfehle ich hier den Punkt? Entschuldigung, ich versuche es zu verstehen

    – AmaJayJB

    30. Oktober 2014 um 10:02 Uhr

  • Ich möchte Sammlungsinhalte durchblättern, aber nicht die innere Buchliste (außer horizontal). So etwas wie ExpandableListView.

    – Twibit

    30. Oktober 2014 um 10:12 Uhr

  • Ich stehe vor der gleichen Frage mit dir, hast du sie jetzt gelöst?

    – VinceStyling

    2. November 2014 um 9:30 Uhr

1646241193 899 Die Ansichtshohe des verschachtelten Recyclers umschliest seinen Inhalt nicht
Denis Neke

@ user2302510 Lösung funktioniert nicht so gut wie erwartet. Vollständige Problemumgehung für beide Ausrichtungen und dynamische Datenänderungen ist:

public class MyLinearLayoutManager extends LinearLayoutManager {

    public MyLinearLayoutManager(Context context, int orientation, boolean reverseLayout)    {
        super(context, orientation, reverseLayout);
    }

    private int[] mMeasuredDimension = new int[2];

    @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++) {
            measureScrapChild(recycler, i,
                    View.MeasureSpec.makeMeasureSpec(i, View.MeasureSpec.UNSPECIFIED),
                    View.MeasureSpec.makeMeasureSpec(i, View.MeasureSpec.UNSPECIFIED),
                    mMeasuredDimension);

            if (getOrientation() == HORIZONTAL) {
                width = width + mMeasuredDimension[0];
                if (i == 0) {
                    height = mMeasuredDimension[1];
                }
            } else {
                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 != null) {
            RecyclerView.LayoutParams p = (RecyclerView.LayoutParams) view.getLayoutParams();
            int childWidthSpec = ViewGroup.getChildMeasureSpec(widthSpec,
                    getPaddingLeft() + getPaddingRight(), p.width);
            int childHeightSpec = ViewGroup.getChildMeasureSpec(heightSpec,
                    getPaddingTop() + getPaddingBottom(), p.height);
            view.measure(childWidthSpec, childHeightSpec);
            measuredDimension[0] = view.getMeasuredWidth() + p.leftMargin + p.rightMargin;
            measuredDimension[1] = view.getMeasuredHeight() + p.bottomMargin + p.topMargin;
            recycler.recycleView(view);
        }
    }
}

  • Ihre Lösung funktioniert ziemlich gut, scheint aber ItemDecoration (z. B. Trennzeichen) nicht zu berücksichtigen.

    – Twibit

    23. Dezember 2014 um 10:35 Uhr

  • Ich bin mir noch nicht sicher warum, aber das Scrollen scheint nicht zu funktionieren. Ich habe diesen Code mit einem vertikal scrollenden Layout ausprobiert … Wenn die Elemente kleiner als die Höhe des Bildschirms sind, funktioniert alles einwandfrei. Wenn es jedoch mehr Elemente gibt, als auf dem Bildschirm angezeigt werden können, funktioniert das Scrollen nicht.

    – Justin

    6. Januar 2015 um 8:07 Uhr

  • Dies funktioniert nicht mit Animationen zum Ändern von Inhalten – die Größe der Recycleransicht rastet ein, anstatt sanft zu wachsen / zu schrumpfen.

    – zyamis

    21. Februar 2015 um 4:06 Uhr

  • Hier ist eine verfeinerte Version der Klasse, die zu funktionieren scheint und keine Probleme mit anderen Lösungen hat: github.com/serso/android-linear-layout-manager/blob/master/lib/…

    – se.solowjew

    29. April 2015 um 13:49 Uhr

  • Ich verwende diese Recyclerview innerhalb von Scrollview und mache Recyclerview Wrap-Inhalte mit diesem Code. Das Scrollen in der Scrollansicht ist jedoch nicht reibungslos. Die Lösung ist stackoverflow.com/a/32283439/3736955

    – Jemshit Iskenderov

    3. September 2015 um 8:51 Uhr

1646241194 178 Die Ansichtshohe des verschachtelten Recyclers umschliest seinen Inhalt nicht
verblüfft

Aktualisieren

Viele Probleme im Zusammenhang mit dieser Funktion in Version 23.2.0 wurden in 23.2.1 behoben, aktualisieren Sie stattdessen darauf.

Mit der Veröffentlichung der Support-Bibliothek Version 23.2 RecyclerView jetzt unterstützt das!

Aktualisieren build.gradle zu:

compile 'com.android.support:recyclerview-v7:23.2.1'

oder jede Version darüber hinaus.

Diese Version bringt eine aufregende neue Funktion in die LayoutManager-API: automatische Messung! Dadurch kann eine RecyclerView ihre Größe basierend auf der Größe ihres Inhalts anpassen. Dies bedeutet, dass zuvor nicht verfügbare Szenarien, wie z. B. die Verwendung von WRAP_CONTENT für eine Dimension der RecyclerView, jetzt möglich sind. Sie werden feststellen, dass alle eingebauten LayoutManager jetzt die automatische Messung unterstützen.

Dies kann über deaktiviert werden setAutoMeasurementEnabled() wenn nötig. Prüfen Sie im Detail Hier.

  • Vorsichtig sein! Hier sind neue Fehler: stackoverflow.com/questions/35619022/…

    – Denis Nek

    25. Februar 2016 um 10:28 Uhr


  • behebt das den Fehler oben?

    – Rausch

    7. März 2016 um 12:24 Uhr

  • Dies funktioniert nicht immer richtig, wenn Sie das Leerzeichen zwischen den einzelnen Elementen sehen

    – RAHULRSANSIDHI

    8. März 2016 um 12:50 Uhr

  • Bitte achten Sie darauf, dass die Höhe des übergeordneten Layouts, das die untergeordnete Recycler-Ansicht enthält, Wrap-Inhalt sein muss.

    – RAHULRSANSIDHI

    9. März 2016 um 11:37 Uhr

  • Ausführung 23.2.1 von RecyclerView scheint mehrere Fehler behoben zu haben. Funktioniert bei uns sehr gut. Wenn nicht, kannst du es sogar mit versuchen 24.0.0-alpha1

    – Joaquin Iurchuk

    17. März 2016 um 12:08 Uhr


1646241194 714 Die Ansichtshohe des verschachtelten Recyclers umschliest seinen Inhalt nicht
Kaerdan

Der obige Code funktioniert nicht gut, wenn Sie Ihre Artikel zu “wrap_content” machen müssen, da er sowohl die Höhe als auch die Breite der Artikel mit MeasureSpec.UNSPECIFIED misst. Nach einigen Problemen habe ich diese Lösung geändert, sodass Elemente jetzt erweitert werden können. Der einzige Unterschied besteht darin, dass die Höhe oder Breite der Eltern angegeben wird. MeasureSpec hängt von der Layoutausrichtung ab.

public class MyLinearLayoutManager extends LinearLayoutManager {

public MyLinearLayoutManager(Context context, int orientation, boolean reverseLayout)    {
    super(context, orientation, reverseLayout);
}

private int[] mMeasuredDimension = new int[2];

@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(i, View.MeasureSpec.UNSPECIFIED),
                    heightSpec,
                    mMeasuredDimension);

            width = width + mMeasuredDimension[0];
            if (i == 0) {
                height = mMeasuredDimension[1];
            }
        } else {
            measureScrapChild(recycler, i,
                    widthSpec,
                    View.MeasureSpec.makeMeasureSpec(i, 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);
    recycler.bindViewToPosition(view, position);
    if (view != null) {
        RecyclerView.LayoutParams p = (RecyclerView.LayoutParams) view.getLayoutParams();
        int childWidthSpec = ViewGroup.getChildMeasureSpec(widthSpec,
                getPaddingLeft() + getPaddingRight(), p.width);
        int childHeightSpec = ViewGroup.getChildMeasureSpec(heightSpec,
                getPaddingTop() + getPaddingBottom(), p.height);
        view.measure(childWidthSpec, childHeightSpec);
        measuredDimension[0] = view.getMeasuredWidth() + p.leftMargin + p.rightMargin;
        measuredDimension[1] = view.getMeasuredHeight() + p.bottomMargin + p.topMargin;
        recycler.recycleView(view);
    }
}
}

  • Danke! Diese Lösung hat bei mir am besten funktioniert. Denis’ schien nicht genug zu messen und die Ansicht war immer noch scrollbar. Sinans schien sich nur dann richtig zu verhalten, wenn es ein einzelnes Kind gab. Hinweis: Meine untergeordneten Ansichten verwendet wrap_content

    – kasim

    10. März 2015 um 23:30 Uhr


  • Um das Scrollen zu ermöglichen, wenn es die Grenzen der übergeordneten Ansicht erreicht, musste ich einfügen switch (heightMode) { case View.MeasureSpec.AT_MOST: if (height < heightSize) break; case View.MeasureSpec.EXACTLY: height = heightSize; case View.MeasureSpec.UNSPECIFIED: }

    – kasim

    6. April 2015 um 1:49 Uhr


  • Hervorragende Lösung. Dies funktionierte perfekt. Nebenbei bemerkt, anstatt einen Konstruktor zu verwenden, habe ich einfach eine private Instanzvariable und eine Setter/Getter-Methode mit einer Konstanten final int ORIENTATION erstellt (nur für den Fall, dass jemand anderes ein Problem hat) und diese dann verwendet, um die übergebene Ausrichtung zu überprüfen .

    – PGMacDesign

    29. Mai 2015 um 20:03 Uhr

  • Ich habe Probleme mit Lollipop und höher, ScrollView, das RecyclerView umschließt, funktioniert nicht richtig (es gibt keine Schleudern), wenn Sie versucht haben, über RecyclerView zu scrollen. Um dieses Problem zu lösen, müssen Sie NotScrollableRecyclerView (benutzerdefiniert) erstellen und onInterceptTouchEvent- und onTouchEvent-Methoden überschreiben, ohne Superimplementierungen davon aufzurufen, und Sie sollten in beiden Methoden false zurückgeben.

    – ultraon

    17. Juli 2015 um 17:22 Uhr

  • Das funktioniert, aber ich verstehe nicht, warum es so unnötig komplex ist, das Ding einfach seine Höhe messen zu lassen, nachdem die Größe seiner Kinder berechnet wurde …

    – Joe Maher

    3. November 2015 um 3:31 Uhr

Vorhandene Layout-Manager unterstützen noch keine Wrap-Inhalte.

Sie können einen neuen LayoutManager erstellen, der den vorhandenen erweitert und die onMeasure-Methode überschreibt, um den Umbruchinhalt zu messen.

Die Ansichtshohe des verschachtelten Recyclers umschliest seinen Inhalt nicht
Sinan Kosak

Wie @yiğit erwähnt hat, müssen Sie onMeasure() überschreiben. Sowohl @user2302510 als auch @DenisNek haben gute Antworten, aber wenn Sie ItemDecoration unterstützen möchten, können Sie diesen benutzerdefinierten Layout-Manager verwenden.

Und andere Antworten können nicht gescrollt werden, wenn mehr Elemente vorhanden sind, als auf dem Bildschirm angezeigt werden können. Dieser verwendet die Standardimplementierung von onMeasure(), wenn mehr Elemente als die Bildschirmgröße vorhanden sind.

public class MyLinearLayoutManager extends LinearLayoutManager {

public MyLinearLayoutManager(Context context, int orientation, boolean reverseLayout)    {
    super(context, orientation, reverseLayout);
}

private int[] mMeasuredDimension = new int[2];

@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++) {
        measureScrapChild(recycler, i,
                View.MeasureSpec.makeMeasureSpec(i, View.MeasureSpec.UNSPECIFIED),
                View.MeasureSpec.makeMeasureSpec(i, View.MeasureSpec.UNSPECIFIED),
                mMeasuredDimension);

        if (getOrientation() == HORIZONTAL) {
            width = width + mMeasuredDimension[0];
            if (i == 0) {
                height = mMeasuredDimension[1];
            }
        } else {
            height = height + mMeasuredDimension[1];
            if (i == 0) {
                width = mMeasuredDimension[0];
            }
        }
    }

    // If child view is more than screen size, there is no need to make it wrap content. We can use original onMeasure() so we can scroll view.
    if (height < heightSize && width < widthSize) {

        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);
    } else {
        super.onMeasure(recycler, state, widthSpec, heightSpec);
    }
}

private void measureScrapChild(RecyclerView.Recycler recycler, int position, int widthSpec,
                               int heightSpec, int[] measuredDimension) {

   View view = recycler.getViewForPosition(position);

   // For adding Item Decor Insets to view
   super.measureChildWithMargins(view, 0, 0);
    if (view != null) {
        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() + getPaddingBottom() + 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);
        }
    }
}

Und wenn Sie es mit GridLayoutManager verwenden möchten, erweitern Sie es einfach von GridLayoutManager und ändern Sie es

for (int i = 0; i < getItemCount(); i++)

zu

for (int i = 0; i < getItemCount(); i = i + getSpanCount())

  • Dies ist die Lösung, die richtig funktioniert, ich habe alle anderen in diesem Thread getestet und alle hatten Probleme

    – wasyl

    17. Februar 2015 um 15:10 Uhr

  • Diese Lösung hat bei mir auch sehr gut funktioniert. Das einzige Problem war, dass umbrochener Text im untergeordneten Element nicht richtig berücksichtigt wird. Siehe meine Antwort oben für die Lösung dieses Problems.

    – Bishbulb

    31. März 2015 um 13:58 Uhr

  • Dies funktioniert nicht für Gridlayout (ja, ich habe die Änderungen übernommen). Zuerst scheint es zu funktionieren, dann ändere ich die Ausrichtung hin und her, und die Höhe wird gegenüber der ursprünglichen Höhe geändert. Auch die Ansichten verhalten sich nicht wie erwartet (z. B. funktionieren Onclicks bei den meisten nicht, während sie mit einem einfachen Gridlayoutmanager funktionieren).

    – Tschabi

    28. Juli 2015 um 14:37 Uhr


  • Wie können wir dasselbe erreichen für gridlayoutmanager und staggeredgridlayoutmanager unter Berücksichtigung der Span-Anzahl?

    – Amrut Bidri

    18. August 2015 um 9:28 Uhr

  • Soll dieser MyLinearLayoutManager auf die untergeordnete Recycler-Ansicht oder auf die übergeordnete Ansicht angewendet werden? oder beides?

    – CommonSenseCode

    6. November 2015 um 14:52 Uhr

1646241195 427 Die Ansichtshohe des verschachtelten Recyclers umschliest seinen Inhalt nicht
Wadim Kotow

Update März 2016

Durch Android-Unterstützungsbibliothek 23.2.1 einer unterstützenden Bibliotheksversion. So alles WRAP_CONTENT sollte korrekt funktionieren.

Bitte aktualisieren Sie die Version einer Bibliothek in der Gradle-Datei.

compile 'com.android.support:recyclerview-v7:23.2.1'

Dadurch kann eine RecyclerView ihre Größe basierend auf der Größe ihres Inhalts anpassen. Das bedeutet, dass bisher nicht verfügbare Szenarien, wie z die Verwendung von WRAP_CONTENT für eine Dimension der RecyclerView, sind jetzt möglich.

Sie müssen anrufen setAutoMeasureEnabled(true)

Fehler im Zusammenhang mit verschiedenen Messspezifikationsmethoden im Update behoben

Überprüfen https://developer.android.com/topic/libraries/support-library/features.html

  • Dies ist die Lösung, die richtig funktioniert, ich habe alle anderen in diesem Thread getestet und alle hatten Probleme

    – wasyl

    17. Februar 2015 um 15:10 Uhr

  • Diese Lösung hat bei mir auch sehr gut funktioniert. Das einzige Problem war, dass umbrochener Text im untergeordneten Element nicht richtig berücksichtigt wird. Siehe meine Antwort oben für die Lösung dieses Problems.

    – Bishbulb

    31. März 2015 um 13:58 Uhr

  • Dies funktioniert nicht für Gridlayout (ja, ich habe die Änderungen übernommen). Zuerst scheint es zu funktionieren, dann ändere ich die Ausrichtung hin und her, und die Höhe wird gegenüber der ursprünglichen Höhe geändert. Auch die Ansichten verhalten sich nicht wie erwartet (z. B. funktionieren Onclicks bei den meisten nicht, während sie mit einem einfachen Gridlayoutmanager funktionieren).

    – Tschabi

    28. Juli 2015 um 14:37 Uhr


  • Wie können wir dasselbe erreichen für gridlayoutmanager und staggeredgridlayoutmanager unter Berücksichtigung der Span-Anzahl?

    – Amrut Bidri

    18. August 2015 um 9:28 Uhr

  • Soll dieser MyLinearLayoutManager auf die untergeordnete Recycler-Ansicht oder auf die übergeordnete Ansicht angewendet werden? oder beides?

    – CommonSenseCode

    6. November 2015 um 14:52 Uhr

1646241196 944 Die Ansichtshohe des verschachtelten Recyclers umschliest seinen Inhalt nicht
Lilienberg

Diese Antwort basiert auf der Lösung von Denis Nek. Es löst das Problem, Dekorationen wie Trennwände nicht zu berücksichtigen.

public class WrappingRecyclerViewLayoutManager extends LinearLayoutManager {

public WrappingRecyclerViewLayoutManager(Context context)    {
    super(context, VERTICAL, false);
}

public WrappingRecyclerViewLayoutManager(Context context, int orientation, boolean reverseLayout)    {
    super(context, orientation, reverseLayout);
}

private int[] mMeasuredDimension = new int[2];

@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++) {
        measureScrapChild(recycler, i,
                View.MeasureSpec.makeMeasureSpec(i, View.MeasureSpec.UNSPECIFIED),
                View.MeasureSpec.makeMeasureSpec(i, View.MeasureSpec.UNSPECIFIED),
                mMeasuredDimension);
        if (getOrientation() == HORIZONTAL) {
            width = width + mMeasuredDimension[0];
            if (i == 0) {
                height = mMeasuredDimension[1];
            }
        } else {
            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 != null) {
        RecyclerView.LayoutParams p = (RecyclerView.LayoutParams) view.getLayoutParams();
        int childWidthSpec = ViewGroup.getChildMeasureSpec(widthSpec, getPaddingLeft() + getPaddingRight(), p.width);
        int childHeightSpec = ViewGroup.getChildMeasureSpec(heightSpec, getPaddingTop() + getPaddingBottom(), p.height);
        view.measure(childWidthSpec, childHeightSpec);
        Rect outRect = new Rect();
        calculateItemDecorationsForChild(view, outRect);
        measuredDimension[0] = view.getMeasuredWidth() + p.leftMargin + p.rightMargin;
        measuredDimension[1] = view.getMeasuredHeight() + p.bottomMargin + p.topMargin + outRect.bottom + outRect.top;
        recycler.recycleView(view);
    }
}

}

  • Schließlich das einzige, was richtig funktioniert. Gute Arbeit. Danke!

    – falc0nit3

    24. Oktober 2015 um 1:13 Uhr

  • Ich erhalte java.lang.IndexOutOfBoundsException: Ungültige Elementposition 0(0). Artikelanzahl: 0 Ausnahme.

    – RAHULRSANSIDHI

    9. März 2016 um 6:11 Uhr

914330cookie-checkDie Ansichtshöhe des verschachtelten Recyclers umschließt seinen Inhalt nicht

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy