创建自定义RecyclerView项目分隔符时的空类

时间:2018-10-13 12:41:30

标签: java android android-recyclerview android-adapter

创建RecyclerView之后。我的应用程序启动正常,但是我在适配器中使用的用于创建项目分隔符(RVLineSeparator)的类为空。我是否应该放弃该类并将代码更改为其他内容?

片段

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

    public FragmentRV() {}

    @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));
        mRecyclerView.addItemDecoration(new DividerItemDecoration(Objects.requireNonNull(getContext()), LinearLayout.VERTICAL));

        super.onActivityCreated(savedInstanceState);

        initRVAdapter();
    }

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

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

        itemsList.add(new SMSmessage("Item A","Item A description"));
        itemsList.add(new Phonecall("Item B","Item B description"));
        itemsList.add(new RVLineSeparator());
        itemsList.add(new SectionHeader("Section C"));
        itemsList.add(new SMSmessage("Item C1","Item C1 description"));
        itemsList.add(new SMSmessage("Item C2","Item C2 description"));
        itemsList.add(new SMSmessage("Item C3","Item C3 description"));
        itemsList.add(new RVLineSeparator());
        itemsList.add(new SectionHeader("Section D"));
        itemsList.add(new SMSmessage("Item D1","Item D1 description"));
        itemsList.add(new SMSmessage("Item D2","Item D2 description"));
        itemsList.add(new RVLineSeparator());
        itemsList.add(new SectionHeader("Section E"));
        itemsList.add(new SMSmessage("Item E1","Item E1 description"));
        itemsList.add(new SMSmessage("Item E2","Item E2 description"));
        itemsList.add(new SMSmessage("Item E3","Item E3 description")); 
        itemsList.add(new RVLineSeparator());
        itemsList.add(new SMSmessage("Item F1","Item F1 description"));             
        itemsList.add(new RVLineSeparator());
        itemsList.add(new Phonecall("Item G1","Item G1 description"));

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

RVLineSeparator类

public class RVLineSeparator {
}

适配器类

public class RVItemsAapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
    private final static int TYPE_EXPANDABLE = 1, TYPE_NONEXPANDABLE = 2, TYPE_SECTION = 3, TYPE_TABLE = 4, TYPE_SEPARATOR = 5;
    private ArrayList callSMSFeed = new ArrayList();
    private Context context;

    // Constructor
    public RVItemsAapter(Context context){
        this.context=context;
    }

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

    @Override
    public int getItemViewType(int position) {
        if (callSMSFeed.get(position) instanceof Phonecall) {
            return TYPE_EXPANDABLE;
        } else if (callSMSFeed.get(position) instanceof SMSmessage) {
            return TYPE_NONEXPANDABLE;
        } else if (callSMSFeed.get(position) instanceof SectionHeader) {
            return TYPE_SECTION;
        } else if (callSMSFeed.get(position) instanceof TableToilets) {
            return TYPE_TABLE;
        } else if (callSMSFeed.get(position) instanceof RVLineSeparator) {
            return TYPE_SEPARATOR;
        }
        throw new IllegalArgumentException("Item at position " + position + " is not an instance of either Phonecall or SMSmessage");
    }

    @Override
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
        int viewType=holder.getItemViewType();
        switch (viewType){
            case TYPE_EXPANDABLE:
                Phonecall call = (Phonecall) callSMSFeed.get(position);
                ((CallViewHolder)holder).showCallDetails(call);
                break;
            case TYPE_NONEXPANDABLE:
                SMSmessage sms = (SMSmessage) callSMSFeed.get(position);
                ((SMSViewHolder)holder).showSmsDetails(sms);
                break;
            case TYPE_SECTION:
                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();}

    @NonNull
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {

        int layout;
        RecyclerView.ViewHolder viewHolder;
        switch (viewType){
            case TYPE_EXPANDABLE:
                layout = R.layout.cardview_dualline_withexpandability;
                View callsView = LayoutInflater
                        .from(parent.getContext())
                        .inflate(layout, parent, false);
                viewHolder = new CallViewHolder(callsView);
                break;
            case TYPE_NONEXPANDABLE:
                layout = R.layout.cardview_dualline_sansexpandability;
                View smsView = LayoutInflater
                        .from(parent.getContext())
                        .inflate(layout, parent, false);
                viewHolder = new SMSViewHolder(smsView);
                break;
            case TYPE_SECTION:
                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;
    }

    // First ViewHolder of object type Call
    public class CallViewHolder extends RecyclerView.ViewHolder {
        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);
        }
    }

    // Second ViewHolder of object type SMS
    public class SMSViewHolder extends RecyclerView.ViewHolder {
        SMSViewHolder(View itemView) {
            super(itemView);
        }

        void showSmsDetails(SMSmessage sms){
        }
    }

    // Third ViewHolder of object type SectionHeader
    public class SectionViewHolder extends RecyclerView.ViewHolder {
        SectionViewHolder(View itemView) {
            super(itemView);
        }

        void showSectionDetails(SectionHeader section){
        }
    }

    // Fourth ViewHolder of object type TableToilets
    public class TblViewHolder extends RecyclerView.ViewHolder {

        TblViewHolder(View itemView) {
            super(itemView);
        }

        void showTblDetails(TableToilets tbl){
        }
    }

    // Fifth ViewHolder of object type RVLineSeparator
    public class SeparatorViewHolder extends RecyclerView.ViewHolder {
        private View lSeparator;

        SeparatorViewHolder(View itemView) {
            super(itemView);


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

1 个答案:

答案 0 :(得分:1)

由于您的getItemViewType基于对象实例选择ViewHolder类型引用,因此可以使用一个空类。您可以通过多种方式实现这一目标。就个人而言,我通常使用属性而不是5个不同的Object类,看起来更简单,并且您将只处理一种对象。

您会遇到这样的事情:

public class MyAdapterObject{

    ......
    int type;

    public int getType(){ return type}
}

@Override
public int getItemViewType(int position) {
    switch(callSMSFeed.get(position).getType()){
         case someType:
              return SOME_TYPE;
         case someOtherType:
              return SOME_OTHER_TYPE;
         default:
              return DEFAULT_TYPE
    }
}

如您在此处看到的那样,您始终保留默认类型,以免最终导致异常,如果未处理,则会导致崩溃。