web-dev-qa-db-ja.com

Android:CardView内にRecyclerViewを挿入するにはどうすればよいですか?

私が話しているアクティビティは、RecyclerViewCardViewsがアイテムとして入力されていることを示す必要があります。私の目標は、すべてのCardViewにRecyclerViewを順番に表示することです。

ここに私の活動の基本的な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>

したがって、私は2つのRecyclerView.Adaptersを実装することによって、最初の試みを大胆に行いました。

以下に2つのコードを示します。

"メイン" 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);
        }
    }
}

ご覧のとおり、最初のアダプターで2番目のアダプターをインスタンス化し、すべてのアイテムのRecyclerViewで新しいLayoutManagerをアタッチして2番目のアダプターを設定するのが適切だと思いました。しかし、私の「メイン」Rec.Viewの最初の2つのアイテムを見るとわかるように、別のRec.Viewが含まれていないが、他のアイテムはうまく機能しません。

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

どうすれば問題を解決できますか?どうぞ、私にはアイデアがありません。

15

私はまったく同じ問題に直面しました。 CardView内のRecyclerViewのレイアウトの高さを指定する必要があります。 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>
16
Ashish Kushwaha

サポートライブラリ23.2以降、LayoutManager APIは、RecyclerViewがコンテンツのサイズに基づいてサイズを自動調整できる自動測定機能を提供します。つまり、RecyclerViewのディメンションにWRAP_CONTENTを使用できるようになりました。すべての組み込みLayoutManagerが自動測定をサポートするようになりました。

ソース

7
Neel