L'attività di cui sto parlando deve mostrare un RecyclerView compilato da CardViews come articoli. Il mio obiettivo è mostrare in ogni CardView un RecyclerView a sua volta.Android: come posso inserire un RecyclerView all'interno di CardView?
Qui il mio xml base di attività:
<?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>
E qui è il layout del RecyclerView di mio CardView:
<?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>
Così, ho coraggiosamente fatto il mio primo tentativo mediante l'attuazione di due RecyclerView.Adapters , uno per (chiamiamolo) "principale" RecyclerView e uno per i singoli in ogni CardView:
Qui ci sono ha due pezzi di codice:
"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);
}
}
}
Articoli (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);
}
}
}
Come potete vedere ho pensato che Era giusto istanziare il secondo adattatore nel primo, e per RecyclerView di ogni articolo attaccare un nuovo LayoutManager e impostare il secondo adattatore. Ma come puoi vedere i primi due elementi del mio "principale" Rec.View che non contengono un altro Rec.View funzionano bene, ma gli altri no.
Come posso risolvere il problema? Per favore, sono fuori di idee.
Ma cosa succede se la mia vista riciclatore ha contenuto variabile? C'è un modo per rendere automatica la scelta dell'altezza in base al numero di articoli? –
Una soluzione può essere quella di utilizzare diversi layout per il CardView contenente RecylerViews di diverse altezze e utilizzare switch case (o istruzioni condizionali) per implementarli rispettivamente. –
Grazie ai tuoi suggerimenti ho finalmente risolto il problema e, se sei interessato, la soluzione alla mia seconda domanda è stata portata da @DenisNek a http://stackoverflow.com/questions/26649406/nested-recycler-view-height -doesnt-wrap-its-content/27616854 # 27616854 –