導言:
RecyclerView使用也有一段時間了 他的出現是對ListView,GridView的進化。但是我們要實現一些複雜的佈局,比如這個佈局,那我們該怎麼辦呢?別急,不是說了RecyclerView是對ListView,GridView的進化嗎?那麼ListView和GridView能實現的效果,RecyclerView肯定能實現,甚至ListView嵌套GridView這個2B的方式也是能實現的,甚至還有ListView和GridView的複用功能。(如果你急於找答案,那就先提示,請使用GridLayoutManager的setSpanSizeLookup的方法,設置單個Item的跨度,如果你有時間,就往下看,謝謝支持)
分析:
當我們美工給我們類似導言裏面的效果圖時,我們不要一臉懵逼,應該對美工妹紙說:你的這效果圖真和你一樣漂亮,今晚下班能一起研究研究嗎?美工妹紙肯定說:哎呀,臭屌絲!滾。 好吧,程序猿果真是苦逼的命啊,那我們只能低頭下來研究技術吧。於是程序猿開始研究了效果圖,這看上去有ListView的效果,又有GridView的效果,能不嵌套起來將就一下呢?但是程序猿又想到嵌套了複用的機制又沒有了,如果Item是圖片,多起來OOM豈不是很沒面子。程序猿又想到了RecyclerView最近不是很火嗎?不是說RecyclerView是對ListView,GridView的進化嗎? 但是RecyclerView的LayoutManager只有GridLayoutManager(一行多個ITEM) 和LinearLayoutManager(一行一個Item)呀?會不會有第三種佈局管理呢?程序猿好像抓住了生命的稻草似的打開了API文檔。找呀找,竟然沒有,哎......一臉失望的開着API,突然眼前好像看到了GridLayoutManager的的構造器有個 int類型的spanCount,還有個setSpanSizeLookup的方法。看了文檔描述,臥槽,上天被程序猿的真誠感動了啊。
文檔說明:
public GridLayoutManager(android.content.Context context, int spanCount)
Creates a vertical GridLayoutManager
param
context Current context, will be used to access resources.
param
spanCount The number of columns in the grid// <span style="color: rgb(51, 51, 51); font-family: arial; font-size: 18px; line-height: 20px;">網格中的列數</span>
spanCount 就是一行有多少列,比如導言中的圖片一行中最多的有2列,那麼我們應該傳入參數2:,
前方高能,請打開AndroidStudio:
setSpanSizeLookup(android.support.v7.widget.GridLayoutManager$SpanSizeLookup spanSizeLookup)
Sets the source to get the number of spans occupied by each item in the adapter.
param
spanSizeLookup {@link SpanSizeLookup} instance to be used to query number of spans occupied by each item<span style="font-weight: bold;">
</span>
這方法就是設置單個Item的跨度(跨度?就是相當於一個LinearLayout裏面設置了weightSum爲5,一個子控件的layout_weight=4
,那麼這個這個item的跨度就是這個LinearLayout的 4/5),同理導言中的圖片中我們拿出item0 和item1 ,item2出來分析。
item2的寬度大概是item1的一半,item1大概是item0 的2/3, 那麼我們大概知道了,item0的跨度爲3,item1的跨度爲2,item2的跨度爲1。是多少
GridLayoutManager manager = new GridLayoutManager(this, 3);
manager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
@Override
public int getSpanSize(int position) {
return (3 - position % 3);
}
});
recyclerView.setLayoutManager(manager);
return
(3-position%3); 我們來看這個,當position爲0的時候,返回的跨度爲3,就是說item佔3個跨度。OK,一切都很明朗了。拓展:
//// 加載Item View的時候根據不同TYPE加載不同的佈局
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
if (viewType == 0) {
return new ItemTypeViewHolder(mLayoutInflater.inflate(
R.layout.item_recommend_title, parent, false));
} else if (viewType == 1 || viewType == 4) {
return new ItemListViewHolder(mLayoutInflater.inflate(
R.layout.item_book_info, parent, false));
} else {
return new ItemGridViewHolder(mLayoutInflater.inflate(
R.layout.item_recommend_hor, parent, false));
}
}
// 初始化不同的佈局。
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder,
final int position) {
if (holder instanceof ItemTypeViewHolder) {
ItemTypeViewHolder tempholder = (ItemTypeViewHolder) holder;
tempholder.mBookNameTv.setText(mBeans.get(position)
.getRecommendtypename());
return;
} else if (holder instanceof ItemListViewHolder) {
ItemListViewHolder tempholder = (ItemListViewHolder) holder;
if (mOnItemClickLitener != null) {
tempholder.itemView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
mOnItemClickLitener.onItemClick(v, position);
}
});
}
tempholder.mBookAuthorTv.setText(mBeans.get(position)
.getBookauthor());
tempholder.mBookNameTv.setText(mBeans.get(position).getBookname());
tempholder.mBookSummry.setText(mBeans.get(position).getSummary());
Picasso.with(mContext).load(mBeans.get(position).getBookCoverURL())
.placeholder(R.drawable.bookcover)
.error(R.drawable.bookcover).into(tempholder.mBookCoverImg);
return;
} else if (holder instanceof ItemGridViewHolder) {
ItemGridViewHolder tempholder = (ItemGridViewHolder) holder;
if (mOnItemClickLitener != null) {
tempholder.itemView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
mOnItemClickLitener.onItemClick(v, position);
}
});
}
tempholder.mBookAuthorTv.setText(mBeans.get(position)
.getBookauthor());
tempholder.mBookNameTv.setText(mBeans.get(position).getBookname());
Picasso.with(mContext).load(mBeans.get(position).getBookCoverURL())
.placeholder(R.drawable.bookcover)
.error(R.drawable.bookcover).into(tempholder.mBookCoverImg);
return;
}
}
// 設置ITEM類型,可以自由發揮,返回Item的樣式。
@Override
public int getItemViewType(int position) {
//返回當前的數據類型,可以在bean模型類中設置一個字段。
//
// return (3 - position % 3);
return mBeans.get(position).getRecommendtype();
}
最後在Fragment或者 Activity中:
mAdapter = new RecommendAdapter(getActivity());
mAdapter.setOnItemClickLitener(this);
mListView = (RecyclerView) mRootView.findViewById(R.id.list);
GridLayoutManager layoutManager = new GridLayoutManager(
getActivity(), 6);
layoutManager.setSpanSizeLookup(new SpanSizeLookup() {
@Override
public int getSpanSize(int position) {
switch (mAdapter.getItemViewType(position)) {
case 0:
return 6; // 寬度爲6, item滿屏
case 1:
return 6;// 寬度爲6, item滿屏
case 2:
return 3;// 寬度爲3,item爲屏幕的寬的一半,這一行可以顯示2個item
case 3:
return 2;// 寬度爲3,item爲屏幕的寬的1/3,這一行可以顯示3個item
case 4:
return 6;// 寬度爲6, item滿屏
default:
return -1;
}
}
});
mListView.setLayoutManager(layoutManager);
mListView.setAdapter(mAdapter);
大功告成。謝謝閱讀.
------Android開發基友羣:64026923,衆多妹紙、基友等着你喲。加的是羣,漲的是技術: