帶屏煙機(jī)項(xiàng)目中有個這樣的需求,右側(cè)菜譜步驟是頂部是食材的一些信息,底部是做法的步驟,可以劃分為兩個區(qū)域
但是兩個區(qū)域是可以連續(xù)滾動的.
怎么布局呢,
一個linerlayout,下面一個gridview,外部再套一個scrollview,這樣明顯是不可行的,因?yàn)閟crollview 和gridview 嵌套會有沖突,如果偏要這樣做,也可以,就必須解決兩者的沖突.明顯是不可行的.所以可以使用一個recylerview來實(shí)現(xiàn)
一個recylerview 怎么做呢?listView 可以使用addHeaderView ,但是recylerview 不行哦,得擴(kuò)展recylerview 的功能才行
所以我們使用一個開源庫 :MultiType 傳送門,很強(qiáng)大的一個庫,不過我們只用到了最簡單的用法
mAdapter = new MultiTypeAdapter();
//header
mAdapter.register(SmartCookMaterialInfo.class, new SmartCookStepHeadAdapter());
//下面的列表
mAdapter.register(NetStepInfo.StepsBean.class, new SmartCookStepAdapter());
mRvCook.setAdapter(mAdapter);
Items allItem = new Items();
//組裝header 的數(shù)據(jù)
List<SmartCookMaterialInfo> stepInfoList = new ArrayList<>();
stepInfoList.add(materialInfo);
//添加header
allItem.addAll(stepInfoList);
//添加下面的列表
allItem.addAll(netStepInfo);
mAdapter.setItems(allItem);
mAdapter.notifyDataSetChanged();
使用方法很簡單
1.new 一個 MultiTypeAdapter
2.注冊兩種不同的類型(之前必須寫好兩個不同類型的adapter)
3.設(shè)置recylerview的adapter
4.分別添加頂部步驟的信息和底部的步驟信息
5.設(shè)置數(shù)據(jù)源
6.notify
就這樣就實(shí)現(xiàn)效果了嗎?
NO NO NO 你會發(fā)現(xiàn)頂部的材料信息模塊,變成了GridView 的一個Item ,顯示在了第一個位置
就時候,我們就使用到另一種方法了,recylerview的混排
使用方法如下:
GridLayoutManager gridLayoutManager = new GridLayoutManager(getActivity(), 2);
gridLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
@Override
public int getSpanSize(int position) {
return position == 0 ? 2 : 1; //第一個位置,占用2個寬度
}
});
首先定義整個recylerview的布局為網(wǎng)格布局和每行的網(wǎng)格數(shù)量2,然后setSpanSizeLookup ,設(shè)置第一個Item 占用2個位置即可
就這樣就實(shí)現(xiàn)了嗎?我們仔細(xì)看下面的item 之前的間距怎么控制呢?在xml 控制?可以,但是我們也可以在代碼里面來控制
public class RecyclerViewSpacesItemDecoration extends RecyclerView.ItemDecoration {
private HashMap<String, Integer> mSpaceValueMap;
public static final String TOP_DECORATION = "top_decoration";
public static final String BOTTOM_DECORATION = "bottom_decoration";
public static final String LEFT_DECORATION = "left_decoration";
public static final String RIGHT_DECORATION = "right_decoration";
public RecyclerViewSpacesItemDecoration(HashMap<String, Integer> mSpaceValueMap) {
this.mSpaceValueMap = mSpaceValueMap;
}
@Override
public void getItemOffsets(Rect outRect, View view,
RecyclerView parent, RecyclerView.State state) {
if (mSpaceValueMap.get(TOP_DECORATION) != null)
outRect.top = mSpaceValueMap.get(TOP_DECORATION);
if (mSpaceValueMap.get(LEFT_DECORATION) != null)
outRect.left = mSpaceValueMap.get(LEFT_DECORATION);
if (mSpaceValueMap.get(RIGHT_DECORATION) != null)
outRect.right = mSpaceValueMap.get(RIGHT_DECORATION);
if (mSpaceValueMap.get(BOTTOM_DECORATION) != null)
outRect.bottom = mSpaceValueMap.get(BOTTOM_DECORATION);
}}
HashMap<String, Integer> stringIntegerHashMap = new HashMap<>();
stringIntegerHashMap.put(RecyclerViewSpacesItemDecoration.TOP_DECORATION, Utils.dip2px(getActivity(), 20));//top間距
stringIntegerHashMap.put(RecyclerViewSpacesItemDecoration.BOTTOM_DECORATION, Utils.dip2px(getActivity(), 20));//底部間距
stringIntegerHashMap.put(RecyclerViewSpacesItemDecoration.LEFT_DECORATION, Utils.dip2px(getActivity(), 20));//左間距
stringIntegerHashMap.put(RecyclerViewSpacesItemDecoration.RIGHT_DECORATION, Utils.dip2px(getActivity(), 20));//右間距
mRvCook.addItemDecoration(new RecyclerViewSpacesItemDecoration(stringIntegerHashMap));
直接調(diào)用recylerview的addItemDecoration方法即可添加邊距信息,這里我們編寫一個類 RecyclerViewSpacesItemDecoration 繼承 recylerview的 RecyclerView.ItemDecoration ,重寫 getItemOffsets 方法,在里面配置相關(guān)的上下左右邊距信息即可
就這樣就可以實(shí)現(xiàn)一個recylerview 實(shí)現(xiàn)以上的功能啦.