Android—ImageView的使用

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能完全显示该图片。

图片基本显示
布局代码:

<?xml version="1.0" encoding="utf-8"?>
     <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         android:orientation="vertical" >

         <TextView
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:text="scaleType:center,未缩放,在ImageView的中心" />

         <ImageView
             android:id="@+id/imageview1"
             android:layout_width="200dp"
             android:layout_height="100dp"
             android:background="#F00"
             android:scaleType="center"
             android:src="@drawable/erha" />

         <TextView
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:text="scaleType:fitCenter,按比例缩放" />

         <ImageView
             android:id="@+id/imageview2"
             android:layout_width="300dp"
             android:layout_height="200dp"
             android:background="#FFF"
             android:padding="10dp"
             android:scaleType="fitCenter"
             android:src="@drawable/erha" />

</LinearLayout>

效果图:
这里写图片描述

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

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

  下面通过一个示例来说明一下图片的放大缩小与旋转的示例,在示例中会提供两个SeekBar,这两个SeekBar一个设置ImageView显示图片的大小,另一个设置旋转的角度。对于图片大小,通过DisplayMetrics设置屏幕的宽度为图像的最大宽度,具体操作在注释中已经写明,这里不在赘述。

布局代码:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <ImageView
        android:id="@+id/imageview3"
        android:layout_width="200dp"
        android:layout_height="150dp"
        android:scaleType="fitCenter"
        android:src="@drawable/erha" />

    <TextView
        android:id="@+id/tv1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:text="图像宽度:240 图像高度:150" />

    <SeekBar
        android:id="@+id/sbSize"
        android:layout_width="200dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:max="240"
        android:progress="120" />

    <TextView
        android:id="@+id/tv2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:text="0°" />

    <SeekBar
        android:id="@+id/sbRotate"
        android:layout_width="200dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:max="360" />

</LinearLayout>

实现代码:

package com.turo.imageviewtest;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.DisplayMetrics;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.SeekBar;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity implements SeekBar.OnSeekBarChangeListener{

    private int minWidth = 80;
    private ImageView imageView;
    private TextView textview1, textview2;
    Matrix matrix=new Matrix();


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        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 b) {
        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.erha);
            //设置旋转角度
            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) {

    }

    @Override
    public void onStopTrackingTouch(SeekBar seekBar) {

    }
}

效果图:
这里写图片描述

从互联网获取图片
在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:定义的消息码,一般用于确定消息的来源。

下面这个示例,使用了两种方式获取传递消息,以一个随机数确定。

布局代码:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <Button android:id="@+id/btnInternet"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="下载网络图片"/>

    <TextView android:id="@+id/tbMsgType"
              android:layout_width="match_parent"
              android:layout_height="wrap_content"/>

    <ImageView android:id="@+id/ivInternet"
               android:layout_width="wrap_content"
               android:layout_height="wrap_content"/>
</LinearLayout>

实现代码:

package com.turo.imageviewtest;

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 java.io.InputStream;
import java.util.Random;

public class MainActivity extends Activity {

    private Button btnInternet;
    private ImageView ivInternet;
    private TextView tvMsgType;
    private Handler handler;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

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

        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.turo.imageviewtest;

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

/**
 * Created by YQ950209 on 2016/10/23.
 */
public class HttpUtils {
    private final static String URL_PATH = "http://ww4.sinaimg.cn/bmiddle/9e58dccejw1e6xow22oc6j20c80gyaav.jpg";

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

}

最后记得在Androidmanifest.xml文件中加上:

<uses-permission android:name="android.permission.INTERNET"></uses-permission>

效果图:
这里写图片描述

猜你喜欢

转载自blog.csdn.net/turodog/article/details/52901120