CardView layout_width = "match_parent" ana RecyclerView genişliğiyle eşleşmiyor


123

Layout_width = "match_parent" içeren bir RecyclerView içeren bir parçam var:

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

RecyclerView'daki öğe ayrıca layout_width = "match_parent" ile birlikte bir CardView'dur:

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

Öğe görünümünü aşağıdaki gibi şişiriyorum:

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

Ancak uygulamayı çalıştırdığımda, CardView aşağıda gösterildiği gibi wrap_content olarak görüntüleniyor:

CardsBug

Bunun gerçek bir cihazda değil emülatörde çalıştırıldığını unutmayın.

Yanlış bir şey mi yapıyorum yoksa bu bir hata mı?


CardView'i şişirirken, üst görünüme gerçek bir parametre sağlıyor musunuz?
nhaarman

Merhaba @NiekHaarman, lütfen düzenlemeye bakın. Şişirme kodunu ekledim. Ve evet, doğru parametreyi geçtim.
ProgrAmmar

Yanıtlar:


291

Aşağıdakiler için dokümanlar inflate:

Belirtilen xml kaynağından yeni bir görünüm hiyerarşisini şişirin. Bir hata varsa InflateException atar.

Yüklenecek XML düzen kaynağı için parametreler
kaynak kimliği (ör. R.layout.main_page) kök
görünümü , oluşturulan hiyerarşinin üst öğesi (attachToRoot doğruysa) veya kök için bir dizi LayoutParams değeri sağlayan bir nesne döndürülen hiyerarşinin (attachToRoot yanlışsa)
attachToRoot Şişirilmiş hiyerarşinin kök parametresine eklenmesinin gerekip gerekmediği? False ise, root yalnızca XML'deki kök görünümü için doğru LayoutParams alt sınıfını oluşturmak için kullanılır. Şişirilmiş hiyerarşinin kök Görünümünü döndürür. Root sağlandıysa ve attachToRoot doğruysa, bu köktür; aksi takdirde şişirilmiş XML dosyasının köküdür.

Burada önemli olan değil gerçek kaynağı, ama do ebeveyn kaynağı:

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

Supplying parentGörünüm kullanımına layoutparams Ne inflater bilmesini sağlar. Supplying falseparametreyi o söyler değil henüz ebeveyne ekleyin. Yani ne RecyclerViewsizin için yapacağız.


4
ListView en yüzünden çözüm için beni işe yaramadı layout_widtholdu wrap_content. Garip çünkü bu liste görünümünü etkilememelidir! Anladığım kadarıyla, layoutinflater'a bir parametre olarak false sağladığınızda, ListView liste öğelerini ListView ile eşleşen düzen parametreleriyle ListView'a ekler! : 0
reubenjohn

1
biraz daha kod gönderebilir misin, çünkü bence ben de aynısını yapıyorum, ama aslında işe yaramıyor
rodi

1
Önerinizin ve match_parent benim için nasıl çalışmadığını şişiriyorum.
Zapnologica

3
Bence doğru anlayış, attachToRoot'u false olarak ayarladığınızda, tanımlanmış LayoutParams değerine sahip bir nesne sağlamanız gerektiğidir. Bu nesnenin mutlaka üst öğe olması gerekmez. "... sadece döndürülen hiyerarşinin kökü için bir dizi LayoutParams değeri sağlayan bir nesne (eğer attachToRoot yanlışsa) ..." Ama inflater'ın CardView'da tanımlanan LayoutParams'ı neden okuyamadığını anlamıyorum ama buna ihtiyaç var bilgilendirmek için başka bir nesne parametresi?
hjchin

1
Özel görünümü kullanırsam, bununla nasıl başa çıkılır? Demek istediğimViewHolder onCreateViewHolder(...) { View v = new MyItemView(parent.getContext); return new ViewHolder(v); }
Kross

66

RelativeLayout'u CardView'e yakın üst öğe olarak kullanın.

<RelativeLayout 
    android:layout_width="match_parent" ... >
    <CardView 
        android:layout_width="match_parent" ... >
    </CardView>
</RelativeLayout>

Evet bu benim için de işe yaradı. LinearLayout kullanıyordum ve yukarıdaki öneri zaten tam olarak bunu yaptığım için işe yaramadı (yani köke bağlanmak değil, bir ebeveyn sağlamak). Her iki RelativeLayout + ebeveyni eklememeli, ancak birini sağlamalısınız.
chubbsondubs

1
Benim için çalışıyor, ancak bunun neden sorunu çözebileceğini bilmiyorum. Kimse nedenini açıklayabilir mi?
Johnny

1
çağlar oldu, android x üretimde, yine de hata düzeltilmedi!
Muhammad Naderi

en kolay yol.
Abdurahman Popal

Benzer bir sorun yaşadım ve bu benim kart görünümümün genişliğini düzeltmek için çalıştı, ancak yükseklik ile benzer bir sorun yaşıyorum? Bunun için de bana bir şey önerebilir misin?

12

Bu benim için çalıştı

 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

Benim yaptığım yol:

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

Açıklama: Kart görünümünü aldıktan sonra onCreateViewHolde'da ekran genişliğini alın ve ardından kart görünümü için düzen parametresini uygun şekilde ayarlayın.


1
lütfen bunu biraz geliştirin. Temelde "Bunu dene" yazıyor
Drew

Açıklama eklendi. Lütfen kontrol edin ve daha fazla yardıma ihtiyacınız olursa buraya yorum yapın.
Rahul


4

Yeni düzen parametrelerini ayarlamanız yeterlidir

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

Bunu onBindViewHolder () içinde ConstraintLayout'tan devralan özel bir görünüm sınıfı kullanırken yararlı buldum.
Rasmusob

Bu iyi bir cevap değil çünkü düzene ayarlanan kenar boşluğu etkilenecektir.
EMI Raz

4

Varsayılan uygulama , varsayılan düzen yöneticisinde wrap_content kullanımını zorlar :

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

Yapmanız gereken tek şey, bu yöntemi LayoutManager'ınızda şu şekilde geçersiz kılmaktır:

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

2

Bu benim için çalışıyor

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

1

Card_view: Negatif bir değer içeren contentPadding kullanın

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

Benim için çalıştı


Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.