CardView layout_width = “match_parent” tidak cocok dengan lebar RecyclerView induk

123

Saya memiliki fragmen berisi RecyclerView dengan 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" />

Item di RecyclerView adalah CardView juga dengan 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>

Saya memekarkan tampilan item seperti di bawah ini:

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

Tetapi ketika saya menjalankan aplikasi, CardView dirender sebagai wrap_content seperti yang ditunjukkan di bawah ini:

CardsBug

Perhatikan bahwa ini dijalankan di emulator, bukan perangkat sebenarnya.

Apakah saya melakukan sesuatu yang salah, atau apakah itu bug?

ProgrAmmar
sumber
Saat memekarkan CardView, apakah Anda menyediakan tampilan induk dengan parameter true?
nhaarman
Hai @NiekHaarman, silakan lihat hasil editnya. Saya menambahkan kode penggelembungan. Dan ya saya telah melewati parameter yang benar.
ProgrAmmar

Jawaban:

291

Dokumen untuk inflate:

Kembangkan hierarki tampilan baru dari sumber daya xml yang ditentukan. Melempar InflateException jika ada kesalahan.

ID
sumber daya parameter untuk sumber daya tata letak XML yang akan dimuat (misalnya, R.layout.main_page)
tampilan root untuk menjadi induk dari hierarki yang dihasilkan (jika attachToRoot bernilai true), atau sekadar objek yang menyediakan sekumpulan nilai LayoutParams untuk root dari hierarki yang dikembalikan (jika attachToRoot salah.)
attachToRoot Apakah hierarki yang digelembungkan harus dilampirkan ke parameter root? Jika salah, root hanya digunakan untuk membuat subkelas LayoutParams yang benar untuk tampilan root di XML. Mengembalikan Tampilan root dari hierarki yang digelembungkan. Jika root diberikan dan attachToRoot benar, ini adalah root; jika tidak itu adalah root dari file XML yang digelembungkan.

Hal ini penting di sini untuk tidak memasok benar, tapi jangan memasok orang tua:

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

Menyediakan parentView memungkinkan inflater mengetahui layoutparams apa yang akan digunakan. Memasok falseparameter memberi tahu untuk tidak melampirkannya ke induk dulu. Itulah yang RecyclerViewakan dilakukan untuk Anda.

nhaarman
sumber
4
Solusi tidak berhasil untuk saya karena ListView- layout_widthnya wrap_content. Aneh karena ini seharusnya tidak memengaruhi tampilan daftar! Jadi pemahaman saya adalah bahwa ketika Anda memberikan false sebagai parameter ke layoutinflater, ListView menambahkan item daftar ke ListView dengan parameter layout yang cocok dengan ListView itu sendiri! : 0
reubenjohn
1
bisakah Anda memposting lebih banyak kode, karena saya pikir saya melakukan hal yang sama, tetapi sebenarnya tidak berhasil
rodi
1
Saya membesar-besarkan bagaimana saran Anda dan match_parent tidak berfungsi untuk saya.
Zapnologica
3
Saya pikir pemahaman yang benar adalah bahwa ketika Anda menyetel attachToRoot ke false, Anda perlu menyediakan objek dengan nilai LayoutParams yang ditentukan. Objek itu belum tentu induknya. "... hanya sebuah objek yang menyediakan sekumpulan nilai LayoutParams untuk root dari hierarki yang dikembalikan (jika attachToRoot salah.) ..." Tapi saya tidak mengerti mengapa inflater tidak bisa membaca LayoutParams yang didefinisikan di CardView tetapi perlu parameter objek lain untuk menginformasikannya?
hjchin
1
Jika saya menggunakan tampilan kustom, bagaimana cara menghadapinya? Maksud sayaViewHolder onCreateViewHolder(...) { View v = new MyItemView(parent.getContext); return new ViewHolder(v); }
Kross
65

Gunakan RelativeLayout sebagai induk langsung dari CardView.

<RelativeLayout 
    android:layout_width="match_parent" ... >
    <CardView 
        android:layout_width="match_parent" ... >
    </CardView>
</RelativeLayout>
Ganesh Kanna
sumber
Ya, ini sepertinya berhasil untuk saya juga. Saya menggunakan LinearLayout dan saran di atas tidak berfungsi karena saya sudah melakukan hal itu (yaitu tidak melampirkan ke root, tetapi menyediakan induk). Anda harus melakukan kedua RelativeLayout + tidak dengan melampirkan induk, tetapi menyediakan satu.
chubbsondubs
1
Ini berhasil untuk saya, tetapi saya tidak tahu mengapa melakukan ini dapat menyelesaikan masalah. Adakah yang bisa menjelaskan mengapa?
Johnny
1
sudah lama sekali, android x sedang dalam produksi, masih saja bugnya belum diperbaiki!
Muhammad Naderi
cara termudah.
Abdurahman Popal
Saya memiliki masalah yang sama dan ini berhasil untuk saya memperbaiki lebar tampilan kartu saya tetapi saya mengalami masalah yang sama dengan ketinggian? Bisakah Anda menyarankan saya sesuatu untuk itu juga?
12

Ini berhasil untuk saya,

 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);
anurag_dake
sumber
6

Cara saya melakukannya adalah:

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

Penjelasan: Dalam onCreateViewHolde Anda setelah Anda mendapatkan tampilan kartu, dapatkan lebar layar dan kemudian setel parameter tata letak yang sesuai untuk tampilan kartu.

Rahul
sumber
1
tolong tingkatkan ini sedikit. Pada dasarnya tertulis "Coba ini"
Drew
Menambahkan Penjelasan. Silakan periksa dan jika butuh bantuan lebih lanjut, beri komentar di sini.
Rahul
5

Ini tampaknya diperbaiki di 'com.android.support:recyclerview-v7:23.2.1'

Lihat: RecyclerView wrap_content untuk diskusi lebih lanjut.

speedynomads
sumber
4

Cukup setel parameter tata letak baru

view.setLayoutParams(new RecyclerView.LayoutParams(
    RecyclerView.LayoutParams.MATCH_PARENT,
    RecyclerView.LayoutParams.WRAP_CONTENT
));
Vlad
sumber
Saya merasa melakukan ini di onBindViewHolder () berguna saat menggunakan kelas tampilan kustom yang diwarisi dari ConstraintLayout.
Rasmusob
Ini bukan jawaban yang bagus karena margin yang disetel ke tata letak akan terpengaruh.
Emi Raz
4

Implementasi default memaksa penggunaan wrap_content di pengelola layout default:

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

Yang harus Anda lakukan adalah mengganti metode ini di LayoutManager Anda seperti ini:

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

Ini berhasil untuk saya

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

Gunakan card_view: contentPadding dengan nilai negatif

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

Itu berhasil untuk saya

Vladimir Salguero
sumber
-1

Bungkus CardViewdalam Layout yang memiliki lebar:match_parent

Samuel Moshie
sumber