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属性是我们要的。
基本布局:
<imageview android:id="@+id/iv_long_picture" android:layout_width="match_parent" android:layout_height="@dimen/dp_146" android:layout_below="@id/tv_main_content_question" android:adjustviewbounds="true" android:scaletype="matrix" android:src="@color/color_333333" /> <textview android:id="@+id/tv_expand_collapse" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/iv_long_picture" android:layout_marginbottom="@dimen/dp_16" android:layout_margintop="@dimen/dp_10" android:drawableend="@drawable/down_icon" android:drawablepadding="@dimen/dp_7" android:text="@string/expand_all" android:textcolor="@color/color_99" android:textsize="@dimen/sp_14" android:textstyle="bold" android:visibility="gone" />
加载图片:
使用glide加载的图片
glide.with(this) .load(maincontentbean.getaccessory().get(0)) .into(ivlongpicture);
点击事件:
直接通过设置imageview的高度来实现图片的展开与收起,
tvexpandcollapse.setonclicklistener(new view.onclicklistener() { boolean expanded = false; @override public void onclick(view v) { if (expanded) { // 收起 viewgroup.layoutparams params = ivlongpicture.getlayoutparams(); params.width = relativelayout.layoutparams.match_parent; params.height = densityutil.dip2px(maincontentactivity.this, 146); ivlongpicture.setlayoutparams(params); expanded = false; tvexpandcollapse.settext(r.string.expand_all); tvexpandcollapse.setcompounddrawablesrelativewithintrinsicbounds(0, 0, r.drawable.down_icon, 0); scmaincontent.smoothscrollto(0, 0); } else { // 展开 viewgroup.layoutparams params = ivlongpicture.getlayoutparams(); params.width = relativelayout.layoutparams.match_parent; params.height = relativelayout.layoutparams.wrap_content; ivlongpicture.setlayoutparams(params); expanded = true; tvexpandcollapse.settext(r.string.collapse_all); tvexpandcollapse.setcompounddrawablesrelativewithintrinsicbounds(0, 0, r.drawable.upper_icon, 0); } } });
遇到问题:
根据以上的思路以及代码实现,普通的长图确实能够做到“展开”和“收起”功能。
但是对于原图宽度超过手机宽度的图片来说,宽度并没有显示完全!
对于glide版本4.0以上,如果宽度过大,会等比例缩放至宽度等于imageview的宽度,因此并不会有问题,但是我们的项目用glide版本是3.7的,而且不容易升级,故此方法不可行。
解决:
查阅了glide的文档,了解了glide可以在图片下载完成后对图片进行一些操作,操作完成之后的图片自然就成了imageview认为的原图了。
因此,可以在加载之前将宽度过大的图片等比例缩放,缩放完成后再加载到imageview中去。
加载图片改进:
glide.with(this) .load(maincontentbean.getaccessory().get(0)) .asbitmap() .listener(new requestlistener<string, bitmap>() { @override public boolean onexception(exception e, string model, target<bitmap> target, boolean isfirstresource) { return false; } @override public boolean onresourceready(bitmap resource, string model, target<bitmap> target, boolean isfrommemorycache, boolean isfirstresource) { int imagewidth = resource.getwidth(); int imageheight = resource.getheight(); windowmanager manager = (windowmanager) maincontentactivity.this .getsystemservice(context.window_service); // 屏幕宽度减去margin值 int width = manager.getdefaultdisplay().getwidth() - densityutil.dip2px(maincontentactivity.this, 32); float scalerate = width * 1.0f / imagewidth; //设置matrix matrix matrix = new matrix(); //设置放缩比例 matrix.setscale(scalerate, scalerate); ivlongpicture.setimagematrix(matrix); if (imageheight * scalerate > densityutil.dip2px(maincontentactivity.this, 146)) { tvexpandcollapse.setvisibility(view.visible); } else { tvexpandcollapse.setvisibility(view.gone); } return false; } }) .into(ivlongpicture);
总结:
- imageview的scaletype属性的各个属性值需要了解;
- glide版本之间的差异需要了解;
- imageview如何根据scaletype进行图片切割的需要了解(之后有时间阅读源码);
- glide是一个庞然大物,也是一个很值得学习的框架,需要熟悉掌握(之后有时间阅读源码)
android的优势在于开源,开源的好处在于易于学习,容易更改。对于开源的框架,仅仅是掌握是不够的,还需要好好的了解框架设计的一些设计模式,框架的优缺点等。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。