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学习

  • 相关阅读:
    保罗·多兰《设计幸福》阅读笔记
    依梦随忆(她)
    科技与人性的交汇处----人和机器人的边际在哪里?
    luogu 5月月赛 #A
    luogu P3916 图的遍历
    数论基础之组合数&计数问题
    洛谷——P3173 [HAOI2009]巧克力
    洛谷——P1748 H数
    洛谷——P1404 平均数
    POJ2454——Jersey Politics
  • 原文地址:https://www.cnblogs.com/zyljal/p/14908847.html
Copyright © 2011-2022 走看看