ImageViewhtml
ImageView,圖像視圖,直接繼承自View類,它的主要功能是用於顯示圖片,實際上它不只僅能夠用來顯示圖片,任何Drawable對象均可以使用ImageView來顯示。ImageView能夠適用於任何佈局中,而且Android爲其提供了縮放和着色的一些操做。java
ImageView的一些經常使用屬性,而且這些屬性都有與之對應的getter、setter方法:android
android:adjustViewBounds:設置ImageView是否調整本身的邊界來保持所顯示圖片的長寬比。網絡
android:maxHeight:設置ImageView的最大高度。多線程
android:maxWidth:設置ImageView的最大寬度。app
android:scaleType:設置所顯示的圖片如何縮放或移動以適應ImageView的大小。dom
android:src:設置ImageView所顯示的Drawable對象的ID。ide
對於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 <ImageView13 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 <TextView21 android:layout_width="match_parent"22 android:layout_height="wrap_content"23 android:text="scaleType:fitCenter,按比例縮放" />24 25 <ImageView26 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 <TextView15 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 <SeekBar22 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 <TextView30 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 <SeekBar37 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 implements20 OnSeekBarChangeListener {21 private int minWidth = 80;22 private ImageView imageView;23 private TextView textview1, textview2;24 Matrix matrix=new Matrix();25 26 @Override27 protected void onCreate(Bundle savedInstanceState) {28 // TODO Auto-generated method stub29 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 @Override48 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 @Override70 public void onStartTrackingTouch(SeekBar seekBar) {71 // TODO Auto-generated method stub72 73 }74 75 @Override76 public void onStopTrackingTouch(SeekBar seekBar) {77 // TODO Auto-generated method stub78 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 @Override28 protected void onCreate(Bundle savedInstanceState) {29 // TODO Auto-generated method stub30 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 @Override40 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 @Override58 public void onClick(View v) {59 //清空以前獲取的數據60 tvMsgType.setText("");61 ivInternet.setImageBitmap(null);62 //定義一個線程類63 new Thread() {64 @Override65 public void run() {66 try {67 //獲取網絡圖片68 InputStream inputStream = HttpUtils69 .getImageViewInputStream();70 Bitmap bitmap = BitmapFactory71 .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) url19 .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項目而言,通常的用到更多的就是從網絡獲取圖片的功能,因此這裏着重講解了一下。