Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android:ImageView

Android:ImageView

編輯:關於Android編程

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的資源文件,以後再進行詳解。

布局代碼:




    

    

    

    

以下設定圖片大小
android:layout_width=”300dp”
android:layout_height=”200dp”

效果展示:
這裡寫圖片描述

縮放與旋轉圖片

  因為ImageView繼承自View,所以在代碼中設置其大小,可以使用View.setLayoutParams(new LinearLayout.LayoutParams(newWidth,newHeight))方法,這個方法可以直接設定View下的所有控件的外觀大小,所以這裡也適用於ImageView。
  要是RelativeLayout就要相應地使用View.setLayoutParams(new RelativeLayout.LayoutParams(newWidth,newHeight)); 這樣設置其大小屬性。

  而對於ImageView的旋轉,這裡涉及到一個Matrix類的使用。它表示一個3x3的坐標變換矩陣,可以在這個矩陣內,對其進行變換、旋轉操作,它需要通過構造函數顯式的初始化之後才可以使用。

  下面通過一個示例來說明一下圖片的放大縮小與旋轉的示例,在示例中會提供兩個SeekBar,對於SeekBar如果不了解的話,可以參見我的另外一篇博客,Android—UI之Progress。這兩個SeekBar一個設置ImageView顯示圖片的大小,另一個設置旋轉的角度。對於圖片大小,通過DisplayMetrics設置屏幕的寬度為圖像的最大寬度,具體操作在注釋中已經寫明,這裡不在累述。

  布局代碼:




    

    

    

    

    

實現代碼:

package com.bgxt.imageviewdemo;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.graphics.drawable.BitmapDrawable;
import android.os.Bundle;
import android.util.DisplayMetrics;

import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TextView;

@SuppressLint("NewApi")
public class ChangeImageActivity extends Activity implements
        OnSeekBarChangeListener {
    private int minWidth = 80;
    private ImageView imageView;
    private TextView textview1, textview2;
    Matrix matrix=new Matrix();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.layout_changeimage);

        imageView = (ImageView) findViewById(R.id.imageview3);
        SeekBar seekbar1 = (SeekBar) findViewById(R.id.sbSize);
        SeekBar seekbar2 = (SeekBar) findViewById(R.id.sbRotate);
        textview1 = (TextView) findViewById(R.id.tv1);
        textview2 = (TextView) findViewById(R.id.tv2);

        //獲取當前屏幕的尺寸,並設置圖片放大的最大尺寸,不能超過屏幕尺寸
        DisplayMetrics dm = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(dm);
        seekbar1.setMax(dm.widthPixels - minWidth);

        seekbar1.setOnSeekBarChangeListener(this);
        seekbar2.setOnSeekBarChangeListener(this);        
    }

    @Override
    public void onProgressChanged(SeekBar seekBar, int progress,
            boolean fromUser) {
        if (seekBar.getId() == R.id.sbSize) {
            //設置圖片的大小
            int newWidth=progress+minWidth;
            int newHeight=(int)(newWidth*3/4);
            imageView.setLayoutParams(new LinearLayout.LayoutParams(newWidth, newHeight));
            textview1.setText("圖像寬度:"+newWidth+"圖像高度:"+newHeight);
        } else if (seekBar.getId() == R.id.sbRotate){
            //獲取當前待旋轉的圖片
            Bitmap bitmap=BitmapFactory.decodeResource(getResources(), R.drawable.green);
            //設置旋轉角度
            matrix.setRotate(progress,30,60);
            //通過待旋轉的圖片和角度生成新的圖片
            bitmap=Bitmap.createBitmap(bitmap,0,0,bitmap.getWidth(),bitmap.getHeight(),matrix,true);
            //綁定圖片到控件上
            imageView.setImageBitmap(bitmap);
            textview2.setText(progress+"°");
        }
    }

    @Override
    public void onStartTrackingTouch(SeekBar seekBar) {
        // TODO Auto-generated method stub

    }

    @Override
    public void onStopTrackingTouch(SeekBar seekBar) {
        // TODO Auto-generated method stub
    }
}

效果展示:
這裡寫圖片描述這裡寫圖片描述這裡寫圖片描述

從互聯網獲取圖片

一個移動的平台開發,很多資源是不可能一直保存在本地的,更多實時性的東西,是需要直接通過網絡及時獲取的。這裡通過一個從網上獲取圖片展示到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協議。

  布局代碼:


實現代碼:

package com.bgxt.imageviewdemo;

import java.io.InputStream;
import java.net.HttpURLConnection;
import java.util.Random;

import com.bgxt.httputils.HttpUtils;

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

public class InternetImageActivity extends Activity {
    private Button btnInternet;
    private ImageView ivInternet;
    private TextView tvMsgType;
    private Handler handler;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_internetimage);

        btnInternet = (Button) findViewById(R.id.btnInternet);
        ivInternet = (ImageView) findViewById(R.id.ivInternet);
        tvMsgType = (TextView) findViewById(R.id.tbMsgType);

        // 定義一個handler,用於接收消息
        handler = new Handler() {
            @Override
            public void handleMessage(Message msg) {
                Bitmap bmp = null;
                // 通過消息碼確定使用什麼方式傳遞圖片信息
                if (msg.what == 0) {
                    bmp = (Bitmap) msg.obj;
                    tvMsgType.setText("使用obj傳遞數據");
                } else {
                    Bundle ble = msg.getData();
                    bmp = (Bitmap) ble.get("bmp");
                    tvMsgType.setText("使用Bundle傳遞數據");
                }
                // 設置圖片到ImageView中
                ivInternet.setImageBitmap(bmp);
            }
        };

        btnInternet.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //清空之前獲取的數據
                tvMsgType.setText("");
                ivInternet.setImageBitmap(null);
                //定義一個線程類
                new Thread() {
                    @Override
                    public void run() {
                        try {
                            //獲取網絡圖片
                            InputStream inputStream = HttpUtils
                                    .getImageViewInputStream();
                            Bitmap bitmap = BitmapFactory
                                    .decodeStream(inputStream);
                            Message msg = new Message();
                            Random rd = new Random();
                            int ird = rd.nextInt(10);
                            //通過一個隨機數,隨機選擇通過什麼方式傳遞圖片信息到消息中
                            if (ird / 2 == 0) {
                                msg.what = 0;
                                msg.obj = bitmap;
                            } else {
                                Bundle bun = new Bundle();
                                bun.putParcelable("bmp", bitmap);
                                msg.what = 1;
                                msg.setData(bun);
                            }
                            //發送消息
                            handler.sendMessage(msg);
                        } catch (Exception e) {

                        }
                    }
                }.start();
            }
        });
    }
}

訪問網絡類,代碼:

package com.bgxt.httputils;

import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;

public class HttpUtils {
    private final static String URL_PATH = "http://ww4.sinaimg.cn/bmiddle/9e58dccejw1e6xow22oc6j20c80gyaav.jpg";

    public HttpUtils() {
    }

    public static InputStream getImageViewInputStream() throws IOException {
        InputStream inputStream = null;
        URL url = new URL(URL_PATH);
        if (url != null) {
            HttpURLConnection httpURLConnection = (HttpURLConnection) url
                    .openConnection();
            httpURLConnection.setConnectTimeout(3000);
            httpURLConnection.setRequestMethod("GET");
            httpURLConnection.setDoInput(true);
            int response_code = httpURLConnection.getResponseCode();
            if (response_code == 200) {
                inputStream = httpURLConnection.getInputStream();
            }
        }
        return inputStream;
    }
}

效果展示:
這裡寫圖片描述這裡寫圖片描述這裡寫圖片描述

ImageView的Animation

mSplashItem_iv = (ImageView) findViewById(R.id.splash_loading_item);//獲取圖片路徑轉成ImageView
...
//在anim目錄添加,splash_loading.xml文件,文件內容看後面
//這裡調用loadAnimation函數加載動畫相關的xml文件。
Animation translate = AnimationUtils.loadAnimation(this,
                R.anim.splash_loading);
...
//設置動畫播放的幾個回調函數
translate.setAnimationListener(new AnimationListener() {
            @Override
            public void onAnimationStart(Animation animation) {
                // TODO Auto-generated method stub

            }
            @Override
            public void onAnimationRepeat(Animation animation) {
                // TODO Auto-generated method stub
            }
            @Override
            public void onAnimationEnd(Animation animation) {
                // TODO Auto-generated method stub
                openActivity(HomeActivity.class);
                overridePendingTransition(R.anim.push_left_in,
                        R.anim.push_left_out);
                SplashActivity.this.finish();
            }
        });     
...
//開始動畫!!
mSplashItem_iv.setAnimation(translate);

動畫相關的xml文件,放在anim目錄下:


這個例子只是單純移動一段距離的動畫。還有其他很多,需要另外專門看看動畫相關的設置!

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