zoukankan      html  css  js  c++  java
  • 长图的展开与收起(Android)

    前言:

    在app的文章中,经常会夹杂着一些特别长的长图。在阅读的时候需要滑动很久才能看图片下方的文字,因此对于长图只展示图片上面一部分,并且可以展开这个功能是很重要的。

    效果:

    基本思路:

    利用scaleType的matrix属性以及直接改变图片的高度来实现图片的收起与展开。

    过程:

    开始尝试:

    scaleType属性介绍:

    1. center:保持原图的大小,显示在ImageView的中心。当原图的size大于ImageView的size,超过部分裁剪处理;
    2. centerInside:以原图完全显示为目的,将图片的内容完整居中显示,通过按比例缩小原图的size宽(高)等于或小于ImageView的宽(高)。如果原图的size本身就小于ImageView的size,则原图的size不作任何处理,居中显示在ImageView;
    3. centerCrop:以填满整个ImageView为目的,将原图的中心对准ImageView的中心,等比例放大原图,直到填满ImageView为止(指的是ImageView的宽和高都要填满),原图超过ImageView的部分作裁剪处理;
    4. matrix:不改变原图的大小,从ImageView的左上角开始绘制原图,原图超过ImageView的部分作裁剪处理;
    5. fitCenter:把原图按比例扩大或缩小到ImageView的高度,居中显示;
    6. fitEnd:把原图按比例扩大(缩小)到ImageView的高度,显示在ImageView的下部分位置;
    7. fitStart:把原图按比例扩大(缩小)到ImageView的高度,显示在ImageView的上部分位置;
    8. fitXY:把原图按照指定的大小在View中显示,拉伸显示图片,不保持原比例,填满ImageView

    根据以上属性介绍,可以知道matrix属性是我们要的。

    基本布局:

     1 <ImageView
     2     android:id="@+id/iv_long_picture"
     3     android:layout_width="match_parent"
     4     android:layout_height="@dimen/dp_146"
     5     android:layout_below="@id/tv_main_content_question"
     6     android:adjustViewBounds="true"
     7     android:scaleType="matrix"
     8     android:src="@color/color_333333" />
     9 <TextView
    10     android:id="@+id/tv_expand_collapse"
    11     android:layout_width="wrap_content"
    12     android:layout_height="wrap_content"
    13     android:layout_below="@id/iv_long_picture"
    14     android:layout_marginBottom="@dimen/dp_16"
    15     android:layout_marginTop="@dimen/dp_10"
    16     android:drawableEnd="@drawable/down_icon"
    17     android:drawablePadding="@dimen/dp_7"
    18     android:text="@string/expand_all"
    19     android:textColor="@color/color_99"
    20     android:textSize="@dimen/sp_14"
    21     android:textStyle="bold"
    22     android:visibility="gone" />

    加载图片:

    使用Glide加载的图片,

    1 Glide.with(this)
    2         .load(mainContentBean.getAccessory().get(0))
    3         .into(ivLongPicture);

    点击事件:

    直接通过设置imageView的高度来实现图片的展开与收起,

     1 tvExpandCollapse.setOnClickListener(new View.OnClickListener() {
     2     boolean expanded = false;
     3     @Override
     4     public void onClick(View v) {
     5         if (expanded) {
     6             // 收起
     7             ViewGroup.LayoutParams params = ivLongPicture.getLayoutParams();
     8             params.width = RelativeLayout.LayoutParams.MATCH_PARENT;
     9             params.height = DensityUtil.dip2px(MainContentActivity.this, 146);
    10             ivLongPicture.setLayoutParams(params);
    11             expanded = false;
    12             tvExpandCollapse.setText(R.string.expand_all);
    13             tvExpandCollapse.setCompoundDrawablesRelativeWithIntrinsicBounds(0, 0, R.drawable.down_icon, 0);
    14             scMainContent.smoothScrollTo(0, 0);
    15         } else {
    16             // 展开
    17             ViewGroup.LayoutParams params = ivLongPicture.getLayoutParams();
    18             params.width = RelativeLayout.LayoutParams.MATCH_PARENT;
    19             params.height = RelativeLayout.LayoutParams.WRAP_CONTENT;
    20             ivLongPicture.setLayoutParams(params);
    21             expanded = true;
    22             tvExpandCollapse.setText(R.string.collapse_all);
    23             tvExpandCollapse.setCompoundDrawablesRelativeWithIntrinsicBounds(0, 0, R.drawable.upper_icon, 0);
    24         }
    25     }
    26 });

    遇到问题:

    根据以上的思路以及代码实现,普通的长图确实能够做到“展开”和“收起”功能。

    但是对于原图宽度超过手机宽度的图片来说,宽度并没有显示完全!

    对于Glide版本4.0以上,如果宽度过大,会等比例缩放至宽度等于ImageView的宽度,因此并不会有问题,但是我们的项目用Glide版本是3.7的,而且不容易升级,故此方法不可行。

    解决:

    查阅了Glide的文档,了解了Glide可以在图片下载完成后对图片进行一些操作,操作完成之后的图片自然就成了ImageView认为的原图了。

    因此,可以在加载之前将宽度过大的图片等比例缩放,缩放完成后再加载到ImageView中去

    加载图片改进:

     1 Glide.with(this)
     2             .load(mainContentBean.getAccessory().get(0))
     3             .asBitmap()
     4             .listener(new RequestListener<String, Bitmap>() {
     5                 @Override
     6                 public boolean onException(Exception e, String model, Target<Bitmap> target, boolean isFirstResource) {
     7                     return false;
     8                 }
     9 
    10                 @Override
    11                 public boolean onResourceReady(Bitmap resource, String model, Target<Bitmap> target, boolean isFromMemoryCache, boolean isFirstResource) {
    12                     int imageWidth = resource.getWidth();
    13                     int imageHeight = resource.getHeight();
    14 
    15                     WindowManager manager = (WindowManager) MainContentActivity.this
    16                             .getSystemService(Context.WINDOW_SERVICE);
    17 
    18                     // 屏幕宽度减去margin值
    19                     int width = manager.getDefaultDisplay().getWidth() - DensityUtil.dip2px(MainContentActivity.this, 32);
    20 
    21                     float scaleRate = width * 1.0f / imageWidth;
    22 
    23                     //设置matrix
    24                     Matrix matrix = new Matrix();
    25 
    26                     //设置放缩比例
    27                     matrix.setScale(scaleRate, scaleRate);
    28 
    29                     ivLongPicture.setImageMatrix(matrix);
    30 
    31                     if (imageHeight * scaleRate > DensityUtil.dip2px(MainContentActivity.this, 146)) {
    32                         tvExpandCollapse.setVisibility(View.VISIBLE);
    33                     } else {
    34                         tvExpandCollapse.setVisibility(View.GONE);
    35                     }
    36 
    37                     return false;
    38                 }
    39             })
    40             .into(ivLongPicture);

    总结:

    • ImageView的scaleType属性的各个属性值需要了解;
    • Glide版本之间的差异需要了解;
    • ImageView如何根据scaleType进行图片切割的需要了解(之后有时间阅读源码);
    • Glide是一个庞然大物,也是一个很值得学习的框架,需要熟悉掌握(之后有时间阅读源码)

    Android的优势在于开源,开源的好处在于易于学习,容易更改。对于开源的框架,仅仅是掌握是不够的,还需要好好的了解框架设计的一些设计模式,框架的优缺点等。

    大家如果有什么疑问或者建议可以通过评论或者邮件的方式联系我,欢迎大家的评论~

  • 相关阅读:
    SpringBoot,来实现MySQL读写分离技术
    range范围
    tuple元组
    序列通用操作及可变序列通用操作
    list列表
    数据
    python基础知识
    charm写代码时添加快捷键
    2、添加到项目里 在⚙图标里选择Add Remote...charm初期设置(远程服务器)
    5、优化
  • 原文地址:https://www.cnblogs.com/lanxingren/p/9700020.html
Copyright © 2011-2022 走看看