RecyclerView實現標題-網格,標題-網格佈局
阿新 • • 發佈:2019-01-04
公司讓實現標題--網格,標題--網格的佈局,想來想去就用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];
}
}
只能向前。。。後來在網上也是各種扒資料,最終實現了效果,雖然效果實現了,但是裡面還有些地方是自己不太明白的,特意記錄一下下。。。。。
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];
}
}