Hi,喜欢每天练习的小伙伴肯定对上一篇的Button了如指掌了,那么今天我们为大家带来了ImageView控件,这个控件能与Button碰撞出什么样的火花呢?话不多说,让我们赶紧开始学习吧~
ImageView的结构
public class ImageView extends View
java.lang.Object ↳ android.view.View ↳ android.widget.TextView ↳ android.widget.ImageView
已知直接子类:
ImageButton
, QuickContactBadge
已知间接子类:
ZoomButton
ImageView
(图像视图),直接继承自View类,它的主要功能是用于显示图片,实际上它不仅仅可以用来显示图片,任何Drawable对象都可以使用 ImageView
来显示。 ImageView
可以适用于任何布局中,并且Android为其提供了缩放和着色的一些操作。
下面我们简单的介绍 ImageView
的使用(再此示例中,需要使用到一个ic_luffy.png的图片,需要放到res文件夹下drawable文件夹中):
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
给定的宽度来进行拉伸
让我们看一个示例:
我们将图片的宽高属性设置为固定值,并且给图片增加 background
属性,我们可以直观的发现,第一张图片明显出现了拉伸,而第二张图片未出现变化,验证上述结论的正确性。
而 ImageView
还有很多有趣的属性:
android:maxHeight
:设置ImageView的最大高度;android:maxWidth
:设置ImageView的最大宽度;android:adjustViewBounds
:设置ImageView是否调整自己的边界来保持所显示图片的长宽比,需要结合 android:maxWidth
、 android:maxHeight
一起使用否则单独使用没有效果,并且设置 layout_width
和 layout_height
为 wrap_content
;android:scaleType
:设置所显示的图片如何缩放或移动以适应ImageView的大小。对于 android:scaleType
属性,因为关于图像在 ImageView
中的显示效果,所以有如下属性值可以选择:
matrix
:使用 matrix
方式进行缩放。fitXY
:横向、纵向独立缩放,以适应该 ImageView
;fitStart
:保持纵横比缩放图片,并且将图片放在 ImageView
的左上角;fitCenter
:保持纵横比缩放图片,缩放完成后将图片放在 ImageView
的中央;fitEnd
:保持纵横比缩放图片,缩放完成后将图片放在 ImageView
的右下角;center
:把图片放在 ImageView
的中央,但是不进行任何缩放;centerCrop
:保持纵横比缩放图片,以使图片能完全覆盖ImageView;centerInside
:保持纵横比缩放图片,以使得 ImageView
能完全显示该图片;上述的几个属性小编就不给大家做具体展示了,希望各位小伙伴可以自主尝试。
在上述中,只是简单的介绍加载资源文件中的图片以及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);
}
}
效果图如下:
看了上述的一个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;
}
}
}
为了效率,我们把主要代码进行了展示,其他部分代码依然没有变化,小伙伴可以放心尝试,运行效果如下:
其实 ImageView
还有很多属性和方法:
ImageView
设置透明度主要有以下几种方法:
android:alpha// 0f~1f
setAlpha(floatalpha);// 0f~1f
setAlpha(intalpha);// 0~255,已过时
setImageAlpha(intalpha);// API>=16
setlmageBitmap(Bitmapbm)
:使用 Bitmap 位图设置该 ImageView 显示的图片。setlmageDrawable(Drawabledrawable)
:使用 Drawable 对象设置该 ImageView 显示的图片。