经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 移动开发 » Android » 查看文章
长图的展开与收起(Android)
来源:cnblogs  作者:懒星人  时间:2018/9/25 19:59:51  对本文有异议

前言:

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

加载图片:

使用Glide加载的图片,

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

点击事件:

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

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

遇到问题:

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

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

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

解决:

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

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

加载图片改进:

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

总结:

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

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

 

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

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号