zoukankan      html  css  js  c++  java
  • 3.26Android学习

    一、今日学习

    Android加载长图的多种方案分享

    背景介绍

    在某些特定场景下,我们需要考虑加载长图的需求,比如加载一幅《清明上河图》,这个好像有点过分了,那就加载1/2的《清明上河图》吧... 那TMD还不是一样道理。

    言归正传说一下我这边遇到的情况,之前有图片或大图的模块是划分为H5来实现的,现在需求变更划分为原生开发,那么问题就来了。

    图片尺寸为

    图片大小为

    这一刻我是懵逼的,哪个端图片上传的时候没限制尺寸和压缩?mdzz, 吐槽归吐槽,还是要撸起袖子解决加载长图大图的问题。 先提供几个技术方案来对比一下:

     

    方案1:WebView加载渲染

    因为图片本身也是一个URL地址,也是被WebView渲染,并且支持缩放。这是一种实现方案,遇到几M的大图WebView也是会崩溃Crash,所以这种投机的方式并不推荐。

     

    方案2:BitmapRegionDecoder

    分片加载,使用系统BitmapRegionDecoder去加载本地的图片,调用bitmapRegionDecoder.decodeRegion解析图片的矩形区域,返回bitmap,最终显示在ImageView上。这种方案需要手动处理滑动、缩放手势,网络图片还要处理缓存策略等问题。实现方式比较繁琐也不是很推荐。

     

    方案3:SubsamplingScaleImageView

    一款封装BitmapRegionDecoder的三方库,已经处理了滑动,缩放手势。我们可以考虑选择这个库来进行加载长图,但是官方上的Demo示例加载的长图均为本地图片。这可能并不符合我们的网络场景需求,所以对于网络图片,我们还要考虑不同的加载框架,

    SubsamplingScaleImageView Git传送门

     

    方案4:Glide+SubsamplingScaleImageView混合加载渲染

    对于图片加载框架,Glide当然是首选,我们使用Glide进行网络图片的下载和缓存管理,FileTarget作为桥梁,SubsamplingScaleImageView进行本地资源图片的分片加载,看起来很靠谱,那么一起来实现吧。

    Glide Git传送门

    SubsamplingScaleImageView Git传送门

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    fun loadLargeImage(context: Context, res: String, imageView: SubsamplingScaleImageView) {
                imageView.isQuickScaleEnabled = true
                imageView.maxScale = 15F
                imageView.isZoomEnabled = true
                imageView.setMinimumScaleType(SubsamplingScaleImageView.SCALE_TYPE_CUSTOM)
                
                Glide.with(context).load(res).downloadOnly(object : SimpleTarget<File?>() {
                    override fun onResourceReady(resource: File, glideAnimation: Transition<in File?>?) {
                        val sWidth = BitmapFactory.decodeFile(resource.absolutePath).width
                        val sHeight = BitmapFactory.decodeFile(resource.absolutePath).height
                        val wm = ContextCompat.getSystemService(context, WindowManager::class.java)
                        val width = wm?.defaultDisplay?.width ?: 0
                        val height = wm?.defaultDisplay?.height ?: 0
                        if (sHeight >= height
                                && sHeight / sWidth >= 3) {
                            imageView.setMinimumScaleType(SubsamplingScaleImageView.SCALE_TYPE_CENTER_CROP)
                            imageView.setImage(ImageSource.uri(Uri.fromFile(resource)), ImageViewState(0.5f, PointF(0f, 0f), 0))
                        } else {
                            imageView.setMinimumScaleType(SubsamplingScaleImageView.SCALE_TYPE_CUSTOM)
                            imageView.setImage(ImageSource.uri(Uri.fromFile(resource)))
                            imageView.setDoubleTapZoomStyle(SubsamplingScaleImageView.ZOOM_FOCUS_CENTER_IMMEDIATE)
                        }
                    }
                    override fun onLoadFailed(errorDrawable: Drawable?) {
                        super.onLoadFailed(errorDrawable)
                    }
                })
     
            }

    这是我封装起来的一个方法,就很简单就能理解了, 包括SubsamplingScaleImageView的缩放设置,默认展示状态、缩放、位置,计算当前图片高宽比为3倍进行长图渲染处理,否则按正常图片渲染处理。

    最后快用下面的这张完整版《清明上河图》来试一试效果吧~ 赞

    二、问题

     无,原文出自脚本之家

    三、明日计划

    继续Android学习

  • 相关阅读:
    创建Variant数组
    ASP与存储过程(Stored Procedures)
    FileSystemObject对象成员概要
    Kotlin 朱涛9 委托 代理 懒加载 Delegate
    Kotlin 朱涛 思维4 空安全思维 平台类型 非空断言
    Kotlin 朱涛7 高阶函数 函数类型 Lambda SAM
    Kotlin 朱涛16 协程 生命周期 Job 结构化并发
    Proxy 代理模式 动态代理 cglib MD
    RxJava 设计理念 观察者模式 Observable lambdas MD
    动态图片 Movie androidgifdrawable GifView
  • 原文地址:https://www.cnblogs.com/zyljal/p/14908847.html
Copyright © 2011-2022 走看看