IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> android 加载长图 -> 正文阅读

[移动开发]android 加载长图

长图加载的自定义view。

总结:1.利用Options先得到图片的宽高。

2.通过计算view的宽高得到?缩放因子。

3.利用缩放因子,计算要加载的图片Rect。

4.利用 BitmapRegionDecoder?结合Rect?进行制定区域解码图片。

5.通过 Options.inMutable = true?和Options.inBitmap = bitmap?重复利用Bitmap内存

6.利用缩放因子进行Bitmap矩阵的绘制,达到完全显示图片的效果

package com.example.bigview

import android.content.Context
import android.graphics.*
import android.util.AttributeSet
import android.view.GestureDetector
import android.view.MotionEvent
import android.view.View
import android.widget.Scroller
import java.io.InputStream

/**
 * 长图加载自定义 view
 */
class VerticalLoadBigView : View, GestureDetector.OnGestureListener {

    lateinit var bitmap: Bitmap
    private var mViewHeight: Int = 0
    var mViewWidth: Int = 0
    var mRect: Rect //要加载的图片的矩形区域

    var mOptions: BitmapFactory.Options //需要复用的

    var mGestureDetector: GestureDetector //手势识别

    var mImageWidth = 0
    var mImageHeight = 0

    lateinit var mDecoder: BitmapRegionDecoder

    var mScroller: Scroller //滑动帮助类

    var mScale: Float = 0.0f

    constructor(context: Context) : this(context, null)

    constructor(context: Context, attributeSet: AttributeSet?) : this(context, attributeSet, 0)

    constructor(context: Context, attributeSet: AttributeSet?, defS: Int) : super(
        context,
        attributeSet,
        defS
    ) {
        mRect = Rect()

        mOptions = BitmapFactory.Options()

        mGestureDetector = GestureDetector(context, this)

        mScroller = Scroller(context)
    }

    /**
     * 设置图片进来
     */
    fun setImage(inputStream: InputStream) {
        mOptions.inJustDecodeBounds = true
        BitmapFactory.decodeStream(inputStream, null, mOptions)
        //得到图片的宽高
        mImageWidth = mOptions.outWidth
        mImageHeight = mOptions.outHeight

        mOptions.inMutable = true //开启重用bitmap 必须与mOptions.bitmap = bitmap一起使用

        //设置格式
        mOptions.outConfig = Bitmap.Config.RGB_565

        mOptions.inJustDecodeBounds = false

        //创建一个区域解码器
        mDecoder = BitmapRegionDecoder.newInstance(inputStream, false)

        requestLayout()
    }

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec)

        //得到View的宽高
        mViewWidth = measuredWidth
        mViewHeight = measuredHeight

        //获得缩放因子
        if (mImageHeight > mImageWidth) {
            mScale = (mViewWidth / mImageWidth).toFloat()
        } else {
            mScale = (mViewHeight / mImageHeight).toFloat()
        }


        //确定要加载的图片的矩形区域
        mRect.left = 0
        mRect.top = 0
        mRect.right = mImageWidth
        mRect.bottom = (mImageHeight / mScale).toInt()
    }

    override fun onDraw(canvas: Canvas?) {
        super.onDraw(canvas)
        //解码图片的指定区域
        bitmap = mDecoder.decodeRegion(mRect, mOptions)

        //复用上一张bitmap的内存区域
        mOptions.inBitmap = bitmap


        //创建一个缩放比
        val matrix = Matrix()
        matrix.setScale(mScale, mScale)
        canvas?.drawBitmap(bitmap, matrix, null)
    }


    override fun onTouchEvent(event: MotionEvent?): Boolean {
        return mGestureDetector.onTouchEvent(event)
    }

    override fun onShowPress(e: MotionEvent?) {

    }

    override fun onSingleTapUp(e: MotionEvent?): Boolean {
        return false
    }

    override fun onDown(e: MotionEvent?): Boolean {
        if (!mScroller.isFinished) {
            //如果移动还没有停止,强制停止
            mScroller.forceFinished(true)
        }

        return true
    }

    /**
     * 处理惯性事件
     * velocaityX 计算像素点每秒移动的速度  得到的是一个速度值
     * velocaityY
     */
    override fun onFling(
        e1: MotionEvent?,
        e2: MotionEvent?,
        velocityX: Float,
        velocityY: Float
    ): Boolean {

        //做计算
        mScroller.fling(
            0, mRect.top,
            0, (-velocityY).toInt(),
            0, 0,
            0, mImageHeight - (mViewHeight / mScale).toInt()
        )
        return false
    }

    override fun computeScroll() {
        if (mScroller.isFinished) {
            return
        }
        //true 表示当前滑动还没有结束  就去计算 mRect的上下值
        if (mScroller.computeScrollOffset()) {
            mRect.top = mScroller.currY
            mRect.bottom = mRect.top + (mViewHeight / mScale).toInt()
            invalidate()
        }
    }

    /**
     * 处理滑动事件
     * e1 按下的 event
     * e2 移动的event
     * distanceX 左右移动的距离
     * distanceY 上下移动的距离
     */
    override fun onScroll(
        e1: MotionEvent?,
        e2: MotionEvent?,
        distanceX: Float,
        distanceY: Float
    ): Boolean {
        //设置偏移的距离
        mRect.offset(0, distanceY.toInt())

        //处理移动时已经移到了两个顶端的问题
        if (mRect.bottom > mImageHeight) {
            mRect.bottom = mImageHeight
            mRect.top = mImageHeight - (mViewHeight / mScale).toInt()
        }

        if (mRect.top < 0) {
            mRect.top = 0
            mRect.bottom = (mViewHeight / mScale).toInt()
        }

        invalidate()
        return false;
    }

    override fun onLongPress(e: MotionEvent?) {
    }
}
  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2021-08-05 17:27:58  更:2021-08-05 17:30:42 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/17 10:04:39-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码