`
yanghaoli
  • 浏览: 288426 次
社区版块
存档分类
最新评论

Android

 
阅读更多

前言

这篇博客聊一聊在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项目而言,一般的用到更多的就是从网络获取图片的功能,所以这里着重讲解了一下。

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

0
1
分享到:
评论

相关推荐

    android 经典代码例子

    在Android开发领域,经典代码例子是开发者学习和提升技能的重要资源。这些例子涵盖了各种关键功能和组件的实现,有助于深入理解Android应用的工作原理。在这个压缩包中,我们可能找到了多个有关Android编程的示例...

    Android开发入门60个小案例+源代码

    在Android开发领域,初学者经常会面临许多挑战,如理解Android应用程序的基本架构、学习XML布局、掌握Java或Kotlin编程语言,以及如何与设备硬件交互等。"Android开发入门60个小案例+源代码"这个资源提供了丰富的...

    Android省市区三级联动滚轮选择——Cascade_Master

    该组件是基于开源库`Android-wheel`实现的,`Android-wheel`是一个适用于Android的滚轮选择器,它可以创建类似于iOS中PickerView的效果,让用户通过滚动来选取所需的数据。在省市区三级联动中,当用户在一级(省)...

    Android自定义日期选择器源码

    在Android开发中,系统默认的日期和时间选择器虽然实用,但往往无法满足所有场景的需求。因此,开发者经常需要自定义日期选择器来提供更符合应用风格或特定功能的交互体验。这篇内容将深入探讨如何在Android中创建一...

    Android通过webservice连接Sqlserver实例

    在Android开发中,有时我们需要与远程数据库进行交互,例如SQLServer。这个场景通常是通过Web服务,如WebService来实现。本文将详细介绍如何在Android应用中利用WebService接口连接到SQLServer数据库,实现数据的增...

    Android串口通信(Android Studio)

    在Android开发中,串口通信(Serial Port Communication)是一种重要的技术,它允许设备之间通过串行接口进行数据交换。在Android Studio环境下实现串口通信,开发者可以构建与硬件设备交互的应用,例如读取传感器...

    Android设置虚线、圆角、渐变

    在Android开发中,为UI元素添加虚线、圆角和渐变效果是常见的需求,可以提升应用的视觉吸引力。下面将详细讲解如何实现这些效果。 ### 一、虚线(Dashed Line) 在Android中,我们可以使用`Shape Drawable`来创建...

    Android组件设计思想

    Android应用开发的哲学是把一切都看作是组件。把应用程序组件化的好处是降低模块间的耦合性,同时提高模块的复用性。Android的组件设计思想与传统的组件设计思想最大的区别在于,前者不依赖于进程。也就是说,进程...

    新版Android开发教程.rar

    ----------------------------------- Android 编程基础 1 封面----------------------------------- Android 编程基础 2 开放手机联盟 --Open --Open --Open --Open Handset Handset Handset Handset Alliance ...

    Android 完美实现图片圆角和圆形

    在Android开发中,有时我们需要对显示的图片进行特殊处理,比如让图片呈现圆角或完全圆形。本知识点将深入探讨如何在Android应用中完美实现图片的圆角和圆形效果。 首先,我们来看如何实现图片的圆角效果。Android...

    Android.bp文件说明.pdf

    Android新编译规则Android.bp文件语法规则详细介绍,条件编译的配置案例。 Android.bp 文件首先是 Android 系统的一种编译配置文件,是用来代替原来的 Android.mk 文件的。在 Android7.0 以前,Android 都是使用 ...

    JS调用Android方法,向Android方法传递json数据

    在现代的移动应用开发中,JavaScript与原生平台之间的交互变得越来越常见,特别是在使用Android的WebView组件时。本文将深入探讨如何使用JavaScript调用Android的方法,并传递JSON数据,以实现两者之间的高效通信。 ...

    Android扫雷游戏(基于Android Studio)

    【Android扫雷游戏开发详解】 在移动开发领域,Android Studio是Google推出的官方集成开发环境(IDE),用于构建Android应用程序。本项目"Android扫雷游戏"就是利用Android Studio进行开发的一个实例,旨在帮助初学...

    android应用开发范例精解

    第2篇为应用开发篇,通过实例介绍了Android UI布局、Android人机界面、手机硬件设备的使用、Android本地存储系统、Android中的数据库、多线程设计、Android传感器、Android游戏开发基础、Android与Internet,以及...

    android 仿微信语音聊天demo

    【Android 微信语音聊天Demo】是一个典型的移动应用开发示例,主要展示了如何在Android平台上构建类似微信的语音聊天功能。这个Demo包含了按钮状态切换、语音录制、本地存储、回放和加载等一系列关键操作,是Android...

    Android SDK离线包合集(Android 4.0-5.0)

    Android SDK离线包合集(Android 4.0-5.0)。不用去Google下载,直接国内下载离线包,各版本文件独立,任意下载。手机流量上传了一部分,好心疼。如不能下载,请告诉我更新地址。 附上简单教程。 这是Android开发所...

    Android 图片浏览全屏缩放

    在Android开发中,实现图片浏览的全屏缩放效果是一项常见的需求,特别是在社交应用中,如QQ好友动态和微信朋友圈。这种功能不仅需要提供良好的用户体验,还需要考虑性能和内存优化,因为图片通常较大,处理不当可能...

    Android小项目集合100多个

    1. **Android SDK**:Android软件开发工具包(SDK)是开发Android应用的基础,包含了开发、调试和发布应用所需的所有工具,如Android Studio IDE、Java Development Kit(JDK)、模拟器以及各种版本的Android平台库...

Global site tag (gtag.js) - Google Analytics