RecyclerView中利用GridLayoutManager實現item四周都帶有分割線效果(更正版!!!)
阿新 • • 發佈:2019-01-07
今天,花了很長的時間才實現瞭如題的效果,回想一下,實現起來確實不難,只怪當時做的時候思路不清晰,沒想好就動手了,這是病,得改!好了,不多說,實現工程中主要參考了鴻洋部落格中Android RecyclerView 使用完全解析 體驗藝術般的控制元件DividerGridItemDecoration這個類的實現,其中有一個問題,就是一開始我死活都弄不出豎向方向分割線效果,後來查了一下資料,最後在部落格下方的評論那裡找到了解決方案,即是:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >
<gradient
android:centerColor="#ff00ff00"
android:endColor="#ff0000ff"
android:startColor="#ffff0000"
android:type="linear" />
<size android:height="4dp"
android:width="4dp"/>
</shape>
drawable檔案中需要加上android:width=”4dp”這個屬性,我在部落格上面沒看到有width這個屬性,可能部落格的demo裡面有吧(這,就尷尬了,我這次沒有下載原始碼來跑)。。
現在說一下如何實現item四周都帶有分割線效果,關鍵地方在於DividerGridItemDecoration這個類,其中我作了修改的地方主要如下:
public void drawHorizontal(Canvas c, RecyclerView parent)
{
int childCount = parent.getChildCount();
for (int i = 0; i < childCount; 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();
int top = 0;
int bottom = 0;
// 1 不計算中間item的divider情況
if((i/column_num) == 0) {
//畫item最上面的分割線
top = child.getTop(); //該處一開始是top = 0,沒考慮到佈局中recyclerview的padding情況
bottom = top + mDivider.getIntrinsicHeight();
mDivider.setBounds(left, top, right, bottom);
mDivider.draw(c);
//畫item下面的分割線
top = child.getBottom() + params.bottomMargin;
bottom = top + mDivider.getIntrinsicHeight();
mDivider.setBounds(left, top, right, bottom);
mDivider.draw(c);
}
else {
top = child.getBottom() + params.bottomMargin;
bottom = top + mDivider.getIntrinsicHeight();
mDivider.setBounds(left, top, right, bottom);
mDivider.draw(c);
}
// 2 計算中間item的divider情況
// //畫item最上面的分割線
// top = child.getTop(); //該處一開始是top = 0,沒考慮到佈局中recyclerview的padding情況
// bottom = top + mDivider.getIntrinsicHeight();
// mDivider.setBounds(left, top, right, bottom);
// mDivider.draw(c);
// //畫item下面的分割線
// top = child.getBottom() + params.bottomMargin;
// bottom = top + mDivider.getIntrinsicHeight();
// mDivider.setBounds(left, top, right, bottom);
// mDivider.draw(c);
}
}
public void drawVertical(Canvas c, RecyclerView parent)
{
final int childCount = parent.getChildCount();
for (int i = 0; i < childCount; 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;
int left = 0;
int right = 0;
// 3 不計算中間item的divider情況
if((i%column_num) == 0) {
//item左邊分割線
left = child.getLeft();//該處一開始是left = 0,沒考慮到佈局中recyclerview的padding情況
right = left + mDivider.getIntrinsicWidth();
mDivider.setBounds(left, top, right, bottom);
mDivider.draw(c);
//item右邊分割線
left = child.getRight() + params.rightMargin;
right = left + mDivider.getIntrinsicWidth();
}
else {
left = child.getRight() + params.rightMargin;
right = left + mDivider.getIntrinsicWidth();
}
// 4 計算中間item的divider情況
// //item左邊分割線
// left = child.getLeft();//該處一開始是left = 0, 沒考慮到佈局中recyclerview的padding情況
// right = left + mDivider.getIntrinsicWidth();
// mDivider.setBounds(left, top, right, bottom);
// mDivider.draw(c);
// //item右邊分割線
// left = child.getRight() + params.rightMargin;
// right = left + mDivider.getIntrinsicWidth();
mDivider.setBounds(left, top, right, bottom);
mDivider.draw(c);
}
}
程式碼裡面我已經加上相應的註釋,相信還是比較容易理解的,另外,遮蔽瞭如下的程式碼(下面的程式碼判斷是否是最後一列,博主原本是不繪製右邊的分割線):
private boolean isLastColum(RecyclerView parent, int pos, int spanCount,
int childCount)
{
RecyclerView.LayoutManager layoutManager = parent.getLayoutManager();
if (layoutManager instanceof GridLayoutManager)
{
/* if ((pos + 1) % spanCount == 0)// 如果是最後一列,則不需要繪製右邊
{
return true;
}*/
} else if (layoutManager instanceof StaggeredGridLayoutManager)
{
下面是判斷是否是最後一行,博主原本是不繪製底部分割線
private boolean isLastRaw(RecyclerView parent, int pos, int spanCount,
int childCount)
{
RecyclerView.LayoutManager layoutManager = parent.getLayoutManager();
if (layoutManager instanceof GridLayoutManager)
{
/* childCount = childCount - childCount % spanCount;
if (pos >= childCount)// 如果是最後一行,則不需要繪製底部
return true;*/
} else if (layoutManager instanceof StaggeredGridLayoutManager)
{
備註:顯示效果中出現了中間的item正常,但是邊緣的item寬高彆扭,主要是因為 我沒有處理中間item的左、右divider造成,因為我的divider_bg中divider的width、height設定的比較小,不處理中間item的左、右divider看上去稍微好看些,實際開發中,如果要處理,那麼恢復 drawHorizontal方法中的2註釋(還要註釋掉1註釋)以及 drawVertical方法中的4註釋(還要註釋掉3註釋),可詳見demo
嗯,以上就是主要的修改程式碼,下面附上demo下載連結,點我下載~