我們都知道support庫有一個DividerItemDecoration, 可以作為Item之間的分隔線(divider)。但它作用以后所有的item之間都會有這個分隔線,實際情況往往是:recyclerView中存在多種的視圖類型(viewType), 我們只是需要在某一類型的視圖后添加分隔線。
創(chuàng)新互聯(lián)主營天心網(wǎng)站建設(shè)的網(wǎng)絡(luò)公司,主營網(wǎng)站建設(shè)方案,app軟件定制開發(fā),天心h5重慶小程序開發(fā)公司搭建,天心網(wǎng)站營銷推廣歡迎天心等地區(qū)企業(yè)咨詢
要實現(xiàn)這種分隔線效果并不是什么難事,既然是某一類型有這個分隔線,那在直接在這種視圖的layout文件上增加如下一個bottomLine界面元素妥妥的:
<View android:layout_width="match_parent" android:layout_height="0.5dp" android:background="@color/colorGrayLight" />
但如果添加這樣一個界面元素導致新增一層布局那感覺代價有點大。另外一種情況,如果當前這個視圖由于某種原因存在padding,而期望的分隔線是穿透整個布局的,那添加bottomLine的做法也是行不通的;還有一種情況同一類型布局在一個頁面有分隔線,在另一個頁面沒有分隔線;總之就是希望分隔線和視圖內(nèi)容無關(guān)。所以我們需要一種類似DividerItemDecoration的decoration,它能針對某些viewType起作用。
先要了解一下RecyclerView.ItemDecoration,它有2個重要的回調(diào)方法:onDrawOver和getItemOffsets。onDrawOver其實是一種應用多個item的方法,所以無論如何都需要一個遍歷操作。需要理解的是getItemOffsets中outRect這個輸出型參數(shù),雖然是一個Rect類型,但并不表示任何范圍,而只是一個item四周的間隔距離:

outRect參數(shù)各域的含義
我們思路已經(jīng)很清楚了: 在getItemOffsets中判斷當前view的類型(parent.getChildViewHolder(view)), 如果是我們需要的類型設(shè)置對應的bottom;在onDrawOver中我們遍歷recyclerView的child,同樣如果是我們需要的類型將分隔線畫在對應位置上就行了;這個decoration可以針對任意一種或者幾種類型設(shè)置不種的drawable,我們當前用SparseArray存儲,key就是視圖的viewType
private final SparseArrayCompat<Drawable> mDividers = new SparseArrayCompat<>(2);
同時我們可以設(shè)置這個item的高度,當Drawable為null時相當于一個透明的間隙,不為null時具有強制指定的高度。
同樣我們還要考慮方向:layoutManager為橫向和豎向的情況,無它,只是畫的位置不同而已。
話不多說了,上代碼:
import android.graphics.drawable.Drawable;
import android.support.annotation.Nullable;
import android.support.v7.widget.RecyclerView;
public class ViewTypeDivider extends ItemHolderDivider {
@Override
protected int keyFrom(RecyclerView.ViewHolder holder) {
return holder.getItemViewType();
}
public ViewTypeDivider put(int viewType, Drawable drawable) {
putDrawable(viewType, drawable);
return this;
}
public ViewTypeDivider put(int viewType, @Nullable Drawable drawable, int height) {
putHeight(viewType, drawable, height);
return this;
}
}
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.support.annotation.Nullable;
import android.support.v4.util.SparseArrayCompat;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;
abstract class ItemHolderDivider extends RecyclerView.ItemDecoration {
private final SparseArrayCompat<Drawable> mDividers = new SparseArrayCompat<>(2);
private final SparseArrayCompat<Integer> mHeights = new SparseArrayCompat<>(2);
protected abstract int keyFrom(RecyclerView.ViewHolder holder);
@Override
public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {
final int childCount = parent.getChildCount();
final int width = parent.getWidth();
final int height = parent.getHeight();
for (int childViewIndex = 0; childViewIndex < childCount; childViewIndex++) {
final View view = parent.getChildAt(childViewIndex);
RecyclerView.ViewHolder holder = parent.getChildViewHolder(view);
int key = keyFrom(holder);
if (isVertical(parent)) {
drawBottom(c, key, (int) view.getY() + view.getHeight(), width);
drawTop(c, -key, (int) view.getY(), width);
} else {
drawRight(c, key, (int) view.getX() + view.getWidth(), height);
drawLeft(c, -key, (int) view.getX(), height);
}
}
}
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent,
RecyclerView.State state) {
RecyclerView.ViewHolder holder = parent.getChildViewHolder(view);
int key = keyFrom(holder);
if (isVertical(parent)) {
outRect.bottom = getHeight(key);
outRect.top = getHeight(-key);
} else {
outRect.right = getHeight(key);
outRect.left = getHeight(-key);
}
}
private void drawBottom(Canvas c, int key, int y, int width) {
Drawable d = mDividers.get(key);
if (d != null) {
d.setBounds(0, y, width, y + getHeight(key, d));
d.draw(c);
}
}
private void drawTop(Canvas c, int key, int y, int width) {
Drawable d = mDividers.get(key);
if (d != null) {
d.setBounds(0, y - getHeight(key, d), width, y);
d.draw(c);
}
}
private void drawRight(Canvas c, int key, int x, int height) {
Drawable d = mDividers.get(key);
if (d != null) {
d.setBounds(x, 0, x + getHeight(key, d), height);
d.draw(c);
}
}
private void drawLeft(Canvas c, int key, int x, int height) {
Drawable d = mDividers.get(key);
if (d != null) {
d.setBounds(x - getHeight(key, d), 0, x, height);
d.draw(c);
}
}
final void putDrawable(int key, Drawable drawable) {
mDividers.put(key, drawable);
}
final void putHeight(int key, @Nullable Drawable drawable, int height) {
if (drawable != null) {
mDividers.put(key, drawable);
}
mHeights.put(key, height);
}
private int getHeight(int key) {
Drawable d = mDividers.get(key);
return getHeight(key, d);
}
private int getHeight(int key, @Nullable Drawable d) {
int index = mHeights.indexOfKey(key);
return index < 0 ? d == null ? 0 : d.getIntrinsicHeight() : mHeights.valueAt(index);
}
private boolean isVertical(RecyclerView parent) {
RecyclerView.LayoutManager layoutManager = parent.getLayoutManager();
return !(layoutManager instanceof LinearLayoutManager) ||
((LinearLayoutManager) layoutManager).getOrientation() == LinearLayoutManager.VERTICAL;
}
}
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持創(chuàng)新互聯(lián)。
當前題目:AndroidRecyclerView區(qū)分視圖類型的Divider的實現(xiàn)
網(wǎng)站URL:http://www.chinadenli.net/article44/pecehe.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站營銷、響應式網(wǎng)站、網(wǎng)站策劃、網(wǎng)站設(shè)計、定制開發(fā)、用戶體驗
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)