国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Android > 正文

Android RecyclerView區分視圖類型的Divider的實現

2019-10-22 18:12:45
字體:
來源:轉載
供稿:網友

我們都知道support庫有一個DividerItemDecoration, 可以作為Item之間的分隔線(divider)。但它作用以后所有的item之間都會有這個分隔線,實際情況往往是:recyclerView中存在多種的視圖類型(viewType), 我們只是需要在某一類型的視圖后添加分隔線。

要實現這種分隔線效果并不是什么難事,既然是某一類型有這個分隔線,那在直接在這種視圖的layout文件上增加如下一個bottomLine界面元素妥妥的:

<View  android:layout_width="match_parent"  android:layout_height="0.5dp"  android:background="@color/colorGrayLight" />

但如果添加這樣一個界面元素導致新增一層布局那感覺代價有點大。另外一種情況,如果當前這個視圖由于某種原因存在padding,而期望的分隔線是穿透整個布局的,那添加bottomLine的做法也是行不通的;還有一種情況同一類型布局在一個頁面有分隔線,在另一個頁面沒有分隔線;總之就是希望分隔線和視圖內容無關。所以我們需要一種類似DividerItemDecoration的decoration,它能針對某些viewType起作用。

先要了解一下RecyclerView.ItemDecoration,它有2個重要的回調方法:onDrawOver和getItemOffsets。onDrawOver其實是一種應用多個item的方法,所以無論如何都需要一個遍歷操作。需要理解的是getItemOffsets中outRect這個輸出型參數,雖然是一個Rect類型,但并不表示任何范圍,而只是一個item四周的間隔距離:

Android,RecyclerView,Divider

outRect參數各域的含義

我們思路已經很清楚了: 在getItemOffsets中判斷當前view的類型(parent.getChildViewHolder(view)), 如果是我們需要的類型設置對應的bottom;在onDrawOver中我們遍歷recyclerView的child,同樣如果是我們需要的類型將分隔線畫在對應位置上就行了;這個decoration可以針對任意一種或者幾種類型設置不種的drawable,我們當前用SparseArray存儲,key就是視圖的viewType
private final SparseArrayCompat<Drawable> mDividers = new SparseArrayCompat<>(2);
同時我們可以設置這個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;  }}

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VEVB武林網。


注:相關教程知識閱讀請移步到Android開發頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 灯塔市| 拜城县| 大渡口区| 牡丹江市| 环江| 和林格尔县| 襄城县| 长岭县| 石林| 淳安县| 思茅市| 攀枝花市| 正阳县| 齐齐哈尔市| 都安| 北辰区| 祁东县| 揭阳市| 金湖县| 舞阳县| 普陀区| 永川市| 三穗县| 多伦县| 红河县| 黑河市| 东安县| 黄浦区| 兰州市| 襄樊市| 买车| 高碑店市| 通河县| 密云县| 仁化县| 商水县| 正宁县| 嵊州市| 汉沽区| 怀化市| 花莲县|