Подтвердить что ты не робот

Android: как я могу вставить RecyclerView внутри CardView?

Активность, о которой я говорю, должна показывать RecyclerView, заполненную CardViews как элементы. Моя цель состоит в том, чтобы показать в каждом CardView RecyclerView в свою очередь.

Здесь my activity basic xml:

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

И вот макет моего CardView RecyclerView:

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

Итак, я смело сделал свою первую попытку, выполнив два RecyclerView.Adapters, один для (пусть его называют) "main" RecyclerView и один для одиночных в каждом CardView:

Вот две части кода:

"Основной" RecyclerView (w/ViewHolders):

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

}

Элементы RecyclerView (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);
        }
    }
}

Как вы можете видеть, я решил, что правильно создать второй адаптер в первом, и для каждого элемента RecyclerView подключить новый LayoutManager и установить второй адаптер. Но, поскольку вы можете видеть первые два элемента моего "основного" Rec.View, которые не содержат другую работу Rec.View, просто отлично, а другие нет.

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

Как я могу решить проблему? Пожалуйста, у меня нет идей.

4b9b3361

Ответ 1

Я столкнулся с той же проблемой. Вы должны указать высоту макета RecyclerView внутри CardView. Измените его с wrap_content на определенное значение в dp. Вложенное RecyclerView не переносит содержимое по высоте, если родительская прокрутка VERTICAL и аналогичным образом не обертывает содержимое по своей ширине, когда родительская прокрутка HORIZONTAL.

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

Как и в библиотеке поддержки 23.2, API LayoutManager привносит автоматическое измерение, которое позволяет RecyclerView самому размеру основываться на размере его содержимого. Это означает, что использование WRAP_CONTENT для измерения RecyclerView теперь возможно. Вы найдете, что все встроенные LayoutManager теперь поддерживают автоматическое измерение.

Источник