週記(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 屬性自動生效。
相關文章
相關標籤/搜索