1. 程式人生 > >RecyclerView實現標題-網格,標題-網格佈局

RecyclerView實現標題-網格,標題-網格佈局

公司讓實現標題--網格,標題--網格的佈局,想來想去就用Recyclerview來實現了,說實話,中間休息了一段時間,recyclerview我用的並不多,為了工作,
只能向前。。。後來在網上也是各種扒資料,最終實現了效果,雖然效果實現了,但是裡面還有些地方是自己不太明白的,特意記錄一下下。。。。。
1.首先建立recyclerview的佈局
 layoutManager1 = new GridLayoutManager(getActivity(),4, GridLayoutManager.VERTICAL,false);
            //找到RecyclerView,並設定佈局管理器
             adapter = new EntityAdapter(getActivity());
            layoutManager1.setSpanSizeLookup(new SectionedSpanSizeLookup(adapter,layoutManager1));
            home_type_recv.setLayoutManager(layoutManager1);
            //將RecyclerView元件繫結adapter
            home_type_recv.setAdapter(adapter);
  adapter.setData(傳入封裝好的資料);
2.SectionedSpanSizeLookup:
public class SectionedSpanSizeLookup extends GridLayoutManager.SpanSizeLookup {    protected SectionedRecyclerViewAdapter<?, ?, ?> adapter = null;
    protected GridLayoutManager layoutManager = null;    public SectionedSpanSizeLookup(SectionedRecyclerViewAdapter<?, ?, ?> adapter, GridLayoutManager layoutManager) {
        this.adapter = adapter;
        this.layoutManager = layoutManager;
    }    @Override
    public int getSpanSize(int position) {        if(adapter.isSectionHeaderPosition(position) || adapter.isSectionFooterPosition(position)){
            return layoutManager.getSpanCount();
        }else{
            return 1;
        }    }
}
3.HotelEntityAdapter:
public class EntityAdapter extends SectionedRecyclerViewAdapter<HeaderHolder, DescHolder, RecyclerView.ViewHolder> {    public ArrayList<HotelEntity.TagsEntity> allTagList = new ArrayList<>();
    private Context mContext;
    private LayoutInflater mInflater;
    private SparseBooleanArray mBooleanMap;
    public EntityAdapter(Context context) {
        mContext = context;
        mInflater = LayoutInflater.from(context);
        mBooleanMap = new SparseBooleanArray();
    }    public void setData(ArrayList<HotelEntity.TagsEntity> allTagList) {
        this.allTagList = allTagList;
        Log.i("info","HotelEntityAdapter"+allTagList.size());
        notifyDataSetChanged();
    }    @Override
    protected int getSectionCount() {
        return HotelUtils.isEmpty(allTagList) ? 0 : allTagList.size();
    }    @Override
    protected int getItemCountForSection(int section) {
        int count = allTagList.get(section).tagInfoList.size();
       /* if (count >= 8 && !mBooleanMap.get(section)) {
            count = 8;
        }*/        return HotelUtils.isEmpty(allTagList.get(section).tagInfoList) ? 0 : count;
    }    //是否有footer佈局
    @Override
    protected boolean hasFooterInSection(int section) {
        return false;
    }    @Override
    protected HeaderHolder onCreateSectionHeaderViewHolder(ViewGroup parent, int viewType) {
        return new HeaderHolder(mInflater.inflate(R.layout.home_header_type, parent, false));
    }
    @Override
    protected RecyclerView.ViewHolder onCreateSectionFooterViewHolder(ViewGroup parent, int viewType) {
        return null;
    }    @Override
    protected DescHolder onCreateItemViewHolder(ViewGroup parent, int viewType) {
        return new DescHolder(mInflater.inflate(R.layout.recomendcardview, parent, false));
    }
    @Override
    protected void onBindSectionHeaderViewHolder(final HeaderHolder holder, final int section) {        holder.titleView.setText(allTagList.get(section).tagsName);
    }
    @Override
    protected void onBindSectionFooterViewHolder(RecyclerView.ViewHolder holder, int section) {    }
    public static interface  OnItemClickListener{
        void onItemClick(View view,int selection, int positon);
    }
    private EntityAdapter.OnItemClickListener mOnItemClickListener;    public void setOnItemClickListener(HotelEntityAdapter.OnItemClickListener listener) {
        this.mOnItemClickListener = listener;
    }
    @Override
    protected void onBindItemViewHolder(final DescHolder holder, final int section, final int position) {
        holder.home_Tag_Cbx.setText(allTagList.get(section).tagInfoList.get(position).getName());
        holder.home_Tag_Cbx.setTag(position);
        //根據isSelected欄位控制checkbox的selected狀態
        holder.home_Tag_Cbx.setChecked(allTagList.get(section).tagInfoList.get(position).isSelected());
        //根據狀態設定背景
        if(holder.home_Tag_Cbx.isChecked()){
            holder.home_Tag_Cbx.setTextColor(mContext.getResources().getColor(R.color.color_946e3d));
            holder.home_Tag_Cbx.setBackgroundResource(R.drawable.home_type_selected_tag);        }else{
            holder.home_Tag_Cbx.setTextColor(mContext.getResources().getColor(R.color.color_b7b4ad));
            //((VideoViewHolder)holder).videovname.setTextColor(context.getResources().getColor(R.color.color_b7b4ad));
            holder.home_Tag_Cbx.setBackgroundResource(R.drawable.home_type_tag);
        }
        //        holder.home_Tag_Cbx.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.i("info","position列印"+position+"select:"+allTagList.get(section).tagInfoList.get(position).isSelected());
                allTagList.get(section).tagInfoList.get(position).setSelected(!allTagList.get(section).tagInfoList.get(position).isSelected());
                Log.i("info","position列印"+position+"sectionFlag:"+section);
                notifyDataSetChanged();
                mOnItemClickListener.onItemClick(holder.home_Tag_Cbx,section,(Integer)(holder).home_Tag_Cbx.getTag());
               //用EventBus來監聽狀態
                EventBus.getDefault().post(new ActionEvent(ActionType.CHANGE_TAG, 0));            }
        });
    }
    //全選
    public void all() {
        for(int i=0;i<allTagList.size();i++){
            for(int j=0;j<allTagList.get(i).tagInfoList.size();j++){
                allTagList.get(i).tagInfoList.get(j).setSelected(true);
            }
        }
        notifyDataSetChanged();
    }}
4.SectionedRecyclerViewAdapter
public abstract class SectionedRecyclerViewAdapter<H extends RecyclerView.ViewHolder,
        VH extends RecyclerView.ViewHolder,
        F extends RecyclerView.ViewHolder>
        extends RecyclerView.Adapter<RecyclerView.ViewHolder> {    protected static final int TYPE_SECTION_HEADER = -1;
    protected static final int TYPE_SECTION_FOOTER = -2;
    protected static final int TYPE_ITEM = -3;    private int[] sectionForPosition = null;
    private int[] positionWithinSection = null;
    private boolean[] isHeader = null;
    private boolean[] isFooter = null;
    private int count = 0;    public SectionedRecyclerViewAdapter() {
        super();
        registerAdapterDataObserver(new SectionDataObserver());
    }    @Override
    public void onAttachedToRecyclerView(RecyclerView recyclerView) {
        super.onAttachedToRecyclerView(recyclerView);
        setupIndices();
    }
   
    /**
     * Returns the sum of number of items for each section plus headers and footers if they
     * are provided.
     */
    @Override
    public int getItemCount() {
        return count;
    }    private void setupIndices(){
        count = countItems();
        allocateAuxiliaryArrays(count);
        precomputeIndices();
    }    private int countItems() {
        int count = 0;
        int sections = getSectionCount();        for(int i = 0; i < sections; i++){
            count += 1 + getItemCountForSection(i) + (hasFooterInSection(i) ? 1 : 0);
        }
        return count;
    }    private void precomputeIndices(){
        int sections = getSectionCount();
        int index = 0;        for(int i = 0; i < sections; i++){
            setPrecomputedItem(index, true, false, i, 0);
            index++;            for(int j = 0; j < getItemCountForSection(i); j++){
                setPrecomputedItem(index, false, false, i, j);
                index++;
            }            if(hasFooterInSection(i)){
                setPrecomputedItem(index, false, true, i, 0);
                index++;
            }
        }
    }    private void allocateAuxiliaryArrays(int count) {
        sectionForPosition = new int[count];
        positionWithinSection = new int[count];
        isHeader = new boolean[count];
        isFooter = new boolean[count];
    }    private void setPrecomputedItem(int index, boolean isHeader, boolean isFooter, int section, int position) {
        this.isHeader[index] = isHeader;
        this.isFooter[index] = isFooter;
        sectionForPosition[index] = section;
        positionWithinSection[index] = position;
    }    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        RecyclerView.ViewHolder viewHolder;        if(isSectionHeaderViewType(viewType)){
            viewHolder = onCreateSectionHeaderViewHolder(parent, viewType);
        }else if(isSectionFooterViewType(viewType)){
            viewHolder = onCreateSectionFooterViewHolder(parent, viewType);
        }else{
            viewHolder = onCreateItemViewHolder(parent, viewType);
        }        return viewHolder;
    }    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        int section = sectionForPosition[position];
        int index = positionWithinSection[position];        if(isSectionHeaderPosition(position)){
            onBindSectionHeaderViewHolder((H) holder, section);
        }else if(isSectionFooterPosition(position)){
            onBindSectionFooterViewHolder((F) holder, section);
        }else{
            onBindItemViewHolder((VH) holder, section, index);
        }    }    @Override
    public int getItemViewType(int position) {        if(sectionForPosition == null){
            setupIndices();
        }        int section = sectionForPosition[position];
        int index = positionWithinSection[position];        if(isSectionHeaderPosition(position)){
            return getSectionHeaderViewType(section);
        }else if(isSectionFooterPosition(position)){
            return getSectionFooterViewType(section);
        }else{
            return getSectionItemViewType(section, index);
        }    }    protected int getSectionHeaderViewType(int section){
        return TYPE_SECTION_HEADER;
    }    protected int getSectionFooterViewType(int section){
        return TYPE_SECTION_FOOTER;
    }    protected int getSectionItemViewType(int section, int position){
        return TYPE_ITEM;
    }    /**
     * Returns true if the argument position corresponds to a header
     */
    public boolean isSectionHeaderPosition(int position){
        if(isHeader == null){
            setupIndices();
        }
        return isHeader[position];
    }    /**
     * Returns true if the argument position corresponds to a footer
     */
    public boolean isSectionFooterPosition(int position){
        if(isFooter == null){
            setupIndices();
        }
        return isFooter[position];
    }    protected boolean isSectionHeaderViewType(int viewType){
        return viewType == TYPE_SECTION_HEADER;
    }    protected boolean isSectionFooterViewType(int viewType){
        return viewType == TYPE_SECTION_FOOTER;
    }    /**
     * Returns the number of sections in the RecyclerView
     */
    protected abstract int getSectionCount();    /**
     * Returns the number of items for a given section
     */
    protected abstract int getItemCountForSection(int section);    /**
     * Returns true if a given section should have a footer
     */
    protected abstract boolean hasFooterInSection(int section);    /**
     * Creates a ViewHolder of class H for a Header
     */
    protected abstract H  onCreateSectionHeaderViewHolder(ViewGroup parent, int viewType);    /**
     * Creates a ViewHolder of class F for a Footer
     */
    protected abstract F  onCreateSectionFooterViewHolder(ViewGroup parent, int viewType);    /**
     * Creates a ViewHolder of class VH for an Item
     */
    protected abstract VH onCreateItemViewHolder(ViewGroup parent, int viewType);    /**
     * Binds data to the header view of a given section
     */
    protected abstract void onBindSectionHeaderViewHolder(H holder, int section);    /**
     * Binds data to the footer view of a given section
     */
    protected abstract void onBindSectionFooterViewHolder(F holder, int section);    /**
     * Binds data to the item view for a given position within a section
     */
    protected abstract void onBindItemViewHolder(VH holder, int section, int position);    class SectionDataObserver extends RecyclerView.AdapterDataObserver{
        @Override
        public void onChanged() {
            setupIndices();
        }
    }    public int getItemPosition(int position) {
        return positionWithinSection[position];
    }
}