前言

Hi,喜欢每天练习的小伙伴肯定对上一篇的Button了如指掌了,那么今天我们为大家带来了ImageView控件,这个控件能与Button碰撞出什么样的火花呢?话不多说,让我们赶紧开始学习吧~

简介

ImageView的结构

public class ImageViewextends View

java.lang.Object↳ android.view.View↳ android.widget.ImageView

已知直接子类:

ImageButtonQuickContactBadge

已知间接子类:

ZoomButton

ImageView(图像视图),直接继承自View类,它的主要功能是用于显示图片,实际上它不仅仅可以用来显示图片,任何Drawable对象都可以使用ImageView来显示。ImageView可以适用于任何布局中,并且Android为其提供了缩放和着色的一些操作。

一. 简单使用

下面我们简单的介绍ImageView的使用(再此示例中,需要使用到一个ic_luffy.png的图片,需要放到res文件夹下drawable文件夹中):

Android控件之ImageView(一)-LMLPHP

  • android:src:设置ImageView所显示的Drawable对象的ID。

而我们也可以通过代码设置图像,运行后的结果和上述中一样:

/**
 * @author: 下码看花
 * date: 2019年8月16日
 * description: ImageView的使用
 */
public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ImageView ivPic = findViewById(R.id.iv_picture);
        ivPic.setImageResource(R.drawable.ic_luffy);
    }
}

部分小伙伴看完后可能会有点儿好奇,我随便写一个Layout再设置一个android:background属性也可以做到展示图片,为什么还要特地去使用ImageView呢?这就不得不要说一下android:src属性和android:background的区别了:

在API文档中我们发现ImageView有两个可以设置图片的属性(任意继承自View的控件都包含background属性),分别是:src和background

常识:

android:background通常指的都是背景,而android:src指的是内容!!

②当使用android:src填入图片时,是按照图片大小直接填充,并不会进行拉伸

而使用android:background填入图片,则是会根据ImageView给定的宽度来进行拉伸

让我们看一个示例:

Android控件之ImageView(一)-LMLPHP

我们将图片的宽高属性设置为固定值,并且给图片增加background属性,我们可以直观的发现,第一张图片明显出现了拉伸,而第二张图片未出现变化,验证上述结论的正确性。

ImageView还有很多有趣的属性:

  • android:maxHeight:设置ImageView的最大高度;
  • android:maxWidth:设置ImageView的最大宽度;
  • android:adjustViewBounds:设置ImageView是否调整自己的边界来保持所显示图片的长宽比,需要结合android:maxWidthandroid:maxHeight一起使用否则单独使用没有效果,并且设置layout_widthlayout_heightwrap_content
  • android:scaleType:设置所显示的图片如何缩放或移动以适应ImageView的大小。

对于android:scaleType属性,因为关于图像在ImageView中的显示效果,所以有如下属性值可以选择:

  • matrix:使用matrix方式进行缩放。
  • fitXY:横向、纵向独立缩放,以适应该ImageView
  • fitStart:保持纵横比缩放图片,并且将图片放在ImageView的左上角;
  • fitCenter:保持纵横比缩放图片,缩放完成后将图片放在ImageView的中央;
  • fitEnd:保持纵横比缩放图片,缩放完成后将图片放在ImageView的右下角;
  • center:把图片放在ImageView的中央,但是不进行任何缩放;
  • centerCrop:保持纵横比缩放图片,以使图片能完全覆盖ImageView;
  • centerInside:保持纵横比缩放图片,以使得ImageView能完全显示该图片;

上述的几个属性小编就不给大家做具体展示了,希望各位小伙伴可以自主尝试。

二. 加载SD卡中的图片

在上述中,只是简单的介绍加载资源文件中的图片以及ImageView的一些基本属性,接下来,我们为大家讲解如何加载SD卡中的图片,并且我们考虑到部分小伙伴对Android很感兴趣,但是都是使用自己的手机来进行调试,那么如何让自己手机中的照片展示到实际项目,赶紧继续往下看吧!

首先,我们开发者要知道,从Android 6.0(API 23)开始,对系统权限做了很大的改变。在之前用户安装APP前,只是把APP需要使用的权限列出来给用户告知一下(直接在AndroidManifest.xml中声明就可以),APP安装后都可以访问这些权限。从6.0开始,一些敏感权限(权限主要分为normal、dangerous、signature和signatureOrSystem四个等级,常规情况下我们只需要了解前两种,即正常权限和危险权限。),需要在使用时动态申请,并且用户可以选择拒绝授权访问这些权限,已授予过的权限,用户也可以去APP设置页面去关闭授权。这对用户来说提高了安全性,可以防止一些应用恶意访问用户数据,但是对于开发来说,也增加了不少工作量,这块不做适配处理的话,APP在访问权限的时候会容易崩溃。

package com.xmkh.imagetest;

import android.Manifest;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;

import java.io.File;

/**
 * @author: 下码看花
 * date: 2019年8月16日
 * description: ImageView的使用
 */
public class MainActivity extends AppCompatActivity {

    /**
     * 用于请求值使用
     */
    private final int PERMISSION_REQUEST = 100;

    /**
     * 加载图片用的ImageView
     */
    private ImageView ivPic;

    /**
     * 点击后去加载图片
     */
    private Button btnLoad;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //因为小编使用的是android6.0版本以上的手机,需要动态申请权限
        //而Android6.0以下的手机,只需在AndroidManifest.xml中写入权限就可以
        if (Build.VERSION.SDK_INT >= 23) {
            //申请的权限数组
            String[] mPermissionList = new String[]{
                    //SD卡写入权限
                    Manifest.permission.WRITE_EXTERNAL_STORAGE,
                    //SD卡读取权限
                    Manifest.permission.READ_EXTERNAL_STORAGE,
                    //访问电话状态
                    Manifest.permission.READ_PHONE_STATE,
                    //访问摄像机权限
                    Manifest.permission.CAMERA
            };
            //以下int数值都是申请权限后的返回值,0表示同意(PackageManager.PERMISSION_GRANTED),-1表示拒绝(PERMISSION_DENIED)
            //而我们为了读取到SD卡中的数据,需要点同意
            int checkSPermission = ContextCompat.checkSelfPermission(this,
                    Manifest.permission.WRITE_EXTERNAL_STORAGE);
            int checkSPermission2 = ContextCompat.checkSelfPermission(this,
                    Manifest.permission.READ_EXTERNAL_STORAGE);
            int checkSPermission3 = ContextCompat.checkSelfPermission(this,
                    Manifest.permission.READ_PHONE_STATE);
            int checkSPermissionCAMERA = ContextCompat.checkSelfPermission(this,
                    Manifest.permission.CAMERA);

            //判断用户是否允许了我们所需权限
            if ((checkSPermission != PackageManager.PERMISSION_GRANTED)
                    || (checkSPermission2 != PackageManager.PERMISSION_GRANTED)
                    || (checkSPermission3 != PackageManager.PERMISSION_GRANTED)
                    || (checkSPermissionCAMERA != PackageManager.PERMISSION_GRANTED)) {
                ActivityCompat.requestPermissions(this, mPermissionList, PERMISSION_REQUEST);
            }
        }

        ivPic = findViewById(R.id.iv_picture);
        btnLoad = findViewById(R.id.btn_load);
        btnLoad.setOnClickListener(new View.OnClickListener() {

            /**
             * 在点击之前,其实还应该再次判断用户是否授权
             * 但是为了避免重敲一遍上述代码小编就省略啦,但是小伙伴在实际开发中一定要写!!!!
             * @param view
             */
            @Override
            public void onClick(View view) {
                //Environment.getExternalStorageDirectory().getAbsolutePath()方法是获取手机SD卡的绝对路径
                //而绝对路径就是你SD卡的最上层文件夹(就好比还未双击的C盘)
                //而/xmkh表示的是文件夹(相当于C盘中的一个文件夹)的名字
                //而/xmkh.png表示的是你要加载的本地图片(相当于C盘中xmkh文件夹下的一个图片)
                String path = Environment.getExternalStorageDirectory().getAbsolutePath() + "/xmkh/xmkh.png";
                //Uri我们前面的文章ContentProvider已经讲过了,忘记了的小伙伴可以去复习一下~
                Uri uri = Uri.fromFile(new File(path));
                //通过setImageURI设置路径
                ivPic.setImageURI(uri);
            }
        });
    }

    /**
     * 请求权限回调方法(有兴趣的小伙伴可以自己尝试一下在这个方法中写一些东西,不懂的可以给我们留言哦~)
     *
     * @param requestCode  请求值(PERMISSION_REQUEST)
     * @param permissions  对应我们上面写到的mPermissionList
     * @param grantResults 对应mPermissionList中请求权限返回结果的数组
     *                     (数组的长度与mPermissionList相等,数组中的内容就是PERMISSION_GRANTED或者PERMISSION_DENIED,并表示对应权限是否开启)
     */
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    }

}

效果图如下:

Android控件之ImageView(一)-LMLPHP

三. 打开相册加载图片

看了上述的一个demo展示,可能有的小伙伴表示太麻烦了,难道我得找到每张图片的路径才可以去加载图片嘛?而且一些小伙伴阔能使用的是自己的手机,相册都不知道在哪个文件夹下,没关系,接下来我们就教你如何从相册中选取照片并通过ImageView进行加载!!

btnLoad.setOnClickListener(new View.OnClickListener() {

            /**
             * 一定要记得再次判断权限!!
             * @param view
             */
            @Override
            public void onClick(View view) {
                //调用图库,获取所有本地图片
                Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
                //第一个参数是Uri,其实就是通过咱们之前讲到过的四大组件ContentProvider根据Uri进行查找SD卡中的所有的图片
                //只不过这是系统封装了一个方法不用我们自己去写(一环套一环,ContentProvider的重要性不用我再强调了吧~)
                intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
                        "image/*");
                //INTENT_MEDIA_REQUEST_CODE是我们需要在onActivityResult方法中的识别码,识别是否是从相册返回的数据,与PERMISSION_REQUEST作用相同
                startActivityForResult(intent, INTENT_MEDIA_REQUEST_CODE);
            }
        });
/**
     * @param requestCode 我们startActivityForResult中第二个参数,用于区分是哪个Intent的返回
     * @param resultCode  返回值常用的有RESULT_OK(成功)和RESULT_CANCELED(取消或者失败)
     * @param data        返回数据
     */
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == RESULT_OK) {
            switch (requestCode) {
                case INTENT_MEDIA_REQUEST_CODE:
                    if (data != null) {
                        //根据返回的Uri展示图片
                        ivPic.setImageURI(data.getData());
                    }
                    break;
                default:
                    break;
            }
        }
    }

为了效率,我们把主要代码进行了展示,其他部分代码依然没有变化,小伙伴可以放心尝试,运行效果如下:

Android控件之ImageView(一)-LMLPHP

其实ImageView还有很多属性和方法:

设置透明度

ImageView 设置透明度主要有以下几种方法:

  • android:alpha // 0f~1f
  • setAlpha(float alpha); // 0f~1f
  • setAlpha(int alpha); // 0~255,已过时
  • setImageAlpha(int alpha); // API>=16
设置图片
  • setlmageBitmap(Bitmap bm):使用 Bitmap 位图设置该 ImageView 显示的图片。
  • setlmageDrawable(Drawable drawable):使用 Drawable 对象设置该 ImageView 显示的图片。

结语

其他属性就要靠大家自己摸索啦,或者加入我们的扣扣群,你想知道的内容都会有人回复,以上就是我们今天所要讲解的全部重要内容,下一章更精彩,看好标题哦,今天只是ImageView第一讲~PS:如果还有未看懂的小伙伴,欢迎加入我们的QQ技术交流群:892271582,里面有各种大神回答小伙伴们遇到的问题,我们的微信群马上也将要和大家见面啦,届时希望大家踊跃加入其中~~

Android控件之ImageView(一)-LMLPHP

08-17 23:25