12

Aktywność, o której mówię, musi być oznaczona jako RecyclerView wypełniona przez CardViews jako elementy. Moim celem jest pokazanie w każdym CardView RecyclerView z kolei.Android: jak mogę włożyć wtyczkę RecyclerView do CardView?

Oto moje podstawowe xml Activity za:

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout 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" 
    tools:context=".ConjActivity" > 

    <android.support.v7.widget.RecyclerView 
     android:id="@+id/conjCardList" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     android:clickable="false" /> 

</LinearLayout> 

A oto układ RecyclerView mojego CardView za:

<?xml version="1.0" encoding="utf-8"?> 
<android.support.v7.widget.CardView 
    xmlns:card_view="http://schemas.android.com/apk/res-auto" 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/card_analysis" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:layout_marginTop="@dimen/activity_vertical_margin" 
    android:layout_marginBottom="@dimen/activity_vertical_margin" 
    android:layout_marginLeft="@dimen/activity_horizontal_margin" 
    android:layout_marginRight="@dimen/activity_horizontal_margin" 
    android:padding="5dp" 
    card_view:cardCornerRadius="5dp" > 

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

     <android.support.v7.widget.RecyclerView 
      android:id="@+id/item_mode" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:paddingTop="5dp" 
      android:paddingLeft="@dimen/activity_horizontal_margin" > 

     </android.support.v7.widget.RecyclerView> 
    </LinearLayout> 
</android.support.v7.widget.CardView> 

Więc śmiało podjąłem pierwszą próbę, wprowadzając dwa RecyclerView.Adapters , jeden dla ("nazwijmy to") "głównego" RecyclerView i jeden dla pojedynczych w każdym CardView:

Tutaj są t on dwa kawałki kodu:

"Main" RecyclerView (w/ViewHolders): RecyclerView

public class ConjCardAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>{ 

    private static Context context; 
    private LinearLayoutManager llm; 
    private static ConjFormAdapter formAdapt; 
    private ArrayList<String> adapterList; 
    private List<Object> items; 
    private static final int 
      HEADER = 0, 
      CONJTYPE = 1, 
      ITEM = 2; 
    private Paradigma par; 
    private String sel_vb; 

    public ConjCardAdapter(List<Object> items){ 
     this.items = items; 
     context = ConjActivity.context; 
     adapterList = new ArrayList<String>(); 
     formAdapt = new ConjFormAdapter(adapterList); 
    } 

    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType){ 

     switch(viewType){ 
     case HEADER: 
      return new HeaderHolder(LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.card_header, viewGroup, false)); 
     case CONJTYPE: 
      return new ConjTypeHolder(LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.card_conjtext, viewGroup, false)); 
     case ITEM: 
      return new ItemModeHolder(LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.card_item, viewGroup, false)); 
     default: 
      return null; 
     } 
    } 

    public void onBindViewHolder(RecyclerView.ViewHolder vvh, final int pos) { 
     HeaderItem headerItem; 
     String stringItem; 
     ArrayList<String> listItem; 
     HeaderHolder hh; 
     ConjTypeHolder cjh; 
     ItemModeHolder imh; 

     switch(getItemViewType(pos)){ 
     case HEADER: 
      // it doesn't really matter... 
      break; 
     case CONJTYPE: 
      // it doesn't really matter... 
      break; 
     case ITEM: 
      listItem = (ArrayList<String>) items.get(pos); 
      imh = (ItemModeHolder) vvh; 
      llm = new LinearLayoutManager(context); 
      imh.rv_mode.setLayoutManager(llm); 
      adapterList.addAll(listItem); 
      imh.rv_mode.setAdapter(formAdapt); 
      formAdapt.notifyDataSetChanged(); 
      break; 
     }   
    } 

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

    @Override 
    public int getItemViewType(int position) { 

     switch(position){ 
     case 0: 
      return HEADER; 
     case 1: 
      return CONJTYPE; 
     default: 
      return ITEM; 
     } 
    } 


    static class HeaderHolder extends RecyclerView.ViewHolder{ 

     TextView verbo, 
       paradigma, 
       analisi; 
     View divider; 

     public HeaderHolder(View itemView) { 
      super(itemView); 
      verbo = (TextView) itemView.findViewById(R.id.verb); 
      paradigma = (TextView) itemView.findViewById(R.id.paradigm); 
      analisi = (TextView) itemView.findViewById(R.id.analysis); 
      divider = (View) itemView.findViewById(R.id.divider); 
     } 
    } 

    static class ConjTypeHolder extends RecyclerView.ViewHolder{ 

     TextView type; 

     public ConjTypeHolder(View itemView) { 
      super(itemView); 
      type = (TextView) itemView.findViewById(R.id.conj_type); 
     } 
    } 
: 
    static class ItemModeHolder extends RecyclerView.ViewHolder{ 

     RecyclerView rv_mode; 

     public ItemModeHolder(View itemView) { 
      super(itemView); 
      rv_mode = (RecyclerView) itemView.findViewById(R.id.item_mode); 
     } 
    } 

} 

aplikacji (w/ViewHolder):

public class ConjFormAdapter extends RecyclerView.Adapter<ConjFormAdapter.FormHolder>{ 

    private Context context; 
    private ArrayList<String> list; 
    private Paradigma par; 
    private String sel_vb; 
    private ArrayList<Long> ids; 
    private HashMap<String, Long> mIdMap; 
    private StringAnalisi analisi; 
    private final int IND_MODE_TYPE=0, 
      ELSE_MODE_TYPE=1, 
      TENSE_TYPE=2, 
      FORM_TYPE=3; 

    public ConjFormAdapter(ArrayList<String> list){ 
     this.list = list; 
     // Constructor implementation 
    } 

    // other methods 

    @Override 
    public FormHolder onCreateViewHolder(ViewGroup viewGroup, int itemType) { 
     switch(itemType){ 
     case IND_MODE_TYPE: 
      return new FormHolder(LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item_mode_ind, viewGroup, false)); 
     case ELSE_MODE_TYPE: 
      return new FormHolder(LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item_mode_else, viewGroup, false)); 
     case TENSE_TYPE: 
      return new FormHolder(LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item_tense, viewGroup, false)); 
     default: 
      return new FormHolder(LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item_form, viewGroup, false)); 
     } 
    } 

    @Override 
    public void onBindViewHolder(FormHolder fh, int pos) { 

     fh.txt.setText(list.get(pos)); 

     // other implementation 

    } 

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

    @Override 
    public int getItemViewType(int position) { 
     String item = (String) list.get(position); 
     if(item.equals(context.getResources().getString(R.string.ind))){ 
      return IND_MODE_TYPE; 
     } else if(item.equals(context.getResources().getString(R.string.subj))||item.equals(context.getResources().getString(R.string.imp))||item.equals(context.getResources().getString(R.string.inf))||item.equals(context.getResources().getString(R.string.pt))||item.equals(context.getResources().getString(R.string.ger))||item.equals(context.getResources().getString(R.string.gerv))||item.equals(context.getResources().getString(R.string.sup))){ 
      return ELSE_MODE_TYPE; 
     } else if(item.equals(context.getResources().getString(R.string.pres))||item.equals(context.getResources().getString(R.string.impf))||item.equals(context.getResources().getString(R.string.fut))||item.equals(context.getResources().getString(R.string.pf))||item.equals(context.getResources().getString(R.string.ppf))||item.equals(context.getResources().getString(R.string.futant))){ 
      return TENSE_TYPE; 
     } else { 
      return FORM_TYPE; 
     } 
    } 

    @Override 
    public long getItemId(int position) { 

     String item = list.get(position); 
     return mIdMap.get(item); 
    } 

    @Override 
    public void setHasStableIds(boolean hasStableIds) { 
     super.setHasStableIds(true); 
    } 


    static class FormHolder extends RecyclerView.ViewHolder{ 

     TextView txt; 
     View divider1, divider2, divider3; 

     public FormHolder(View itemView) { 
      super(itemView); 
      txt = (TextView) itemView.findViewById(R.id.text1); 
      divider1 = (View) itemView.findViewById(R.id.conj_divider1); 
      divider2 = (View) itemView.findViewById(R.id.conj_divider2); 
      divider3 = (View) itemView.findViewById(R.id.conj_divider3); 
     } 
    } 
} 

Jak widać myślałem, że miał rację, aby utworzyć instancję drugiego adaptera w pierwszym, a dla każdego produktu RecyclerView dołączyć nowy LayoutManager i ustawić drugi adapter. Ale jak widać pierwsze dwa elementy mojego "głównego" Rec.View, które nie zawierają innej pracy Rec.View, są w porządku, ale pozostałe nie.

The items with a RecyclerView don't show up like they should

Jak mogę rozwiązać ten problem? Proszę, nie mam pomysłów.

Odpowiedz

16

Zmierzyłem się z tym samym problemem. Musisz określić wysokość układu RecyclerView wewnątrz CardView. Zmień go z wrap_content na określoną wartość w dp. Zagnieżdżone narzędzie RecyclerView nie opakowuje zawartości w jej wysokość, jeśli nadrzędne przewijanie jest PIONOWE i podobnie nie zawija treści na jej szerokość, gdy nadrzędne przewijanie ma wartość POZIOME.

<?xml version="1.0" encoding="utf-8"?> 
<android.support.v7.widget.CardView 
xmlns:card_view="http://schemas.android.com/apk/res-auto" 
xmlns:android="http://schemas.android.com/apk/res/android" 
android:id="@+id/card_analysis" 
android:layout_width="match_parent" 
android:layout_height="wrap_content" 
android:layout_marginTop="@dimen/activity_vertical_margin" 
android:layout_marginBottom="@dimen/activity_vertical_margin" 
android:layout_marginLeft="@dimen/activity_horizontal_margin" 
android:layout_marginRight="@dimen/activity_horizontal_margin" 
android:padding="5dp" 
card_view:cardCornerRadius="5dp" > 

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

    <android.support.v7.widget.RecyclerView 
     android:id="@+id/item_mode" 
     android:layout_width="wrap_content" 
     android:layout_height="100dp" 
     android:paddingTop="5dp" 
     android:paddingLeft="@dimen/activity_horizontal_margin" > 

    </android.support.v7.widget.RecyclerView> 
</LinearLayout> 
</android.support.v7.widget.CardView> 
+2

Ale co, jeśli mój widok recyklera ma zmienną zawartość? Czy istnieje sposób na dokonanie wyboru wysokości automatycznej w zależności od liczby przedmiotów? –

+0

Rozwiązaniem może być użycie różnych układów dla CardView zawierających widoki RecylerView o różnych wysokościach i użycie ich odpowiednio (lub instrukcji warunkowych) do ich implementacji. –

+1

Dzięki twoim podpowiedziom w końcu rozwiązałem problem i, jeśli jesteś zainteresowany, rozwiązanie mojego drugiego pytania przyniosło @DenisNek na http://stackoverflow.com/questions/26649406/nested-recycler-view-height -doesnt-wrap-its-content/27616854 # 27616854 –

5

Jako biblioteki wsparcia 23,2 API LayoutManager przynosi automatycznego pomiaru, która pozwala na RecyclerView do samego rozmiaru na podstawie wielkości jego zawartości. Oznacza to, że używanie WRAP_CONTENT dla wymiaru RecyclerView jest teraz możliwe. Znajdziesz wszystkie wbudowane w LayoutManagers teraz obsługują auto-pomiar.

Source

Powiązane problemy