滾動(dòng)顯示完整圖片

自定義ImageView,是RecyclerView的一個(gè)item,滾動(dòng)顯示完整的圖片,如下

device-2020-11-26-114926 00_00_04-00_00_24.gif

其實(shí)思路也很簡(jiǎn)單了,展示圖片的控件高度很小,而圖片高度很大,我們只有滾動(dòng)的時(shí)候才能看到完整圖片的不同部分, 我是想到ImageView處理圖片的時(shí)候也會(huì)裁剪啥的,而且也有一種scaleType是Matrix,我們動(dòng)態(tài)修改Matrix不就可以動(dòng)態(tài)處理圖片的顯示效果了?


image.png
image.png

如下就是自定義了一個(gè)ImageView


import android.content.Context
import android.graphics.Matrix
import android.util.AttributeSet
import androidx.appcompat.widget.AppCompatImageView
import androidx.recyclerview.widget.RecyclerView

class ScrollShowImageView : AppCompatImageView {

    constructor(context: Context) : super(context)
    constructor(context: Context, attrs: AttributeSet?) : super(context, attrs)
    constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(
        context,
        attrs,
        defStyleAttr
    )

    init {
        scaleType = ScaleType.MATRIX
    }

    val location = IntArray(2)
    val scrollListener = object : RecyclerView.OnScrollListener() {
        override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
            calMatrix()
        }

        override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
        }
    }
    private fun calMatrix(){

        drawable?.apply {
            val recyclerView=rv?:return
            //只關(guān)心上下滾動(dòng)的情況,所以這里只處理y軸
            recyclerView.getLocationInWindow(location)//get recyclerView location [left ,top]
            val y1 = location[1]
            getLocationInWindow(location)//get this ImageView location [left,top]
            val y2 = location[1]

            val imageViewTop = y2 - y1
            val rvHeight = recyclerView.height

            val factor = Math.max(imageViewTop * 1.0f / rvHeight, 0f)
            val dwidth: Int = this.bounds.width()//原始圖片寬
            val dheight: Int = this.bounds.height()//原始圖片高

            val vwidth: Int = width - paddingStart - paddingEnd// 這個(gè)ImageView的寬

            val scale: Float = vwidth.toFloat() / dwidth.toFloat()//我們要保證圖片橫向鋪滿,所以縮放以橫向?yàn)闇?zhǔn)

            val trans =
                factor * dheight * scale //dheight*scale 這個(gè)是原始圖片縮放后的實(shí)際高度, 乘以滾動(dòng)因子,就是要平移的距離
            val m = Matrix()
            m.setScale(scale, scale)
            m.postTranslate(0f, -trans)
            imageMatrix = m

        }
    }
    private var rv: RecyclerView? = null
    fun bindRecyclerView(recyclerView: RecyclerView) {
        if (rv == recyclerView) return
        rv?.removeOnScrollListener(scrollListener)
        rv = recyclerView
        rv?.addOnScrollListener(scrollListener)
        post { calMatrix() }
    }


    override fun onDetachedFromWindow() {
        super.onDetachedFromWindow()
        rv?.removeOnScrollListener(scrollListener)
        rv=null

    }
}

用的時(shí)候也很簡(jiǎn)單,設(shè)置完圖片,然后調(diào)用bindRecyclerView()就ok拉!

簡(jiǎn)單說下原理,黑框RecyclerView高度,紅框是ImageView高度,ImageView可見范圍就是RecyclerView的高度,算出這個(gè)因子,就知道圖片該偏移多少,反正ImageView到頂部的話顯示圖片的頂部視圖,ImageView在底部的話顯示圖片的底部視圖.

image.png

題外話

目前的效果是滾到頂部的時(shí)候圖片就不滾動(dòng)了,然后繼續(xù)劃出屏幕, 感覺不滿意的可以自行處理,把分母加上ImageView的高度也行,隨意.

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容