【Android学习】图片

1,ImageView(图片视图)

1)概念

ImageView继承自View组件,它的主要功能是用于显示图片,且任何Drawable对象都可使用ImageView来显示。

Android中不仅可以将扩展名为.png,.jpg,.gif的普通图片作为图片资源,而且可以将扩展名为.9.png的9-Patch图片作为图片资源。扩展名为.png,.jpg,.gif的普通图片较为常见,他们通常是通过绘图软件完成的。而9-Patch图片是通过使用Android SDK中的提供的工具Draw 9-patch生成的。那为什么要使用9-Patch这种图片呢?原因是:与普通图片不同,使用9-Patch图片作为屏幕或按钮的背景时,当屏幕的尺寸或按钮的大小改变时,图片可自动缩放,达到不失真的效果。

2)属性

--scaleType
设置图片的填充方式,相关方法setScaleType(ImageView.ScaleType)

ImageView.ScaleType / android:scaleType值:
CENTER /center 按图片的原来size居中显示,当图片长/宽超过View的长/宽,则截取图片的居中部分显示
CENTER_CROP / centerCrop 按比例扩大图片的size居中显示,使得图片长(宽)等于或大于View的长(宽)
CENTER_INSIDE / centerInside 将图片的内容完整居中显示,通过按比例缩小或原来的size使得图片长/宽等于或小于View的长/宽
FIT_CENTER / fitCenter 把图片按比例扩大/缩小到View的宽度,居中显示
FIT_END / fitEnd 把图片按比例扩大/缩小到View的宽度,显示在View的下部分位置
FIT_START / fitStart 把图片按比例扩大/缩小到View的宽度,显示在View的上部分位置
FIT_XY / fitXY 把图片不按比例扩大/缩小到View的大小显示
MATRIX / matrix 用矩阵来绘制,动态缩小放大图片来显示。
ImageView

--adjustViewBounds
调整边框时是否保持可绘制对象的宽高比,相关方法setAdjustViewBounds(boolean)
--src 
设置要显示的Drawable对象的ID
,相关方法setImageResource(int)
--android:maxHeight
设置ImageView的最大高度,相关方法setMaxHeight(int)

2,图片加载

1)大量图片加载慢

按需加载,不需要的释放。
必要时做一个存放图片地址的映射数组,这样图片删掉了也可以从数组里面取对应的路径。

2)加载大图片

android系统给图片分配的内存只有8M,当加载大量图片时往往会出现OOM。
①尽量不要使用setImageBitmap或setImageResource或BitmapFactory.decodeResource来设置一张大图
这些函数在完成decode后,最终都是通过java层的createBitmap来完成的,需要消耗更多内存,可以通过BitmapFactory.decodeStream方法,创建出一个bitmap,再将其设为ImageView的 source
②使用BitmapFactory.Options对图片进行压缩

     InputStream is = this.getResources().openRawResource(R.drawable.pic1);
     BitmapFactory.Options options=new BitmapFactory.Options();
     options.inJustDecodeBounds = false;
     options.inSampleSize = 10;   //width,hight设为原来的十分一
     Bitmap btp =BitmapFactory.decodeStream(is,null,options); 

③运用Java软引用,进行图片缓存,将需要经常加载的图片放进缓存里,避免反复加载
及时销毁不再使用的Bitmap对象

  if(!bmp.isRecycle() ){
         bmp.recycle()   //回收图片所占的内存
         system.gc()  //提醒系统及时回收
   } 

3)图片选择器

GitHub:ImagePicker
使用步骤:
①引入依赖。

public static final int REQUEST_CODE_SELECT = 100;
public static final int REQUEST_CODE_PREVIEW = 101;
private ArrayList<ImageItem> selImageList = new ArrayList<>(); //当前选择的所有图片

②初始化ImagePicker。

private void initImagePicker() {

    ImagePicker imagePicker = ImagePicker.getInstance();
    imagePicker.setImageLoader(new GlideImageLoader());   //设置图片加载器
    imagePicker.setShowCamera(true);                      //显示拍照按钮
    imagePicker.setCrop(true);                           //允许裁剪(单选才有效)
    imagePicker.setSaveRectangle(true);                   //是否按矩形区域保存
    imagePicker.setSelectLimit(maxImgCount);              //选中数量限制
    imagePicker.setStyle(CropImageView.Style.RECTANGLE);  //裁剪框的形状
    imagePicker.setFocusWidth(800);                       //裁剪框的宽度。单位像素(圆形自动取宽高最小值)
    imagePicker.setFocusHeight(800);                      //裁剪框的高度。单位像素(圆形自动取宽高最小值)
    imagePicker.setOutPutX(1000);                         //保存文件的宽度。单位像素
    imagePicker.setOutPutY(1000);                         //保存文件的高度。单位像素
}

③跳转。

//打开选择,本次允许选择的数量(通过maxImgCount控制一次选择照片的数量)
ImagePicker.getInstance().setSelectLimit(maxImgCount);
Intent intent1 = new Intent(this, ImageGridActivity.class);
/* 如果需要进入选择的时候显示已经选中的图片,
* 详情请查看ImagePickerActivity
* */
startActivityForResult(intent1, REQUEST_CODE_SELECT); 

④onActivityResult方法回调

if (resultCode == ImagePicker.RESULT_CODE_ITEMS) {//添加图片返回
        if (data != null && requestCode == REQUEST_CODE_SELECT) {
            images = (ArrayList<ImageItem>) data.getSerializableExtra(ImagePicker.EXTRA_RESULT_ITEMS);
            if (images != null) {
                selImageList.clear();
                selImageList.addAll(images);
                ImageItem imageItem = selImageList.get(0);//imageItem.path为地址
Glide.with(this)//context
        .load(userImage)//uri
        .placeholder(R.mipmap.icon_cover_default)//占位图(不可用于CircleImageView图片的加载)
        .error(R.drawable.nmtittle)//错误图
        .into(myTitleImage);//ImageView控件

            }
        }
    } else if (resultCode == ImagePicker.RESULT_CODE_BACK) {//预览图片返回
        if (data != null && requestCode == REQUEST_CODE_PREVIEW) {
            images = (ArrayList<ImageItem>) data.getSerializableExtra(ImagePicker.EXTRA_IMAGE_ITEMS);
            if (images != null) {
                selImageList.clear();
                selImageList.addAll(images);
                ImageItem imageItem = selImageList.get(0);                ImagePicker.getInstance().getImageLoader().displayImage(this, imageItem.path, IV_photo, 0, 0);//IV_photo为要显示图片的控件
            }
        }
    }

⑤导入ClideImageLoader(图片加载器)

4)background

①background属性

对于src,图片不会拉伸。
如果以background,图片会根据View的宽度进行拉伸,解决方案是:

如下xml文件:tv_background.xml,放于drawable文件夹中。

<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
    android:src="@drawable/toolbar_bg"
    android:tileMode="disabled" android:gravity="top" >
</bitmap>

可以之间被 android:background使用,且图片不会出现拉伸。
注意:此方案可以把大图片放小,但无法把小图片放大。笔者暂时没有找到可以把bitmap适配于大屏手机的办法。来个大大指教下!

②setBackgroundResource、setBackground比较

功能相同,区别在于效率。
对于使用频率比较高的,从xm读取资源相当于一次IO,可提前通过getResources()存储,然后每次直接使用即可。

playBtn.setBackgroundResource(R.drawable.pause_selecor);
playBtn.setBackgroundDrawable(myContext.getResources().getDrawable(R.drawable.pause_selecor););

5)在不压缩的情况下加载高清大图

使用BitmapRegionDecoder进行布局加载。

3,Bitmap的加载和Cache

4,Drawable

5,drawableLeft、drawableRight、drawableTop、drawableBottom

1)xml设置

android:drawablePadding="5dp"  
android:drawableRight="@drawable/icon_new"  

2)java设置

//void android.widget.TextView.setCompoundDrawables(Drawable left, Drawable top, Drawable right, Drawable bottom)
Drawable mDrawable = getResources().getDrawable(drawable);
mDrawable.setBounds(0, 0, mDrawable.getMinimumWidth(), mDrawable.getMinimumHeight());
btn_Left.setCompoundDrawables(mDrawable, null, null, null);

3)图片点击

①点击图片切换决定et_password显示的密码是明文还是密文。

 @Override
    public boolean onTouch(View v, MotionEvent event) {
        switch (v.getId()) {
        case R.id.act_login_et_password:
            // et.getCompoundDrawables()得到一个长度为4的数组,分别表示左右上下四张图片
            Drawable drawable = et_password.getCompoundDrawables()[2];
            //如果右边没有图片,不再处理
            if (drawable == null)
                return false;
            //如果不是按下事件,不再处理
            if (event.getAction() != MotionEvent.ACTION_UP)
                return false;
            if (event.getX() > et_password.getWidth()
                    - et_password.getPaddingRight()
                    - drawable.getIntrinsicWidth()){
                isChecked = !isChecked;
                if(isChecked){
                    et_password.setInputType(InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD);
                }else{
                    et_password.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
                }
            }
            break;
        default:
            break;
        }
        return false;
    }

6,实践

1)图片分辨率

H 分辨率480*800
XH 分辨率1280*720
XXH 分辨率1920*1080

在Android studio 中,自定义图片放在drawable中,切图根据分辨率不同,放在mipmap文件夹中(可以自适应屏幕)。

2)屏幕分辨率自适应

①组件大小:权重(layout_weight)、具体像素(dip)
②图片:drawable-hdpi、.9.png图片
③AndroidManifest.xml

<supports-screens
android:largeScreens="true"
android:normalScreens="true"
android:anyDensity = "true"/>

android:anyDensity值为true,系统会依据屏幕密度,自动去找对应的文件夹。
如果drawable-hpdi中有高密度图片,其它两个文件夹中没有对应图片资源,那么系统会去加载drawable-hdpi中的资源。

3)Tab

①tab切换底部线条动画
效果图
方案:
TextView设置切换2种背景。
shape写的只有底部有横线的图形:

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">

    <item
        android:top="-2dp"
        android:right="-2dp"
        android:left="-2dp">
        <shape>
            <solid android:color="@android:color/transparent"/>
            <stroke
                android:width="1dp"
                android:color="@color/red"/>
        </shape>
    </item>

</layer-list>
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值