CardView没有以编程方式添加到LinearLayout

时间:2018-10-21 16:24:07

标签: java android xml android-recyclerview android-linearlayout

每次我将CardView添加到我的RecyclerView适配器时,它一直将其添加到RecyclerView根目录中,而不是我在其中创建的LinearLayout中。我希望将CardViews添加到LinearLayout(ll_section_cards)内,以便可以根据需要显示或隐藏卡片。我已经设法用XML来实现这一点,但是如何以编程方式来完成呢?我从未在任何地方看到1个有关如何执行此操作的教程。

当前结果

Chris Banes.

预期结果

enter image description here

片段类

public class TabFragmentRV extends android.support.v4.app.Fragment {
    RecyclerView mRecyclerView;

    public TabFragmentRV() {}

    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_rv, container, false);
    }

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        View v = getView();
        assert v != null;

        mRecyclerView = v.findViewById(R.id.my_recyclerview);
        mRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity(), LinearLayoutManager.VERTICAL, false));


        List<SMSmessage> items = new ArrayList();
        SMSmessage item = new SMSmessage(dataTitle, dataSubtitle);
        items.add(new SMSmessage("message_a1", "message_a1_description"));
        items.add(new SMSmessage("message_a2", "message_a2_description"));
        items.add(new SMSmessage("message_a3", "message_a3_description"));
        items.add(new SMSmessage("message_a4", "message_a4_description"));

        // dataTitle = new ArrayList<>();
        // dataTitle.add(getString(R.string.message_a1));
        // dataTitle.add(getString(R.string.message_a2));
        // dataTitle.add(getString(R.string.message_a3));
        // dataTitle.add(getString(R.string.message_a4));

        // dataSubtitle = new ArrayList<>();
        // dataSubtitle.add(getString(R.string.message_a1_description));
        // dataSubtitle.add(getString(R.string.message_a2_description));
        // dataSubtitle.add(getString(R.string.message_a3_description));
        // dataSubtitle.add(getString(R.string.message_a4_description));

        super.onActivityCreated(savedInstanceState);

        initRVAdapter();
    }

    ArrayList<String> dataTitle;
    ArrayList<String> dataSubtitle;

    private void initRVAdapter(){
        List<Object> itemsList = new ArrayList<>();

        RVItemsAapter itemsListAdapter = new RVItemsAapter(getContext());
        mRecyclerView.setAdapter(itemsListAdapter);

        itemsList.add(new SectionHeader("Messages (Today)"));
        itemsList.add(new SMSmessage("Message A1","Message E1 description"));
        itemsList.add(new SMSmessage("Message A2","Message E2 description"));
        itemsList.add(new SMSmessage("Message A3","Message E3 description"));
        itemsList.add(new SMSmessage("Message A4","Message E4 description"));
        itemsList.add(new RVLineSeparator());

        itemsListAdapter.setCallSMSFeed(itemsList);
        itemsListAdapter.notifyDataSetChanged();
    }
}

适配器类

public class RVItemsAapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
    private final static int TYPE_MAINHEADER = 1, TYPE_EXPANDABLE = 2, TYPE_SMS = 3, TYPE_SECTIONHEADER = 4, TYPE_TABLE = 5, TYPE_SEPARATOR = 6;
    private ArrayList callSMSFeed = new ArrayList();

    private Context context;


    // public RVItemsAapter(Context context){this.context = context;}
    public RVItemsAapter(Context context, List<SMSmessage> items) { this.context = context; this.items = items;}

    public void setCallSMSFeed(List<Object> callSMSFeed){
        this.callSMSFeed = (ArrayList) callSMSFeed;
    }

    @Override
    public int getItemViewType(int position) {
        if (callSMSFeed.get(position) instanceof MainHeader) {
            return TYPE_MAINHEADER;
        } else if (callSMSFeed.get(position) instanceof Phonecall) {
            return TYPE_CALL;
        } else if (callSMSFeed.get(position) instanceof SMSmessage) {
            return TYPE_SMS;
        } else if (callSMSFeed.get(position) instanceof SectionHeader) {
            return TYPE_SECTIONHEADER;
        } else if (callSMSFeed.get(position) instanceof RVLineSeparator) {
            return TYPE_SEPARATOR;
        }
        throw new IllegalArgumentException("Item at position " + position + " is not an instance of either X, Y or Z");
    }

    @Override
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
        int viewType=holder.getItemViewType();
        switch (viewType){
            case TYPE_MAINHEADER:
                MainHeader mainHeader = (MainHeader) callSMSFeed.get(position);
                ((MHeaderViewHolder)holder).showMHeaderDetails(mainHeader);
                break;
            case TYPE_CALL:
                Phonecall call = (Phonecall) callSMSFeed.get(position);
                ((CallViewHolder)holder).showCallDetails(call);
                break;
            case TYPE_SMS:
                SMSmessage sms = (SMSmessage) callSMSFeed.get(position);
                ((SMSViewHolder)holder).showSmsDetails(sms);
                break;
            case TYPE_SECTIONHEADER:
                SectionHeader sectionHeader = (SectionHeader) callSMSFeed.get(position);
                ((SectionViewHolder)holder).showSectionDetails(sectionHeader);
                break;
            case TYPE_TABLE:
                TableToilets tblToilets = (TableToilets) callSMSFeed.get(position);
                ((TblViewHolder)holder).showTblDetails(tblToilets);
                break;
            case TYPE_SEPARATOR:
                ((SeparatorViewHolder)holder).showSeparatorDetails();
                break;
            default:
                throw new IllegalArgumentException("unexpected viewType: " + viewType);
        }
    }

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

    // Invoked by layout manager to create new views
    @NonNull
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {


        int layout;
        RecyclerView.ViewHolder viewHolder;
        switch (viewType){
            case TYPE_MAINHEADER:
                layout = R.layout.rv_header;
                View mainheaderView = LayoutInflater
                        .from(parent.getContext())
                        .inflate(layout, parent, false);
                viewHolder = new MHeaderViewHolder(mainheaderView);
                break;
            case TYPE_CALL:
                layout = R.layout.cardview_dualline_withexpandability;
                View callsView = LayoutInflater
                        .from(parent.getContext())
                        .inflate(layout, parent, false);
                viewHolder = new CallViewHolder(callsView);
                break;
            case TYPE_SMS:
                layout = R.layout.cardview_dualline_sansexpandability;
                View smsView = LayoutInflater
                        .from(parent.getContext())
                        .inflate(layout, parent, false);
                viewHolder = new SMSViewHolder(smsView);
                break;
            case TYPE_SECTIONHEADER:
                layout = R.layout.sectionheaderforrecyclerview;
                View sectionheaderView = LayoutInflater
                        .from(parent.getContext())
                        .inflate(layout, parent, false);
                viewHolder = new SectionViewHolder(sectionheaderView);
                break;
            case TYPE_TABLE:
                layout = R.layout.cardview_tableview_withexpandability;
                View tblView = LayoutInflater
                        .from(parent.getContext())
                        .inflate(layout, parent, false);
                viewHolder = new TblViewHolder(tblView);
                break;
            case TYPE_SEPARATOR:
                layout = R.layout.lineseparatorforrecyclerview;
                View separatorView = LayoutInflater
                        .from(parent.getContext())
                        .inflate(layout, parent, false);
                viewHolder = new SeparatorViewHolder(separatorView);
                break;
            default:
                throw new IllegalArgumentException("unexpected viewType: " + viewType);
        }
        return viewHolder;
    }


    public class MHeaderViewHolder extends RecyclerView.ViewHolder {
        private Button btnExpandAll, btnCollapseAll;

        MHeaderViewHolder(View itemView) {
            super(itemView);
            // Initiate view
            btnExpandAll = itemView.findViewById(R.id.btn_expandall);
            btnCollapseAll = itemView.findViewById(R.id.btn_collapseall);

            btnExpandAll.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Toast.makeText(context,"expand clicked",Toast.LENGTH_SHORT).show();
                }
            });

            btnCollapseAll.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Toast.makeText(context,"collapse clicked",Toast.LENGTH_SHORT).show();
                }
            });
        }

        void showMHeaderDetails(MainHeader call){
            // Attach values for each item
            String btnAName = call.getButtonAName();
            String btnBName = call.getButtonBName();

            btnExpandAll.setText(btnAName);
            btnCollapseAll.setText(btnBName);
        }
    }

    public class CallViewHolder extends RecyclerView.ViewHolder {
        final Typeface iconFont = FontManager.getTypeface(context, FontManager.FONTAWESOME);

        private TextView arrowexpandcollapseTextView, callerNameTextView, callTimeTextView;
        private LinearLayout llFacilityInformation;

        CallViewHolder(View itemView) {
            super(itemView);
            // Initiate view
            arrowexpandcollapseTextView = itemView.findViewById(R.id.tv_cvwithexpandability_arrowexpandcollapse);
            callerNameTextView = itemView.findViewById(R.id.tv_cvwithexpandability_title);
            callTimeTextView = itemView.findViewById(R.id.tv_cvwithexpandability_subtitle);
            llFacilityInformation = itemView.findViewById(R.id.ll_cvwithexpandability_subtitle);

            arrowexpandcollapseTextView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (llFacilityInformation.getVisibility() == View.GONE) {
                        expandLL(llFacilityInformation, arrowexpandcollapseTextView);
                    } else {
                        collapseLL(llFacilityInformation, arrowexpandcollapseTextView);
                    }
                }
            });

            callerNameTextView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (llFacilityInformation.getVisibility() == View.GONE) {
                        expandLL(llFacilityInformation, arrowexpandcollapseTextView);
                    } else {
                        collapseLL(llFacilityInformation, arrowexpandcollapseTextView);
                    }
                }
            });

            llFacilityInformation.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (llFacilityInformation.getVisibility() == View.GONE) {
                        expandLL(llFacilityInformation, arrowexpandcollapseTextView);
                    } else {
                        collapseLL(llFacilityInformation, arrowexpandcollapseTextView);
                    }
                }
            });
        }

        void showCallDetails(Phonecall call){
            // Attach values for each item
            arrowexpandcollapseTextView.setText(R.string.fa_icon_chevron_down);
            arrowexpandcollapseTextView.setTypeface(iconFont);
            llFacilityInformation.setVisibility(View.GONE);

            String callerName = call.getCallerName();
            String callTime = call.getCallTime();

            callerNameTextView.setText(callerName);
            callTimeTextView.setText(callTime);
        }
    }


    public class SMSViewHolder extends RecyclerView.ViewHolder {

        private CardView myCardView;
        private TextView senderNameTextView, smsContentTextView;

        SMSViewHolder(View itemView) {
            super(itemView);
            // Initiate view
            myCardView = itemView.findViewById(R.id.cv_sansexpandability);

            senderNameTextView = itemView.findViewById(R.id.tv_cvsansexpandability_title);
            smsContentTextView = itemView.findViewById(R.id.tv_cvsansexpandability_subtitle);
        }

        void showSmsDetails(SMSmessage sms){
            // Attach values for each item
            String senderName = sms.getSenderName();
            String smsContent = sms.getSmsContent();

            senderNameTextView.setText(senderName);
            smsContentTextView.setText(smsContent);
        }
    }


    public class SectionViewHolder extends RecyclerView.ViewHolder {
        final Typeface iconFont = FontManager.getTypeface(context, FontManager.FONTAWESOME);
        private LinearLayout llSectionInformation;
        private TextView arrowexpandcollapseTextView, sectionNameTextView;

        SectionViewHolder(View itemView) {
            super(itemView);
            // Initiate view
            arrowexpandcollapseTextView = itemView.findViewById(R.id.tv_sectionheader_expandcollapsearrow);
            sectionNameTextView = itemView.findViewById(R.id.tv_sectionheader_title);
            llSectionInformation = itemView.findViewById(R.id.ll_sectionwithexpandability_cards);

            llSectionInformation.setVisibility(View.GONE);


            // Initiate view
            for (int childPosition = 0; childPosition < items.size(); childPosition++) {
                LayoutInflater infalInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                View childView = infalInflater.inflate(R.layout.cv_sansexpandability, null);

                SMSmessage item = items.get(childPosition);
                TextView title = childView.findViewById(R.id.tv_cvsansexpandability_title);
                TextView subtitle = childView.findViewById(R.id.tv_cvsansexpandability_subtitle);
                title.setText(item.getSenderName());
                subtitle.setText(item.getSmsContent());

                llSectionInformation.addView(childView);
            }

        }

        void showSectionDetails(SectionHeader section){
            // Attach values for each item
            arrowexpandcollapseTextView.setText(R.string.fa_icon_chevron_down);
            arrowexpandcollapseTextView.setTypeface(iconFont);

            String sectionName = section.getSectionName();
            sectionNameTextView.setText(sectionName);
        }
    }

    public class SeparatorViewHolder extends RecyclerView.ViewHolder {
        private View lSeparator;

        SeparatorViewHolder(View itemView) {
            super(itemView);
            // Initiate view
            lSeparator = itemView.findViewById(R.id.rv_lineseparator);
        }

        void showSeparatorDetails(){
            TypedValue tValueD = new TypedValue();
            context.getTheme().resolveAttribute(R.attr.dividerColor, tValueD, true);
            lSeparator.setBackgroundResource(tValueD.resourceId);
        }
    }

    // methods
    private void expandLL(final LinearLayout llFacilityInformation, final TextView arrowexpandcollapseTextView) {
        llFacilityInformation.setVisibility(View.VISIBLE);
        arrowexpandcollapseTextView.setText(R.string.fa_icon_chevron_up);
    }

    private void collapseLL(final LinearLayout llFacilityInformation, final TextView arrowexpandcollapseTextView) {
        llFacilityInformation.setVisibility(View.GONE);
        arrowexpandcollapseTextView.setText(R.string.fa_icon_chevron_down);
    }

    private void expandRL(final RelativeLayout rlFacilityInformation, final TextView arrowexpandcollapseTextView) {
        rlFacilityInformation.setVisibility(View.VISIBLE);
        arrowexpandcollapseTextView.setText(R.string.fa_icon_chevron_up);
    }

    private void collapseRL(final RelativeLayout rlFacilityInformation, final TextView arrowexpandcollapseTextView) {
        rlFacilityInformation.setVisibility(View.GONE);
        arrowexpandcollapseTextView.setText(R.string.fa_icon_chevron_down);
    }
}

SMSmessage类

public class SMSmessage {
    public String senderName, smsContent;

    public SMSmessage(String senderName, String smsContent) {
        this.senderName = senderName;
        this.smsContent = smsContent;
    }

    public String getSenderName() {
        return senderName;
    }

    public String getSmsContent() {
        return smsContent;
    }
}

布局(需要编程版本)

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/ll_sectionwithexpandability_main"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">
    <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/ll_section_header"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:weightSum="100">

        <TextView
            android:id="@+id/tv_sectionheader_expandcollapsearrow"
            android:clickable="true"
            android:focusable="true"
            android:layout_weight="10"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginEnd="10dp" />

        <TextView
            android:id="@+id/tv_sectionheader_title"
            android:layout_weight="90"
            android:layout_width="0dp"
            android:layout_height="wrap_content" />
    </LinearLayout>

    <LinearLayout
        android:id="@+id/ll_section_cards"
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <android.support.v7.widget.CardView
            xmlns:android="http://schemas.android.com/apk/res/android"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:id="@+id/cv_content">

            <LinearLayout
                android:id="@+id/ll_cv"
                android:orientation="vertical"
                android:layout_width="match_parent"
                android:layout_height="wrap_content">

                <TextView
                    android:id="@+id/tv_cv_title"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="@string/app_name" />

                <TextView
                    android:id="@+id/tv_cv_subtitle"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="@string/app_name" />
            </LinearLayout>
        </android.support.v7.widget.CardView>
    </LinearLayout>
</LinearLayout>

SMSMessage类

public class SMSmessage {
    private String senderName, smsContent;

    public SMSmessage(String senderName, String smsContent) {
        this.senderName = senderName;
        this.smsContent = smsContent;
    }

    public String getSenderName() {
        return senderName;
    }

    public String getSmsContent() {
        return smsContent;
    }
}

enter image description here

1 个答案:

答案 0 :(得分:1)

要将cardView添加到LinearLayout,您需要将CardView保留在单独的布局中:

<android.support.v7.widget.CardView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/cv_content">

        <LinearLayout
            android:id="@+id/ll_cv"
            android:orientation="vertical"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

                <TextView
                     android:id="@+id/tv_cv_title"
                     android:layout_width="wrap_content"
                     android:layout_height="wrap_content"
                     android:text="@string/app_name" />

                 <TextView
                      android:id="@+id/tv_cv_subtitle"
                      android:layout_width="wrap_content"
                      android:layout_height="wrap_content"
                      android:text="@string/app_name" />
        </LinearLayout>

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

然后您需要增加布局:

ll_section_cards.removeAllViews();
for (int childPosition = 0; childPosition < items.size(); childPosition++) {
      LayoutInflater infalInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
      View childView = infalInflater.inflate(R.layout.card_item, null);

      Item item = items.get(childPosition);
      TextView title = childView.findViewById(R.id.tv_cv_title);
      title.setText(item.getTitle());

      ll_section_cards.addView(childView);
}

您可能有一个Item类来设置TextViews的文本:

class Item {

   public Item(String title, String subTitle) {
     this.title = title;
     this. subTitle = subTitle;
   }

   public String title;
   public String subTitle;
}

这是项目列表:

List<Item> items = new ArrayList();
Item item = new Item(title, subTitle);
items.add(item);