功能:

自定义 ImageView 设置显示图片,如果图片的宽与高小于控件的宽与高,就将图片设置显示到控件的中央,
如果图片的宽与高有一项大于控件的宽与高,那么就将图片进行缩放显示,两者者是显示在控件的中央效果图:
这里是加载了一个小图片

创建一个自定义的ImageView ,并编写其相关构造方法

public class ScaleImageView extends ImageView  {public ScaleImageView(Context context) {this(context,null);}public ScaleImageView(Context context, AttributeSet attrs) {this(context, attrs,0);}public ScaleImageView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);}

在自定义的ImageView中获取我们所设置的图片

实现 ViewTreeObserver.OnGlobalLayoutListener

在这里,我们可以实现 ViewTreeObserver.OnGlobalLayoutListener这个接口,然后在它的相关实现方法(onGlobalLayout)中进行获取图片的操作

@Overridepublic void onGlobalLayout() {}}

OnGlobalLayoutListener 是ViewTreeObserver的内部类,当一个视图树的布局发生改变时,可以被ViewTreeObserver监听到,
    这是一个注册监听视图树的观察者(observer),在视图树的全局事件改变时得到通知
    需要注意的是OnGlobalLayoutListener可能会被多次触发,因此在得到了高度之后,要将OnGlobalLayoutListener注销掉。

注册与注销OnGlobalLayoutListener

在自定义ImageView中我们可以复写View的两个方法

/*** View出现的时候执行这个方法*/@Overrideprotected void onAttachedToWindow() {super.onAttachedToWindow();//注册OnGlobalLayoutListenergetViewTreeObserver().addOnGlobalLayoutListener(this);}
/*** View从屏幕上消失的时候执行这个方法*/@Overrideprotected void onDetachedFromWindow() {super.onDetachedFromWindow();//注销OnGlobalLayoutListenergetViewTreeObserver().removeOnGlobalLayoutListener(this);}

获取图片信息

//设置只执行一次的判断标识private boolean mOnce = false;//由于我们整个过程都是操作的同一个图片,所以初始加载图片的时候我们只获取一次就可以了@Overridepublic void onGlobalLayout() {//获取加载完后的图片if (!mOnce) {//得到自定义控件的宽与高final int width = getWidth();final int height = getHeight();//得到图片final Drawable drawable = getDrawable();if (drawable == null) {return;}//获取图片的宽与高final int intrinsicHeight = drawable.getIntrinsicHeight();final int intrinsicWidth = drawable.getIntrinsicWidth();mOnce = true;}}

依据获取到的信息设置显示图片

当图片的宽高小于屏幕的宽高时,我们将其显示在控件的中间位置(当然也可以将其进行适当的放大)
    当图片的宽高大于屏幕的宽高时,我们对其进行适当的缩小,并显示在控件的中间位置
    
    由于这里涉及到了图片的相关放大与缩小,所以这里需要使用到Matrix这个类进行图片的相关操作
    
    定义 Matrix 并在构造方法中进行初始化操作

private Matrix mScaleMatrix;mScaleMatrix = new Matrix();
 @Overridepublic void onGlobalLayout() {//获取加载完后的图片if (!mOnce) {//得到控件的宽与高final int width = getWidth();final int height = getHeight();//得到图片,并获取宽与高final Drawable drawable = getDrawable();if (drawable == null) {return;}final int intrinsicHeight = drawable.getIntrinsicHeight();final int intrinsicWidth = drawable.getIntrinsicWidth();//设置缩放比例float scale = 1.0f;//如果图片宽度大于控件宽度,图片高度小于控件高度  图片缩小if (intrinsicWidth > width && intrinsicHeight < height) {scale = intrinsicWidth * 1.0f / width;}//如果图片的高度大于控件的高度,图片的宽度小于控件的宽度  图片缩小if (intrinsicHeight > height && intrinsicWidth < width) {scale = intrinsicHeight * 1.0f / height;}//如果图片的宽与高都大于控件的宽与高 if (intrinsicHeight > height && intrinsicWidth > width) {scale = Math.min(width * 1.0f / intrinsicWidth, height * 1.0f / intrinsicHeight);}//得到初始化时图片需要进行缩放的值mInitScale = scale;//获取将图片移动到控件的中心的坐标int moveX = getWidth() / 2 - intrinsicWidth / 2;int moveY = getHeight() / 2 - intrinsicHeight / 2;//设置图片的平移与缩放mScaleMatrix.postTranslate(moveX, moveY);mScaleMatrix.postScale(mInitScale, mInitScale, getWidth() / 2, getHeight() / 2);setImageMatrix(mScaleMatrix);mOnce = true;}}

走到这里,我们使用这个ImageView就可以适当的加载我们的图片了,当然我们还可以设置一个自定义的属性或者是方法来控制当图片的宽度小于控件的宽度的时候,是否将图片进行适当的放大

自定义属性将图片进行放大操作判断

在res/values/下建立一个attrs.xml文件,在里面定义我们的属性和声明我们的属性和样式

<?xml version="1.0" encoding="utf-8"?>
<resources><attr name="isScaleImage" format="boolean"/><declare-styleable name="ScaleImageView"><attr name="isScaleImage" /></declare-styleable>
</resources>

这样我们定义的属性为boolean类型

接下来就是使用这个自定义属性

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:custom="http://schemas.android.com/apk/res/com.androidlongs.imageviewapplication"android:layout_width="match_parent"android:layout_height="match_parent"><com.androidlongs.imageviewapplication.ScaleAttrsImageViewandroid:scaleType="matrix"android:src="@mipmap/ic_launcher"custom:isScaleImage = "true"android:layout_width="match_parent"android:layout_height="match_parent"/></RelativeLayout>

接下来在我们的自定义Imageview中使用属性

注: 这里是在三个参数的构造中进行初始化操作的,API版本3.0以上才支持

private  boolean isScale = false;public ScaleAttrsImageView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);//获取所有的自定义属性和样式final TypedArray typedArray = context.getTheme().obtainStyledAttributes(attrs, R.styleable.ScaleImageView, defStyleAttr, 0);//获取自定义属性的个数final int indexCount = typedArray.getIndexCount();//获取相关设定的值for (int i = 0; i < indexCount; i++) {final int attr = typedArray.getIndex(i);switch (attr){case  R.styleable.ScaleImageView_isScaleImage:isScale = typedArray.getBoolean(attr,false);}}mMatrix = new Matrix();}

接下来就 是修改我们操作图片并设置图片显示那一块,加一次判断就可以了

@Overridepublic void onGlobalLayout() {....  .... if (isScale&&(intrinsicHeight < height && intrinsicWidth < width)) {scale = Math.min(width * 1.0f / intrinsicWidth, height * 1.0f / intrinsicHeight);}//得到初始化时图片需要进行缩放的值final int moveX = getWidth() / 2 - intrinsicWidth / 2;final int moveY = getHeight() / 2 - intrinsicHeight / 2;mMatrix.postTranslate(moveX, moveY);mMatrix.postScale(scale,scale,getWidth()/2,getHeight()/2);setImageMatrix(mMatrix);mOnce=true;}}

效果图:

这里是加载的小图片,因为设置了属性isScale = "true",那么自定义控件将会在这种情况下对图片进行适当放大的操作

 Android自定义ImageView(二)——实现双击放大与缩小图片 点击打开链接
 Android自定义控件ImageViwe(三)——随手指进行图片的缩放 点击打开链接
Android自定义控件ImageViwe(四)——多点触控实现图片的自由移动  点击打开链接
Android ListView分组排序显示数据 点击打开链接
Android自定义下拉刷新功能的ListView 点击打开链接
Android自定义控件之流式布局 点击打开链接
Android音乐播放器高级开发 点击打开链接
Android自定义下拉刷新功能的ListView 点击打开链接

Android自定义控件ImageViwe(一)——依据控件的大小来设置缩放图片显示相关推荐

  1. android 动态地改变某控件的大小

    android 动态地改变某控件的大小 LinearLayout.LayoutParams params = (LinearLayout.LayoutParams)某控件.getLayoutParam ...

  2. android 自定义控件ondraw,android--------自定义控件 之 方法篇

    前面简单的讲述了Android中自定义控件的理论和流程图,今天通过代码来详细的讲解一下其中的方法 首先先创建一个类 CircularView 继承于 View,之后实现构造方法(初始化步骤) publ ...

  3. Android显示日历的函数,android实现双日期选择控件(可隐藏日,只显示年月)

    在安卓开发中,会碰到选开始日期和结束日期的问题.特别是在使用Pad时,如果弹出一个Dialog,能够同时选择开始日期和结束日期,那将是极好的.我在开发中在DatePickerDialog的基础上做了修 ...

  4. MFC开发IM-自绘按钮控件,给按钮设置背景图片

    MFC 基础知识:对话框背景添加图片和按钮Button添加图片 很长时间没有接触MFC相关的知识了,我大概是在大二时候学习的MFC相关知识及图像处理,现在由于要帮个朋友完成个基于C++的程序,所以又回 ...

  5. Android 自定义控件 ViewPager头部指示器控件 ViewPagerBelowIndicator

    效果 演示 说明 为了实现 ViewPager 切换 Fragment 时的标签效果(类似新闻客户端导航的效果) 代码 package com.demo.view;import android.con ...

  6. android聚焦时如何给控件加边框,edittext设置获得焦点时的边框颜色

    第一步:为了更好的比较,准备两个一模一样的EditText(当Activity启动时,焦点会在第一个EditText上,如果你不希望这样只需要写一个高度和宽带为0的EditText即可避免,这里就不这 ...

  7. android 原理 组合控件_Android自定义控件进阶01-自定义控件开发套路与流程

    Android自定义控件进阶01-自定义控件开发套路与流程本章节为什么要叫进阶篇?(虽然讲的是基础内容),因为从本篇开始,将会逐渐揭开自定义View的神秘面纱,每一篇都将比上一篇内容更加深入,利用所学 ...

  8. android shape 无边框颜色,Android 使用shape定义不同控件的的颜色、背景色、边框色...

    Android 使用shape定义不同控件的的颜色.背景色.边框色 设置按钮的右边框和底边框颜色为红色,边框大小为3dp: 在drawable新建一个 buttonstyle.xml的文件,内容如下: ...

  9. android excel布局,Androidui布局控件(2)表格布局excelPanel

    推荐理由 RecycleView定制组件 支持向左,向右加载过去,未来数据 列行表头锁定 作为表格布局,可以作为您的ui公共组件库里面的一员,你可以二次开发,让它变得更加可定制化,可扩展,更强大 In ...

最新文章

  1. workerman介绍
  2. 大数据将如何重构汽车产业的商业模式?
  3. python3字节转化字符_捋一捋字符串与字节序列的关系
  4. java吃货联盟app讲解_吃货联盟订餐系统——JAVA实现
  5. LoadRunner常用函数(转)
  6. 命令行配置Windows SNMP服务
  7. java中udp的使用
  8. PreferenceFragment和PreferenceActivity
  9. 优化 | 线性化:0-1变量乘以连续变量的线性化
  10. python爬取音乐网站排行榜_使用Python抓取Web端QQ音乐排行榜 批量下载QQ音乐到本地...
  11. soc 设计soc设计 uml实务手册_芯片设计进阶之路——SOC电源管理系统
  12. php 豆瓣抓取,PHP抓取豆瓣读书爬虫代码
  13. openbravo erp介绍(二)
  14. 关于H5版本及说明-为什么优雅草YYC蜻蜓系统H5版本打包不成功以及相关问题
  15. 瑞利熵与拉普拉斯矩阵
  16. [LeetCode][算法初级][数组] 30 有效的数独
  17. 高德地图 搜索店名获取经纬度
  18. 外文版计算机科学期刊,EI(SCI) 收录国外英文期刊(计算机类)
  19. ​​【​观察】萨提亚为微软中国定下主基调 平台价值释放与生态伙伴共赢
  20. 二维码的后台生成及前台界面显示QRCode

热门文章

  1. 30万总奖金·垃圾分类挑战赛进入最后冲刺(附baseline完整分享)
  2. CVPR 2019 论文大盘点—人体姿态篇
  3. 计算机视觉论文-2021-06-30
  4. BBAug: PyTorch的物体检测包
  5. 复旦大学邱锡鹏教授《神经网络与深度学习》最新版!
  6. 数据科学与计算机学院张治国,张治国(河海大学机电工程学院副教授)_百度百科...
  7. Hi3798M V200 SDK文档介绍
  8. 深度学习之主流数据库 | MySQL基础
  9. 重采样和重分类的区别
  10. java抽取注释_JAVA 注解教程(五)注解的提取