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?


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.


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>

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

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.


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


4

Cukup setel parameter tata letak baru

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

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

2

Ini berhasil untuk saya

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

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


Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.