实现以上页面效果,很多开发者会用NestedScrollView去做,然后用recyclerview实现中间菜单区域,在给recyclerview整体做一个带圆角的白色背景图。但是如果整体页面用RecyclerView实现,layoutManager用GribLayoutManager(3),那如何解决以下问题呢?
1.顶部用户信息区域与banner区域做一个整体背景图
2.中间菜单区域使用白色圆角背景图呢
3.菜单区域的最左,最右的菜单按钮,其对应leftmargin与rightmargin不一致
为了解决以上问题,我们得要使用ItemDecoration类,google对于它的解释如下
An ItemDecoration allows the application to add a special drawing and layout offset to specific item views from the adapter's data set. This can be useful for drawing dividers between items, highlights, visual grouping boundaries and more.
解释如下:
ItemDecoration允许应用从适配器的数据向特定的多个Item视图,添加特殊的图形和布局偏移。 这对于在项目,突出显示,可视分组边界等之间绘制分隔线很有用。
public abstract static class ItemDecoration {
// 在条目绘制之前绘制装饰,即在RecyclerView条目的底层展示。
public void onDraw(Canvas c, RecyclerView parent, State state) {
}
// 在条目绘制之后绘制装饰,即在RecyclerView条目的上层展示。
public void onDrawOver(Canvas c, RecyclerView parent, State state) {
}
// 重新设置条目的边距
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, State state) {
}
}
基于ui效果,我们只用在ondraw方法进行操作即可
class BackgroundItemDecoration : RecyclerView.ItemDecoration() {
private val mTempRect = Rect()
override fun onDraw(c: Canvas, parent: RecyclerView, state: RecyclerView.State) {
super.onDraw(c, parent, state)
val childCount = parent.childCount
var left = -1
var top = -1
var right = -1
var bottom = -1
for (i in 0 until childCount) {
val view = parent.getChildAt(i)
if (view.visibility != View.GONE && isTargetItem(view, parent)) {
parent.getDecoratedBoundsWithMargins(view, mTempRect)
if(left == -1){
left = mTempRect.left
top = mTempRect.top
}else if(isRightItem(view,parent)){
right = mTempRect.right
}else{
bottom = mTempRect.bottom
}
}
}
val drawable = ContextCompat.getDrawable(parent.context,R.drawable.shape_round_10_white_bg)
drawable?.setBounds(left,top,right,bottom)
drawable?.draw(c)
}
override fun getItemOffsets(outRect: Rect, view: View, parent: RecyclerView, state: RecyclerView.State) {
super.getItemOffsets(outRect, view, parent, state)
}
private fun isTargetItem(view: View, parent: RecyclerView): Boolean {
var target = false
if (view.visibility != View.GONE) {
val adapter = parent.adapter
if (adapter != null && adapter.getItemViewType(parent.getChildAdapterPosition(view))
!= BaseQuickAdapter.HEADER_VIEW && adapter.getItemViewType(parent.getChildAdapterPosition(view))
!= BaseQuickAdapter.FOOTER_VIEW) {
target = true
}
}
return target
}
private fun isRightItem(view: View, parent: RecyclerView): Boolean {
val isLeft: Boolean
val layoutManager = parent.layoutManager
isLeft = if (layoutManager !is GridLayoutManager) {
true
} else {
val spanIndex: Int = layoutManager.spanSizeLookup
.getSpanIndex(parent.getChildAdapterPosition(view),
layoutManager.spanCount)
spanIndex == 2
}
return isLeft
}
}
不知道大家对以上的ui该如何代码实现布局呢?