Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> Android開發實例 >> Android應用開發入門(二十三)UI控件ImageView的使用

Android應用開發入門(二十三)UI控件ImageView的使用

編輯: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如果不了解的話,可以參見我的另外一篇,http://www.fengfly.com/plus/view-213382-1.html。這兩個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.  

  效果展示:

從互聯網獲取圖片

  一個移動的平台開發,很多資源是不可能一直保存在本地的,更多實時性的東西,是需要直接通過網絡及時獲取的。這裡通過一個從網上獲取圖片展示到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中訪問網絡不熟悉的朋友,可以參見我另外一篇,http://www.fengfly.com/plus/view-213370-1.html。

  布局代碼:

  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.     }  

  訪問網絡類,代碼:

  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.     }  

 效果展示:

  示例代碼下載

總結

  以上就講解了ImageView的一些基本使用,對於Android項目而言,一般的用到更多的就是從網絡獲取圖片的功能,所以這裡著重講解了一下。

 

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved