Saya memiliki DialogFragment
yang berisi RecyclerView
(daftar kartu).
Di dalamnya RecyclerView
ada satu atau lebih CardViews
yang dapat memiliki ketinggian.
Saya ingin memberikan DialogFragment
ketinggian yang benar berdasarkan pada CardViews
yang terkandung di dalamnya.
Biasanya ini akan menjadi sederhana, saya akan mengatur wrap_content
pada RecyclerView
seperti ini.
<android.support.v7.widget.RecyclerView ...
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clickable="true"
android:scrollbars="vertical" >
</android.support.v7.widget.RecyclerView>
Karena saya menggunakan RecyclerView
ini tidak berfungsi lihat:
https://issuetracker.google.com/issues/37001674
dan
Tinggi tampilan Recycler bersarang tidak membungkus kontennya
Di kedua halaman ini orang menyarankan untuk memperpanjang LinearLayoutManager
dan menimpanyaonMeasure()
Saya pertama kali menggunakan LayoutManager yang disediakan seseorang di tautan pertama:
public static class WrappingLayoutManager extends LinearLayoutManager {
public WrappingLayoutManager(Context context) {
super(context);
}
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);
measureScrapChild(recycler, 0,
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
mMeasuredDimension);
int width = mMeasuredDimension[0];
int height = mMeasuredDimension[1];
switch (widthMode) {
case View.MeasureSpec.EXACTLY:
case View.MeasureSpec.AT_MOST:
width = widthSize;
break;
case View.MeasureSpec.UNSPECIFIED:
}
switch (heightMode) {
case View.MeasureSpec.EXACTLY:
case View.MeasureSpec.AT_MOST:
height = heightSize;
break;
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();
measuredDimension[1] = view.getMeasuredHeight();
recycler.recycleView(view);
}
}
}
Namun ini tidak berhasil karena
heightSize = View.MeasureSpec.getSize(heightSpec);
mengembalikan nilai yang sangat besar yang tampaknya terkait dengan match_parent
.
Dengan berkomentar height = heightSize;
(dalam saklar kedua) saya berhasil membuat ketinggian bekerja tetapi hanya jika seorang TextView
anak di dalam CardView
tidak membungkus teksnya sendiri (kalimat yang panjang).
Begitu itu TextView
membungkus teks itu sendiri ketinggiannya HARUS meningkat tetapi tidak. Ini menghitung tinggi untuk kalimat panjang itu sebagai satu baris, bukan garis terbungkus (2 atau lebih).
Adakah saran tentang bagaimana saya harus meningkatkan ini LayoutManager
sehingga RecyclerView
pekerjaan saya WRAP_CONTENT
?
Sunting: Manajer tata letak ini mungkin berfungsi untuk kebanyakan orang, tetapi masih memiliki masalah dengan menggulir dan menghitung ketinggian tampilan teks pembungkus
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);
}
}
}
sumber
Jan 22, 2016: This has been merged into the internal tree, should be available with the next version of support library.
Jawaban:
Dari pembaruan Perpustakaan Dukungan Android 23.2.1 , semua WRAP_CONTENT harus bekerja dengan benar.
Harap perbarui versi perpustakaan dalam
gradle
file ATAU untuk lebih lanjut:memecahkan beberapa masalah seperti Bug yang diperbaiki terkait dengan berbagai metode pengukuran-spesifikasi
Periksa http://developer.android.com/tools/support-library/features.html#v7-recyclerview
Anda dapat memeriksa riwayat revisi Perpustakaan Dukungan
sumber
23.2.0
mulai crash aplikasi saya. Jadi, saya mengikuti jawaban Anda dan sayaRecyclerView
tidak membungkus. Mengapa?mRecyclerView.setNestedScrollingEnabled(false);
sebaliknya tampilan pendaur ulang masih akan menangani pengguliran itu sendiri untuk meneruskan acara kepada orang tua.UPDATE 02.07.2020
Metode ini dapat mencegah daur ulang dan tidak boleh digunakan pada set data yang besar .
PEMBARUAN 05.07.2019
Jika Anda menggunakan
RecyclerView
di dalamScrollView
, ubah sajaScrollView
keandroidx.core.widget.NestedScrollView
. Di dalam tampilan ini tidak perlu berkemasRecyclerView
di dalam aRelativeLayout
.Akhirnya ditemukan solusi untuk masalah ini.
Yang perlu Anda lakukan adalah membungkus
RecyclerView
aRelativeLayout
. Mungkin ada Tampilan lain yang juga berfungsi.sumber
Ini adalah versi kelas yang disempurnakan yang tampaknya berfungsi dan tidak memiliki masalah yang dimiliki solusi lain:
Ini juga tersedia sebagai perpustakaan . Tautan ke kelas yang relevan .
sumber
onBindViewHolder()
dipanggil. Itu buruk karena pada saat itu saya memanggil, misalnyaholder.textView.setText(longText)
, sehingga anak menjadi lebih tinggi, tetapi tidak tercermin ke dalam tinggi pendaur ulang. Jika Anda punya ide (seperti perubahan cepat ke adaptor), saya akan berterima kasih.RecyclerView
dalam vertikalRecyclerView
.MEMPERBARUI
Dengan pembaruan 23.2 Dukungan Perpustakaan Android, semua WRAP_CONTENT harus bekerja dengan benar.
Harap perbarui versi perpustakaan dalam file gradle.
Jawaban Asli
Seperti dijawab pada pertanyaan lain, Anda harus menggunakan metode onMeasure () asli ketika tinggi tampilan pendaur ulang Anda lebih besar dari tinggi layar. Manajer tata letak ini dapat menghitung ItemDecoration dan dapat menggulir dengan lebih banyak.
jawaban asli: https://stackoverflow.com/a/28510031/1577792
sumber
gridlayoutmanager
danstaggeredgridlayoutmanager
mempertimbangkan rentang waktu dalam pikiranIni adalah versi c # untuk mono android
sumber
var p = (RecyclerView.LayoutParams) child.LayoutParameters
denganvar p = child.LayoutParameters.JavaCast<RecyclerView.LayoutParams>()
RecyclerView
menambahkan dukungan untukwrap_content
di23.2.0
yang buggy, 23.2.1 hanya stabil, sehingga Anda dapat menggunakan:Anda dapat melihat riwayat revisi di sini:
https://developer.android.com/topic/libraries/support-library/revisions.html
catatan:
Juga perhatikan bahwa setelah memperbarui pustaka dukungan,
RecyclerView
akan menghormatiwrap_content
jugamatch_parent
demikian jika Anda memiliki Tampilan Item dari suatuRecyclerView
set karenamatch_parent
tampilan tunggal akan mengisi seluruh layarsumber
Komentar ini membantu saya.
Put the recyclerview in any other layout (Relative layout is preferable). Then change recyclerview's height/width as match parent to that layout and set the parent layout's height/width as wrap content.
sumber
Masalah dengan pengguliran dan pembungkus teks adalah bahwa kode ini mengasumsikan bahwa lebar dan tinggi diatur ke
wrap_content
. Namun,LayoutManager
perlu diketahui bahwa lebar horizontal dibatasi. Jadi, alih-alih membuat sendiriwidthSpec
untuk setiap tampilan anak, cukup gunakan yang asliwidthSpec
:sumber
Coba ini (Ini adalah solusi yang tidak menyenangkan tetapi mungkin berhasil): Dalam
onCreate
metode AndaActivity
atau dalamonViewCreated
metode fragmen Anda. Setel panggilan balik yang siap dipicu saatRecyclerView
pertama kali ditampilkan, seperti ini:Dalam
calculeRecyclerViewFullHeight
menghitungRecyclerView
tinggi penuh berdasarkan ketinggian anak-anaknya.Dalam kasus saya konten saya
RecyclerView
adalah dalamSwipeRefreshLayout
untuk alasan itu saya mengatur ketinggian keSwipeRefreshView
dan bukan keRecyclerView
tetapi jika Anda tidak memilikinyaSwipeRefreshView
maka Anda dapat mengatur ketinggian keRecyclerView
gantinya.Beritahu saya jika ini membantu Anda atau tidak.
sumber
RecyclerView
instance Anda .Ini sekarang berfungsi karena mereka telah merilis versi 23.2, sebagaimana dinyatakan dalam posting ini . Mengutip posting blog resmi
sumber
Sederhananya RecyclerView Anda di dalam NestedScrollView. Bekerja dengan sempurna
sumber
Saya telah menggunakan beberapa solusi di atas tetapi itu berhasil
width
tetapiheight
.compileSdkVersion
lebih dari 23 , Anda dapat langsung menggunakan RecyclerView yang disediakan di masing-masing pustaka pandangan recycler, seperti 23 di antaranya'com.android.support:recyclerview-v7:23.2.1'
. Ini dukungan perpustakaan dukungan atribut dariwrap_content
kedua lebar dan tinggi.Anda harus menambahkannya ke dependensi Anda
compileSdkVersion
kurang dari 23 , Anda dapat menggunakan solusi yang disebutkan di bawah ini.Saya menemukan utas Google ini tentang masalah ini. Di utas ini, ada satu kontribusi yang mengarah pada implementasi LinearLayoutManager .
Saya telah mengujinya baik untuk tinggi dan lebar dan itu bekerja dengan baik untuk saya dalam kedua kasus.
sumber
Alih-alih menggunakan perpustakaan apa pun, solusi termudah hingga versi baru keluar adalah dengan membuka b.android.com/74772 . Anda akan dengan mudah menemukan solusi terbaik yang dikenal hingga saat ini di sana.
PS: b.android.com/74772#c50 bekerja untuk saya
sumber
saya sarankan Anda untuk meletakkan recyclerview di tata letak lain (tata letak relatif lebih disukai). Kemudian ubah tinggi / lebar recyclerview sebagai induk pertandingan ke tata letak itu dan atur tinggi / lebar tata letak induk sebagai konten pembungkus. ini bekerja untuk saya
sumber
Ganti
measureScrapChild
untuk mengikuti kode:Saya menggunakan xamarin, jadi ini kode c #. Saya pikir ini dapat dengan mudah "diterjemahkan" ke Jawa.
sumber
Perbarui tampilan Anda dengan nilai nol alih-alih dari viewgroup induk dalam metode onCreateViewHolder, pemegang viewholder.
sumber
Anda harus meletakkan FrameLayout sebagai tampilan Utama lalu memasukkan RelativeLayout dengan ScrollView dan setidaknya RecyclerView Anda, itu berfungsi untuk saya.
Trik sebenarnya di sini adalah RelativeLayout ...
Saya senang bisa membantu.
sumber
Saya belum mengerjakan jawaban saya tetapi cara saya tahu itu StaggridLayoutManager tanpa. kotak 1 dapat menyelesaikan masalah Anda karena StaggridLayout akan secara otomatis menyesuaikan tinggi dan lebarnya pada ukuran konten. jika berhasil jangan lupa untuk memeriksanya sebagai jawaban yang tepat.
sumber