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

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • android列表控件实现展开、收缩功能

    最近在做一个Rss阅读器,我看了一看别人做的阅读器中的lisView可以伸缩,展开,我就在网上搜索了一下.果然让我找到,下面就我找到的一个小例子,给大家分享一下. ActivityMain .java package com.android; import android.app.ExpandableListActivity; import android.os.Bundle; import android.view.ContextMenu; import android.view.MenuIt

  • Android实现长图展开与收起效果

    前言: 在app的文章中,经常会夹杂着一些特别长的长图.在阅读的时候需要滑动很久才能看图片下方的文字,因此对于长图只展示图片上面一部分,并且可以展开这个功能是很重要的. 效果: 基本思路: 利用scaleType的matrix属性以及直接改变图片的高度来实现图片的收起与展开. 过程: 开始尝试: scaleType属性介绍: 1.center:保持原图的大小,显示在ImageView的中心.当原图的size大于ImageView的size,超过部分裁剪处理: 2.centerInside:以原图

  • 原生JS仿QQ阅读点击展开、收起效果

    使用JS技术实现QQ阅读类似的点击展开.收起效果,具体内容如下 一.定义展开函数showdiv(),实现点击"全文"按钮,全文展开. 1.点击展开函数,需要将触发点击事件的按钮作为参数传入 2.通过传入的按钮,查找其父元素,将其父元素设置为隐藏. 3.将紧跟其父元素之后的元素设置为显示. 二.定义收起函数hidediv(),实现点击"收起全文"按钮,全文内容隐藏. 1.点击收起函数,需要将触发点击事件的按钮作为参数传入 2.通过传入的按钮,查找其父元素,将其父元素设

  • Android实现长按圆环动画View效果的思路代码

    一.需求来源 最近想到一个需求,类似悦跑圈或者Keep的结束按钮动画 二.思路代码 该动画按钮的主要作用就是防止用户误操作,具体实现思路如下: 1.监听用户的触摸事件OnTouchListener,在ACTION_DOWN的时候,记录下xy坐标和触摸时间,同时start自定义View动画:在ACTION_MOVE的过程中,判断坐标差值的偏移量是否在一个可接受的范围内,是的话就保留当前动画,不是的话就清除按钮上绘制的path:在ACTION_UP的时候,再次记录下触摸时间,比较两个时间是否达到了长

  • 一文搞懂Android RecyclerView点击展开、折叠效果的实现代码

    RecyclerView是什么 RecycleView是Android5.0后谷歌推出的一个用于在有限的窗口中展示大量数据集的控件,位于support-v7包中.它可以实现与ListView和GridView一样的效果,提供了一种插拔式的体验,高度的解耦,异常的灵活,只需设置其提供的不同的LayoutManager,ItemAnimator和ItemDecoration,就能实现不同的效果. RecyclerView的优点 1.支持局部刷新.    2.可以自定义item增删时的动画.    3

  • JavaScript实现文字展开和收起效果

    列表式的文字的展开和收起的实现,供大家参考,具体内容如下 需求: 1:当文字超出目标值,则截取目标值,其他隐藏,同时显示"展开"二字和下拉箭头: 2:点击"展开"显示所有文字,同时改为"收起"和上拉箭头 3:如果文字本身就没有超过目标值,则显示所有文字即可 之前想过使用css设置超出多少行隐藏,或者给Li标签设置高度隐藏,但都无法满足以上第三条,所以想到了下边一种方法将就可以使用 思路: 1:初始遍历需要展开和收起的元素,超出目标值隐藏,然后把所

  • Android背景图下拉回弹效果实例

    目录 Android实现背景图下拉回弹效果 效果 实现 总结 Android实现背景图下拉回弹效果 增加设置不横向拉伸时增加回弹效果 增加切换横屏时可滑动效果 效果 实现 public class HeadZoomScrollView extends NestedScrollView { public HeadZoomScrollView(Context context) { super(context); } public HeadZoomScrollView(Context context,

  • Android开发实现ListView点击展开收起效果示例

    本文实例讲述了Android开发实现ListView点击展开收起效果.分享给大家供大家参考,具体如下: 废话不说先上效果: 实际上这是采用一个ExpandableListView实现的 布局文件很简单: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xm

  • Android仿微博加载长图滚动查看效果

    本文实例为大家分享了Android加载长图片的具体代码,供大家参考,具体内容如下 解决步骤 1.将图片缩放到与控件等宽 2.判断缩放后的图片高度,如果高度大于控件高度较多(这里设置的是1.5倍),认定为长图,可滑动查看图片                      |-如果高度小于控件高度的1.5倍,以控件高度为基准,重新缩放图片 package org.wandcf_ces.fairproject.widgets; import android.annotation.TargetApi; im

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

    背景介绍 在某些特定场景下,我们需要考虑加载长图的需求,比如加载一幅<清明上河图>,这个好像有点过分了,那就加载1/2的<清明上河图>吧... 那TMD还不是一样道理. 言归正传说一下我这边遇到的情况,之前有图片或大图的模块是划分为H5来实现的,现在需求变更划分为原生开发,那么问题就来了. 图片尺寸为 图片大小为 这一刻我是懵逼的,哪个端图片上传的时候没限制尺寸和压缩?mdzz, 吐槽归吐槽,还是要撸起袖子解决加载长图大图的问题. 先提供几个技术方案来对比一下: 方案1:WebVi

  • Android实现分享长图并且添加全图水印

    Android实现分享长图并且添加全图水印 前言: 长图一般是ScrollView和ListView. 我们需要取得这两个控件的完整显示的图片.原理很简单,搞一张和控件长宽一致的画布(就是创建一个高宽相等的bitmap).然后调用控件的draw方法把自己画到画布上去. 分别贴出两个控件的长图获取方法 /** * 截取scrollview的屏幕 **/ public static Bitmap getScrollViewBitmap(ScrollView scrollView) { int h =

随机推荐