周记(1)-2019-10-27-Android

  1. Bug 汇总java

    1. merge 标签在 ConstraintLayout 中约束失效。
      1. 参考连接
  2. 知识点android

    1. RecyclerView 自定义 ItemDecoration
      1. 参考连接1
      2. 参考连接2
      3. RecyclerView animation 的库
    2. LayoutInflater 填充界面
      1. 郭神的文章

1. Bugs:

  1. 在 ConstraintLayout 布局中使用 include 添加根布局标签为 merge 的 xml 页面时,约束失效。

解决方案:git

  • 在被添加的页面中,移除 merge 标签。

当使用 include 标签时,系统会把 include 标签的属性运用到被添加页面到根视图上。可是 merge 标签是一个特殊的标签,它容许你在布局中有多个视图,但没有根视图。因此使用 merge 标签时,全部约束会被丢弃。github

2. 知识点

1. ItemDecoration

实现自定义的 ItemDecoration,主要重写三个方法,getOffSetsonDraw、和 onDrawOverapp

1.1 getItemOffSets

  • 做用:

设置 ItemView 的内嵌偏移长度,每一个 ItemView 外部都有一个 Rect 矩形(OutRect),默认 ItemView 在 OutRect 中的偏移为 0(重叠),经过调用 outRect 方法能够设置内部 View 的偏移量。ide

  • 代码:
override fun getItemOffsets( outRect: Rect, view: View, parent: RecyclerView, state: RecyclerView.State ) {
        super.getItemOffsets(outRect, view, parent, state)
        outRect.set(50, 50, 50, 50)
    }
复制代码
  • 效果:

原图和实现对比图

1.2 onDraw

onDraw 用于在 ItemView 上进行绘制,onDraw优先进行绘制,并被布局

  • 做用:

为每一个 ItemView 绘制,绘制图层在 ItemView 如下,若是绘制区域相重叠,会被 ItemView 遮挡。ui

  • 代码:
override fun onDraw(c: Canvas, parent: RecyclerView, state: RecyclerView.State) {
        super.onDraw(c, parent, state)
        val childCount = parent.childCount
        paint.color = Color.YELLOW
        for (i in 0 until childCount) {
            val child = parent.getChildAt(i)
            val divider = 10
            val left = child.left
            val top = child.top - divider
            val right = child.right
            val bottom = child.bottom + divider
            c.drawRect(left.toFloat(), top.toFloat(), right.toFloat(), bottom.toFloat(), paint)
        }
    }
复制代码
  • 效果:

绘制的黄色矩形被 ItemView 遮挡

1.3 onDrawOver

  • 做用:

绘制图像,并显示在 itemView 的上层。spa

  • 代码:
override fun onDrawOver(c: Canvas, parent: RecyclerView, state: RecyclerView.State) {
        super.onDrawOver(c, parent, state)
        val childCount = parent.childCount
        paint.color = Color.RED
        for (i in 0 until childCount) {
            val child = parent.getChildAt(i)
            val top = child.top
            val left = child.right - bitmap.width
            c.drawBitmap(bitmap,left.toFloat(),top.toFloat(),paint)
        }
    }
复制代码
  • 效果:

1.4 实现自定义头部并将头部保持在顶部

  • 代码
package com.learnandroid.androidlibraryapp.fragments

import android.content.Context
import android.graphics.*
import android.view.View
import androidx.recyclerview.widget.RecyclerView
import com.learnandroid.androidlibraryapp.R

/** * com.learnandroid.androidlibraryapp.fragments * Author: binguner * Date: 2019-10-23 20:24 */
class MyRecyclerViewDecoration(val context: Context) : RecyclerView.ItemDecoration() {

    private val paint: Paint = Paint()
    private val textPaint: Paint = Paint()
    private var bitmap:Bitmap = BitmapFactory.decodeResource(context.resources,R.drawable.ic_account_circle_black_24dp)
    private val TAG = MyRecyclerViewDecoration::class.java.simpleName
    private var mIndex: Int = 0

    // 设置 ItemView 的内嵌偏移长度,每一个 ItemView 外部都有一个 Rect 矩形(OutRect),默认 ItemView 在 OutRect 中的偏移为 0(重叠)
    override fun getItemOffsets( outRect: Rect, view: View, parent: RecyclerView, state: RecyclerView.State ) {
        super.getItemOffsets(outRect, view, parent, state)
        val position = parent.getChildAdapterPosition(view)
        if (position % 5 == 0) {
            outRect.set(0, 50, 0, 0)
        }
    }

    // 在子视图上设置绘制范围,并绘制内容,绘制图层在 ItemView 如下,若是绘制区域相重叠,会被遮挡
    override fun onDraw(c: Canvas, parent: RecyclerView, state: RecyclerView.State) {
        super.onDraw(c, parent, state)
    }

    // 绘制内容:绘制在图层的最上面
    override fun onDrawOver(c: Canvas, parent: RecyclerView, state: RecyclerView.State) {
        super.onDrawOver(c, parent, state)
        paint.color = Color.YELLOW
        textPaint.color = Color.BLACK
        textPaint.textSize = 35f
        val childCount = parent.childCount
        for (i in 0 until childCount) {
            val child = parent.getChildAt(i)
            val index = parent.getChildAdapterPosition(child)
            if (index % 5 == 0) {
                if (i < 5) {
                    if (i == 1 && child.top < 100 ) {
                        val divider = 50
                        val top = child.top - divider
                        val left = child.left
                        val bottom = child.top
                        val right = child.right
                        c.drawRect(left.toFloat(),top.toFloat(),right.toFloat(),bottom.toFloat(),paint)
                        c.drawText("Index is $index", left.toFloat(), child.top.toFloat() - 10, textPaint)
                    }else{
                        val divider = 50
                        val top = 0
                        val left = 0
                        val bottom = divider
                        val right = child.right
                        c.drawRect(left.toFloat(),top.toFloat(),right.toFloat(),bottom.toFloat(),paint)
                        if (i == 0) {
                            c.drawText("Index is ${index}", left.toFloat(), 35f, textPaint)
                        } else {
                            c.drawText("Index is ${index - 5}", left.toFloat(), 35f, textPaint)
                        }
                    }
                }
                if (i != 0) {
                    val divider = 50
                    val top = child.top - divider
                    val left = child.left
                    val bottom = child.top
                    val right = child.right
                    c.drawRect(left.toFloat(),top.toFloat(),right.toFloat(),bottom.toFloat(),paint)
                    c.drawText("Index is $index", left.toFloat(), child.top.toFloat() - 10, textPaint)
                }
            }
            val top = child.top
            val left = child.right - bitmap.width
            c.drawBitmap(bitmap,left.toFloat(),top.toFloat(),paint)
            if (i < 5) {
                val divider = 50
                val top = child.top - divider
                val left = child.left
                val right = child.right
                val bottom = child.top
            }
    }

}
复制代码
  • 效果

2. LayoutInflater

LayoutInflater 的 infalte 方法有如下几个重载:.net

public View inflate(@LayoutRes int resource, @Nullable ViewGroup root) 
public View inflate(@LayoutRes int resource, @Nullable ViewGroup root, boolean attachToRoot)
复制代码

第一个方法里调用第二个方法,attachToRoot 默认为 true。

  • 若是 root 为 null,attachToRoot 没有意义
  • 若是 root 不为 null,attachToRoot 为 true,会给当前 View 添加一个父布局(root)
  • 若是 root 部位 null,arrachToRoot 为 false,会将布局文件最外层的全部 layout 属性进行设置,当该 View 被添加到父布局中,layout 属性自动生效。
相关文章
相关标签/搜索