前言

  这篇博客聊一聊在Android下ImageView的使用,在此篇博客中,会讲解到ImageView的一些属性的使用,以及ImageView展示图片的放大、缩小、旋转等操作。最后再讲解一下Android4.0项目中最常用的一个功能,从网络获取图片的示例。本文所有讲解均会附上示例代码,并在最后提供源码下载。

ImageView

  ImageView,图像视图,直接继承自View类,它的主要功能是用于显示图片,实际上它不仅仅可以用来显示图片,任何Drawable对象都可以使用ImageView来显示。ImageView可以适用于任何布局中,并且Android为其提供了缩放和着色的一些操作。

  ImageView的一些常用属性,并且这些属性都有与之对应的getter、setter方法:

  • android:adjustViewBounds:设置ImageView是否调整自己的边界来保持所显示图片的长宽比。
  • android:maxHeight:设置ImageView的最大高度。
  • android:maxWidth:设置ImageView的最大宽度。
  • android:scaleType:设置所显示的图片如何缩放或移动以适应ImageView的大小。
  • android:src:设置ImageView所显示的Drawable对象的ID。

  对于android:scaleType属性,因为关于图像在ImageView中的显示效果,所以有如下属性值可以选择:

  • matrix:使用matrix方式进行缩放。
  • fitXY:横向、纵向独立缩放,以适应该ImageView。
  • fitStart:保持纵横比缩放图片,并且将图片放在ImageView的左上角。
  • fitCenter:保持纵横比缩放图片,缩放完成后将图片放在ImageView的中央。
  • fitEnd:保持纵横比缩放图片,缩放完成后将图片放在ImageView的右下角。
  • center:把图片放在ImageView的中央,但是不进行任何缩放。
  • centerCrop:保持纵横比缩放图片,以使图片能完全覆盖ImageView。
  • centerInside:保持纵横比缩放图片,以使得ImageView能完全显示该图片。

图片基本显示

  下面通过一个示例效果,来说明一下ImageView是如何显示图片的,再此示例中,需要使用到一个green.png的图片,需要放到Drawable文件夹下,关于Android的资源文件,以后再进行详解。

  布局代码:

 1 <?xml version="1.0" encoding="utf-8"?>
2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
3 android:layout_width="match_parent"
4 android:layout_height="match_parent"
5 android:orientation="vertical" >
6
7 <TextView
8 android:layout_width="match_parent"
9 android:layout_height="wrap_content"
10 android:text="scaleType:center,未缩放,在ImageView的中心" />
11
12 <ImageView
13 android:id="@+id/imageview1"
14 android:layout_width="200dp"
15 android:layout_height="100dp"
16 android:background="#F00"
17 android:scaleType="center"
18 android:src="@drawable/green" />
19
20 <TextView
21 android:layout_width="match_parent"
22 android:layout_height="wrap_content"
23 android:text="scaleType:fitCenter,按比例缩放" />
24
25 <ImageView
26 android:id="@+id/imageview2"
27 android:layout_width="300dp"
28 android:layout_height="200dp"
29 android:background="#FFF"
30 android:padding="10dp"
31 android:scaleType="fitCenter"
32 android:src="@drawable/green" />
33
34 </LinearLayout>

  效果展示:

  

缩放与旋转图片

  因为ImageView继承自View,所以在代码中设置其大小,可以使用View.setLayoutParams(new LinearLayout.LayoutParams(newWidth,newHeight))方法,这个方法可以直接设定View下的所有控件的外观大小,所以这里也适用于ImageView。

  而对于ImageView的旋转,这里涉及到一个Matrix类的使用。它表示一个3x3的坐标变换矩阵,可以在这个矩阵内,对其进行变换、旋转操作,它需要通过构造函数显式的初始化之后才可以使用。

  下面通过一个示例来说明一下图片的放大缩小与旋转的示例,在示例中会提供两个SeekBar,对于SeekBar如果不了解的话,可以参见我的另外一篇博客,Android—UI之Progress。这两个SeekBar一个设置ImageView显示图片的大小,另一个设置旋转的角度。对于图片大小,通过DisplayMetrics设置屏幕的宽度为图像的最大宽度,具体操作在注释中已经写明,这里不在累述。

  布局代码:

 1 <?xml version="1.0" encoding="utf-8"?>
2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
3 android:layout_width="match_parent"
4 android:layout_height="match_parent"
5 android:orientation="vertical" >
6
7 <ImageView
8 android:id="@+id/imageview3"
9 android:layout_width="200dp"
10 android:layout_height="150dp"
11 android:scaleType="fitCenter"
12 android:src="@drawable/green" />
13
14 <TextView
15 android:id="@+id/tv1"
16 android:layout_width="match_parent"
17 android:layout_height="wrap_content"
18 android:layout_marginTop="10dp"
19 android:text="图像宽度:240 图像高度:150" />
20
21 <SeekBar
22 android:id="@+id/sbSize"
23 android:layout_width="200dp"
24 android:layout_height="wrap_content"
25 android:layout_marginTop="10dp"
26 android:max="240"
27 android:progress="120" />
28
29 <TextView
30 android:id="@+id/tv2"
31 android:layout_width="match_parent"
32 android:layout_height="wrap_content"
33 android:layout_marginTop="10dp"
34 android:text="0°" />
35
36 <SeekBar
37 android:id="@+id/sbRotate"
38 android:layout_width="200dp"
39 android:layout_height="wrap_content"
40 android:layout_marginTop="10dp"
41 android:max="360" />
42
43 </LinearLayout>

  实现代码:

 1 package com.bgxt.imageviewdemo;
2
3 import android.annotation.SuppressLint;
4 import android.app.Activity;
5 import android.graphics.Bitmap;
6 import android.graphics.BitmapFactory;
7 import android.graphics.Matrix;
8 import android.graphics.drawable.BitmapDrawable;
9 import android.os.Bundle;
10 import android.util.DisplayMetrics;
11
12 import android.widget.ImageView;
13 import android.widget.LinearLayout;
14 import android.widget.SeekBar;
15 import android.widget.SeekBar.OnSeekBarChangeListener;
16 import android.widget.TextView;
17
18 @SuppressLint("NewApi")
19 public class ChangeImageActivity extends Activity implements
20 OnSeekBarChangeListener {
21 private int minWidth = 80;
22 private ImageView imageView;
23 private TextView textview1, textview2;
24 Matrix matrix=new Matrix();
25
26 @Override
27 protected void onCreate(Bundle savedInstanceState) {
28 // TODO Auto-generated method stub
29 super.onCreate(savedInstanceState);
30 setContentView(R.layout.layout_changeimage);
31
32 imageView = (ImageView) findViewById(R.id.imageview3);
33 SeekBar seekbar1 = (SeekBar) findViewById(R.id.sbSize);
34 SeekBar seekbar2 = (SeekBar) findViewById(R.id.sbRotate);
35 textview1 = (TextView) findViewById(R.id.tv1);
36 textview2 = (TextView) findViewById(R.id.tv2);
37
38 //获取当前屏幕的尺寸,并设置图片放大的最大尺寸,不能超过屏幕尺寸
39 DisplayMetrics dm = new DisplayMetrics();
40 getWindowManager().getDefaultDisplay().getMetrics(dm);
41 seekbar1.setMax(dm.widthPixels - minWidth);
42
43 seekbar1.setOnSeekBarChangeListener(this);
44 seekbar2.setOnSeekBarChangeListener(this);
45 }
46
47 @Override
48 public void onProgressChanged(SeekBar seekBar, int progress,
49 boolean fromUser) {
50 if (seekBar.getId() == R.id.sbSize) {
51 //设置图片的大小
52 int newWidth=progress+minWidth;
53 int newHeight=(int)(newWidth*3/4);
54 imageView.setLayoutParams(new LinearLayout.LayoutParams(newWidth, newHeight));
55 textview1.setText("图像宽度:"+newWidth+"图像高度:"+newHeight);
56 } else if (seekBar.getId() == R.id.sbRotate){
57 //获取当前待旋转的图片
58 Bitmap bitmap=BitmapFactory.decodeResource(getResources(), R.drawable.green);
59 //设置旋转角度
60 matrix.setRotate(progress,30,60);
61 //通过待旋转的图片和角度生成新的图片
62 bitmap=Bitmap.createBitmap(bitmap,0,0,bitmap.getWidth(),bitmap.getHeight(),matrix,true);
63 //绑定图片到控件上
64 imageView.setImageBitmap(bitmap);
65 textview2.setText(progress+"°");
66 }
67 }
68
69 @Override
70 public void onStartTrackingTouch(SeekBar seekBar) {
71 // TODO Auto-generated method stub
72
73 }
74
75 @Override
76 public void onStopTrackingTouch(SeekBar seekBar) {
77 // TODO Auto-generated method stub
78
79 }
80
81 }

  效果展示:

  

从互联网获取图片

  一个移动的平台开发,很多资源是不可能一直保存在本地的,更多实时性的东西,是需要直接通过网络及时获取的。这里通过一个从网上获取图片展示到ImageView的例子,来讲解一下这个功能的实现。

  在Android4.0之后,增加了一些新特性,也增加了一些限制。其中有一个限制就是不能在主线程中访问网络,必须另开一条线程访问。但是这里又存在另外一个问题,在子线程中,无法直接操作UI控件的属性。如果你们使用的开发平台是Android4.0之下,就不存在这个问题,直接在主线程中访问网络操作UI控件即可。

  我的解决方案就是,通过Thread类,进行多线程访问网络,再通过Handler类,进行消息传递。对于Thread类,是Java的知识,不再详细讲解,对于Handler类,这里简要说明一下。

  在Android平台下,不允许Activity新启动的线程访问该Activity里的界面UI控件,这样就会导致新启动的线程无法动态改变界面UI控件的属性值。所以就需要借助Handler的消息传递机制来实现。Handler类的主要作用有两个:

  • 在新启动的线程中发送消息。
  • 在主线程中获取、处理消息。

  上面描述的两个作用,发送消息好说,在需要的时候发送,那怎么确定什么时候接收消息呢?为了让主线程能接受并处理新启动的线程发送的消息,Android通过回调的方式来实现,开发人员只需要重写Handler类中处理消息的方法,handleMessage(Message)即可,其中Message封装了发送过来的消息。

  Handler包含如下方法,用于实现发送和处理消息:

  • void handleMessage(Message msg):处理消息的方法,用于被重写。
  • final boolean hasMessage(int what):检查消息队列中是否包含what属性为指定值的消息。
  • sendEmptyMessage(int what):立即发送空消息。
  • final boolean sendEmptyMessageDelayed(int what,long delayMillis):指定delayMillis毫秒之后发送空消息。
  • final boolean sendMessage(Message msg):立即发送消息。
  • final boolean sendMessageDelayed(Message msg,long delayMillis):指定delayMillis毫秒之后发送消息。

  Message封装了线程中传递的消息,如果对于一般的数据,Message提供了getData()和setData()方法来获取与设置数据,其中操作的数据是一个Bundle对象,这个Bundle对象提供一系列的getXxx()和setXxx()方法用于传递基本数据类型,对于基本数据类型,使用起来很简单,这里不再详细讲解。而对于复杂的数据类型,如一个对象的传递就要相对复杂一些。在Bundle中提供了两个方法,专门用来传递对象的,但是这两个方法也有相应的限制,需要实现特定的接口,当然,一些Android自带的类,其实已经实现了这两个接口中的某一个,可以直接使用。方法如下:

  • putParcelable(String key,Parcelable value):需要传递的对象类实现Parcelable接口。
  • pubSerializable(String key,Serializable value):需要传递的对象类实现Serializable接口。

  还有另外一种方式在Message中传递对象,那就是使用Message自带的obj属性传值,它是一个Object类型,所以可以传递任意类型的对象,Message自带的有如下几个属性:

  • int arg1:参数一,用于传递不复杂的数据,复杂数据使用setData()传递。
  • int arg2:参数二,用于传递不复杂的数据,复杂数据使用setData()传递。
  • Object obj:传递一个任意的对象。
  • int what:定义的消息码,一般用于确定消息的来源。

  下面这个示例,使用了两种方式获取传递消息,以一个随机数确定。在这个示例中,访问网络的代码会附上但是不会详解,如果对于Android中访问网络不熟悉的朋友,可以参见我另外一篇博客,Android--Http协议。

  布局代码:

 1 <?xml version="1.0" encoding="utf-8"?>
2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
3 android:layout_width="match_parent"
4 android:layout_height="match_parent"
5 android:orientation="vertical" >
6
7
8 <Button android:id="@+id/btnInternet" android:layout_width="wrap_content"
9 android:layout_height="wrap_content" android:text="下载网络图片"/>
10 <TextView android:id="@+id/tbMsgType" android:layout_width="match_parent"
11 android:layout_height="wrap_content"/>
12 <ImageView android:id="@+id/ivInternet" android:layout_width="wrap_content"
13 android:layout_height="wrap_content"/>
14 </LinearLayout>

  实现代码:

 1 package com.bgxt.imageviewdemo;
2
3 import java.io.InputStream;
4 import java.net.HttpURLConnection;
5 import java.util.Random;
6
7 import com.bgxt.httputils.HttpUtils;
8
9 import android.app.Activity;
10 import android.graphics.Bitmap;
11 import android.graphics.BitmapFactory;
12 import android.os.Bundle;
13 import android.os.Handler;
14 import android.os.Message;
15 import android.view.View;
16 import android.widget.Button;
17 import android.widget.ImageView;
18 import android.widget.TextView;
19 import android.widget.Toast;
20
21 public class InternetImageActivity extends Activity {
22 private Button btnInternet;
23 private ImageView ivInternet;
24 private TextView tvMsgType;
25 private Handler handler;
26
27 @Override
28 protected void onCreate(Bundle savedInstanceState) {
29 // TODO Auto-generated method stub
30 super.onCreate(savedInstanceState);
31 setContentView(R.layout.activity_internetimage);
32
33 btnInternet = (Button) findViewById(R.id.btnInternet);
34 ivInternet = (ImageView) findViewById(R.id.ivInternet);
35 tvMsgType = (TextView) findViewById(R.id.tbMsgType);
36
37 // 定义一个handler,用于接收消息
38 handler = new Handler() {
39 @Override
40 public void handleMessage(Message msg) {
41 Bitmap bmp = null;
42 // 通过消息码确定使用什么方式传递图片信息
43 if (msg.what == 0) {
44 bmp = (Bitmap) msg.obj;
45 tvMsgType.setText("使用obj传递数据");
46 } else {
47 Bundle ble = msg.getData();
48 bmp = (Bitmap) ble.get("bmp");
49 tvMsgType.setText("使用Bundle传递数据");
50 }
51 // 设置图片到ImageView中
52 ivInternet.setImageBitmap(bmp);
53 }
54 };
55
56 btnInternet.setOnClickListener(new View.OnClickListener() {
57 @Override
58 public void onClick(View v) {
59 //清空之前获取的数据
60 tvMsgType.setText("");
61 ivInternet.setImageBitmap(null);
62 //定义一个线程类
63 new Thread() {
64 @Override
65 public void run() {
66 try {
67 //获取网络图片
68 InputStream inputStream = HttpUtils
69 .getImageViewInputStream();
70 Bitmap bitmap = BitmapFactory
71 .decodeStream(inputStream);
72 Message msg = new Message();
73 Random rd = new Random();
74 int ird = rd.nextInt(10);
75 //通过一个随机数,随机选择通过什么方式传递图片信息到消息中
76 if (ird / 2 == 0) {
77 msg.what = 0;
78 msg.obj = bitmap;
79 } else {
80 Bundle bun = new Bundle();
81 bun.putParcelable("bmp", bitmap);
82 msg.what = 1;
83 msg.setData(bun);
84 }
85 //发送消息
86 handler.sendMessage(msg);
87 } catch (Exception e) {
88
89 }
90 }
91 }.start();
92 }
93 });
94 }
95 }

  访问网络类,代码:

 1 package com.bgxt.httputils;
2
3 import java.io.IOException;
4 import java.io.InputStream;
5 import java.net.HttpURLConnection;
6 import java.net.URL;
7
8 public class HttpUtils {
9 private final static String URL_PATH = "http://ww4.sinaimg.cn/bmiddle/9e58dccejw1e6xow22oc6j20c80gyaav.jpg";
10
11 public HttpUtils() {
12 }
13
14 public static InputStream getImageViewInputStream() throws IOException {
15 InputStream inputStream = null;
16 URL url = new URL(URL_PATH);
17 if (url != null) {
18 HttpURLConnection httpURLConnection = (HttpURLConnection) url
19 .openConnection();
20 httpURLConnection.setConnectTimeout(3000);
21 httpURLConnection.setRequestMethod("GET");
22 httpURLConnection.setDoInput(true);
23 int response_code = httpURLConnection.getResponseCode();
24 if (response_code == 200) {
25 inputStream = httpURLConnection.getInputStream();
26 }
27 }
28 return inputStream;
29 }
30 }

  效果展示:

总结

  以上就讲解了ImageView的一些基本使用,对于Android项目而言,一般的用到更多的就是从网络获取图片的功能,所以这里着重讲解了一下。

  请支持原创,尊重原创,转载请注明出处。谢谢。

作者:承香墨影
更多内容,请阅读本人新书:《Android深入浅出》
欢迎转载,但还请尊重劳动果实,保留此段声明并注明原文链接。

(转)Android--UI之ImageView的更多相关文章

  1. Android UI系列-----ImageView的scaleType属性

    这篇随笔将会简单的记录下ImageView这个控件的一些使用方法,以及其最重要的一个属性: scaleType ImageView这个控件是用来显示图片用的,例如我们可以通过下面这段xml配置来声明显 ...

  2. Android UI 绘制过程浅析(五)自定义View

    前言 这已经是Android UI 绘制过程浅析系列文章的第五篇了,不出意外的话也是最后一篇.再次声明一下,这一系列文章,是我在拜读了csdn大牛郭霖的博客文章<带你一步步深入了解View> ...

  3. Android UI线程和非UI线程

    Android UI线程和非UI线程 UI线程及Android的单线程模型原则 当应用启动,系统会创建一个主线程(main thread). 这个主线程负责向UI组件分发事件(包括绘制事件),也是在这 ...

  4. Android UI组件----ListView列表控件详解

    [声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/3 ...

  5. 十二、Android UI开发专题(转)

    http://dev.10086.cn/cmdn/bbs/viewthread.php?tid=18736&page=1#pid89255Android UI开发专题(一) 之界面设计 近期很 ...

  6. Android UI基础教程 目录

    从csdn下载了这本英文版的书之后,又去京东搞了一个中文目录下来.对照着看. 话说,这本书绝对超值.有money的童鞋看完英文版记得去买中文版的~~ Android UI基础教程完整英文版 pdf+源 ...

  7. [转]Android UI:看看Google官方自定义带旋转动画的ImageView-----RotateImageView怎么写(附 图片淡入淡出效果)

    http://blog.csdn.net/yanzi1225627/article/details/22439119 众所周知,想要让ImageView旋转的话,可以用setRotation()让其围 ...

  8. shape和selector是Android UI设计中经常用到的

    shape和selector是Android UI设计中经常用到的,比如我们要自定义一个圆角Button,点击Button有些效果的变化,就要用到shape和selector.可以这样说,shape和 ...

  9. Android UI - 实现广告Banner旋转木马效果

    Android UI - 实现广告Banner旋转木马效果 前言 本篇博客要分享的一个效果是实现广告Banner轮播效果,这个效果也比較常见,一些视频类应用就常常有,就拿360影视大全来举例吧: 用红 ...

  10. 【转】【Android UI设计与开发】第07期:底部菜单栏(二)Fragment的详细介绍和使用方法

    原始地址:http://blog.csdn.net/yangyu20121224/article/category/1431917/1 由于TabActivity在Android4.0以后已经被完全弃 ...

随机推荐

  1. AC日记——爱改名的小融3 codevs 3156

    3156 爱改名的小融 3  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 黄金 Gold 题解       题目描述 Description Wikioi上有个人叫小融,他喜 ...

  2. 牛客网 牛客练习赛11 A.假的线段树

    看不懂题意,而且太菜,写了两道就溜了... A.假的线段树 链接:https://www.nowcoder.com/acm/contest/59/A来源:牛客网 时间限制:C/C++ 1秒,其他语言2 ...

  3. LA 2995 Image Is Everything

    题目链接: https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show ...

  4. 遇到的cannot find module 'xxx' 问题

    昨天配置新项目的环境,明明都npm inatsll都安装了,再次运行的时候一直报错,缺少模块.我以为就一个没安装上,就手动npm install -g 'xxx' :结果一个装好了,又继续蹦出cann ...

  5. java基础第三篇

    6.Java 中的容器(重点) a.变量:变量是一个容器,它存储的单个值 //int i=3; 1.局部变量:定义在方法中,没有默认值 2.成员变量:定义在类中方法外,这个事物的属性(特征)定义为成员 ...

  6. IOS 教你玩转UITableViewController和TableView

    iphone和Ipad开发中UITableViewController和TableView应该是用得比較多得控件. 可是你是会由于写这些控件写得多了而厌烦. 全部怎么让这个控件一直能用.怎么让这个控件 ...

  7. 【Todo】各种语言里面的for循环 & loop

    会的语言多了,不同语言的语法就会混淆.整理了一下. Java里面: 普通的for循环之外: 有以下格式: for (int x : intarr) { } JS里面: }; for (x in per ...

  8. mycat安装和测试

    mycat安装和测试 一.  环境准备 本机环境是三台centos6.5 IP 主机名 数据库名 安装软件 192.168.17.4 master db1 mycat,mysql 192.168.17 ...

  9. Git以及github的使用方法(五),暂存区和工作区

    Git和其他版本控制系统如SVN的一个不同之处就是有暂存区的概念. 先来看名词解释. 工作区(Working Directory) 就是你在电脑里能看到的目录,比如我的learngit文件夹就是一个工 ...

  10. 百度地图 创建 自定义控件(vue)

    1.组件代码 Bmap.vue <!-- 离线地图 组件 --> <template> <div id="map" :style="styl ...