當(dāng)前位置:首頁 > 嵌入式培訓(xùn) > 嵌入式學(xué)習(xí) > 講師博文 > RecyclerView學(xué)習(xí)筆記(二)——實(shí)現(xiàn)GridView
RecycleView和ListView一樣,都是做列表顯示View子項(xiàng)的控件,它比ListView更高效和自由。
解析RecycleView,Recycle View意思就是該控件只管回收和顯示View子項(xiàng),而對(duì)于如何顯示,顯示什么,它是不關(guān)心的,這給開發(fā)過程帶來了極大的便利,比如ListView只能作為單列的列表顯示,GridView將一個(gè)界面表格化,通常情況下GridView通過強(qiáng)制View子項(xiàng)的寬度來顯示,在橫豎屏切換時(shí)的效果很差。
而RecycleView可以實(shí)現(xiàn):
ListView的功能
GridView的功能
橫向ListView的功能
橫向ScrollView的功能
瀑布流的功能
添加和刪除View子項(xiàng)
這些功能,非常強(qiáng)大,可以看出,它幾乎可以替代所有的動(dòng)態(tài)布局控件。
這么強(qiáng)大的動(dòng)態(tài)布局控件,得益于它的高度解耦,同樣,眾所周知,高度解耦,就意味著復(fù)雜度提升,相較于ListView、GridView等控件,RecycleView才實(shí)現(xiàn)過程是相對(duì)較復(fù)雜的。
RecyclerView的適配器需要繼承自RecyclerView.Adapter,在該適配器將要面向ViewHolder,也就是說,它內(nèi)部已經(jīng)實(shí)現(xiàn)了緩存復(fù)用。
實(shí)現(xiàn)GridView功能
已經(jīng)實(shí)現(xiàn)了ListView,對(duì)于一個(gè)高度解耦的RecyclerView來說,再實(shí)現(xiàn)GridView的功能就非常簡(jiǎn)單了。
新建RecyclerViewDemo2工程。Adapter可以直接拷貝RecyclerViewDemo1中的內(nèi)容。暫時(shí)不考慮分隔線的情況下,只需要將實(shí)現(xiàn)ListView時(shí)使用的LinnerLayoutManager換成GridLayoutManager即可,只需要改動(dòng)兩行代碼。
Java Code
GridLayoutManager gridLayoutManager = new GridLayoutManager(this, 4);
recyclerView.setLayoutManager(gridLayoutManager);
非常的方便,那么,在一個(gè)界面中通過判斷屏幕方向,使用不同的顯示方式,也就順理成章了。
其他的東西都是不變的,除了布局管理器的改變之外,另一個(gè)需要注意的就是分隔線,需要重新繪制。
Java Code
package com.hqyj.dev.recyclerviewdemo2;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.StaggeredGridLayoutManager;
import android.util.Log;
import android.view.View;
/**
* Created by jiyangkang on 2016/7/16 0016.
*/
public class GridItemDecoration extends
RecyclerView.ItemDecoration {
private Drawable mDivider;
private static final int[] ATTRS = new int[]{
android.R.attr.listDivider
};
public GridItemDecoration(Context context) {
final TypedArray t = context.obtainStyledAttributes(ATTRS);
mDivider = t.getDrawable(0);
t.recycle();
}
@Override
public void onDraw(Canvas c,
RecyclerView parent,
RecyclerView.State state) {
super.onDraw(c, parent, state);
drawHorizontal(c, parent);
drawVertical(c, parent);
}
//獲取列數(shù)
private int getSpanCount(RecyclerView parent) {
int spandCount = -1;
RecyclerView.LayoutManager layoutManager = parent.getLayoutManager();
if (layoutManager instanceof GridLayoutManager) {
spandCount = ((GridLayoutManager) layoutManager).getSpanCount();
} else if (layoutManager instanceof StaggeredGridLayoutManager) {
spandCount = (
(StaggeredGridLayoutManager) layoutManager).getSpanCount();
}
return spandCount;
}
private void drawVertical(Canvas c, RecyclerView parent) {
final int childCount = parent.getChildCount();
for (int i = 0; i < childCount; i++) {
Log.d("Draw_v", "drawVertical: " + i);
final View child = parent.getChildAt(i);
final RecyclerView.LayoutParams params = (
RecyclerView.LayoutParams) child.getLayoutParams();
final int top = child.getTop() - params.topMargin;
final int bottom = child.getBottom() + params.bottomMargin;
final int left = child.getRight();
final int right = left + mDivider.getIntrinsicWidth();
mDivider.setBounds(left, top, right, bottom);
mDivider.draw(c);
}
}
private void drawHorizontal(Canvas c, RecyclerView parent) {
int childCount = parent.getChildCount();
for (int i = 0; i < childCount; i++) {
Log.d("Draw_h", "drawVertical: " + i);
final View child = parent.getChildAt(i);
final RecyclerView.LayoutParams params = (
RecyclerView.LayoutParams) child.getLayoutParams();
final int left = child.getLeft() - params.leftMargin;
final int right = child.getRight() + params.rightMargin
+ mDivider.getIntrinsicWidth();
final int top = child.getBottom() + params.bottomMargin;
final int bottom = top + mDivider.getIntrinsicHeight();
mDivider.setBounds(left, top, right, bottom);
mDivider.draw(c);
}
}
@Override
public void getItemOffsets(Rect outRect,
View view,
RecyclerView parent,
RecyclerView.State state) {
super.getItemOffsets(outRect, view, parent, state);
outRect.set(0,0,mDivider.getIntrinsicWidth(), mDivider.getIntrinsicHeight());
}
}
對(duì)View子項(xiàng)的操作和仿制ListView的時(shí)候是一致的。