第六篇Android--ImageView、Bitmap

ImageView,和前面介绍的TextView、EditText,都继承自View都是View的子类。

ImageView 是用于呈现图片的视图。View可以理解为一个视图或控件。

1.简单使用

   在drawable-xxhdpi文件夹下放一张图片:

   

  xml中把这张图片设置给ImageView,这样就可以在屏幕上看到这张图:

      <ImageView
        android:id="@+id/image_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/girl" />

  另外也可以在代码中给ImageView设置图片:

     方法1:

 imageView = findViewById(R.id.image_view);
 imageView.setImageResource(R.drawable.girl);

     方法2:

 Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.girl);
 imageView.setImageBitmap(bitmap);

   方法1中通过:setImageResource(@DrawableRes int resId)方式,传入一个资源Id,在该方法内会把资源Id加载成一个Drawable。

       ImageView.java中

          try {
                d = mContext.getDrawable(mResource);
            } catch (Exception e) {
                Log.w(LOG_TAG, "Unable to find resource: " + mResource, e);
                // Don't try again.
                mResource = 0;
            }

   方法2中,先把资源Id解析成一个Bitmap,然后把Bitmap设置给ImageView。

      imageView.setImageBitmap(bitmap); 这个方法中,也会把传进来的bitmap转换成Drawable。

        mDrawable = null;
        if (mRecycleableBitmapDrawable == null) {
            mRecycleableBitmapDrawable = new BitmapDrawable(mContext.getResources(), bm);
        } else {
            mRecycleableBitmapDrawable.setBitmap(bm);
        }
        setImageDrawable(mRecycleableBitmapDrawable);

  以上两种方式都会把生成的Drawable赋值给ImageView的成员变量:Drawable  mDrawable

   设置完成后,都调用了invalidate();

                        这会调用父类View的invalidate(),

                        在View中会调用Parent,也就是ViewRootImpl的invalidate()方法。

                        在ViewRootImpl的invalidate()方法中,会触发scheduleTraversals,执行遍历,重新               进行布局layout测量measure绘制draw方法。

  所以最终会回调到了ImageView的onDraw方法中,ondraw方法中会调用drawable.draw方法。

       在draw方法中,传递进来一个画布canvas,最终会把该drawable转成一个bitmap绘制在canvas上,然后交给Native层,在屏幕上进行呈现。

 @Override
    protected void onDraw(Canvas canvas) {
      if (mDrawMatrix == null && mPaddingTop == 0 && mPaddingLeft == 0) {
            mDrawable.draw(canvas);
        } else {
           ........
            mDrawable.draw(canvas);
          .........
            
        }
    }

   2.BitmapFactory相关方法介绍:

//从drable目录下加载一个Bitmap
BitmapFactory.decodeResource(getResources(), R.drawable.girl); 
//把指定文件解析成一个Bitmap
BitmapFactory.decodeFile(file); 
//从内存数组中解析成一个Bitmap
BitmapFactory.decodeByteArray(byteArray,offset,lenght); 
//从流中加载一个Bitmap,
 //这个可以是一个文件流,读取本地的一个缓存文件
//也可以是一个网络流,从网络获取。
BitmapFactory.decodeStream(inputStream);

   1)从文件中读取一张图片,由于设计到文件io操作,最好是放在子线程中。

        示例:通过RxJava读取一张图片到内存。

        首先在build.gragle引入Rxjava相关jar包:

implementation 'io.reactivex.rxjava2:rxandroid:2.1.0'
    implementation 'io.reactivex.rxjava2:rxjava:2.2.4'

       代码实现:

public void createBitmap(ImageView imageView,String file) {
        Observable.create(new ObservableOnSubscribe<String>() {
            @Override
            public void subscribe(ObservableEmitter<String> emitter) throws Exception {
                emitter.onNext(file);
            }
        }).subscribeOn(Schedulers.io()).map(new Function<String, Bitmap>() {

            @Override
            public Bitmap apply(String file) throws Exception {
                return BitmapFactory.decodeFile(file);
            }
        }).observeOn(AndroidSchedulers.mainThread()).subscribe(new Consumer<Bitmap>() {
            @Override
            public void accept(Bitmap bitmap) throws Exception {
                imageView.setImageBitmap(bitmap);
            }
        });
    }

  2)从网络获取图片示例:

/**
     * 获取网络图片
     *
     * @param imageurl 图片网络地址
     * @return Bitmap 返回位图
     */
    public Bitmap GetImageInputStream(String imageurl) {
        URL url;
        HttpURLConnection connection = null;
        Bitmap bitmap = null;
        try {
            url = new URL(imageurl);
            connection = (HttpURLConnection) url.openConnection();
            connection.setConnectTimeout(6000); //超时设置
            connection.setDoInput(true);
            connection.setUseCaches(false); //设置不使用缓存
            InputStream inputStream = connection.getInputStream();
 
            BitmapFactory.Options options = new BitmapFactory.Options();
            options.inSampleSize = 2;
            options.inJustDecodeBounds = false;
 
            bitmap = BitmapFactory.decodeStream(inputStream, null, options);
            inputStream.close();
 
        } catch (Exception e) {
            e.printStackTrace();
        }
        return bitmap;
    }

3.BitmapFactory.Options

     1)options.inJustDecodeBounds = true;不把图加载到内存,只获取宽高。 

        FileInputStream fis = new FileInputStream("fileName");
        BitmapFactory.Options options = new BitmapFactory.Options();
        //为true则只加载图片的大小,返回一个null值,不会把图片加载到内存
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeStream(fis, null, options);
        //得到图片的宽高
        int imgWidth = options.outWidth;
        int imgHeight = options.outHeight;

   2) options.inSampleSize = 2; 设置值大于1,加载的图片大小是原理的4分之1,

        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inSampleSize = 2;
        Bitmap bitmap = BitmapFactory.decodeFile(imageFile,options);

4.创建Bitmap:Bitmap.createBitmap()

   1)代码示例:把View保存到一个bitmap:

 public static Bitmap getBitmapForView(View view) {
        int width = view.getWidth();
        int height = view.getHeight();
        Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);//准备图片
        Canvas canvas = new Canvas(bitmap);//将bitmap作为绘制画布
        view.draw(canvas);//讲View特定的区域绘制到这个canvas(bitmap)上去,
        return bitmap;//得到最新的画布
    }

  2)从一个bitmap得到另外一个大小的bitmap

        Bitmap srcBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.girl);
        int x = 0;
        int y = 0 ;
        float rate = 1.5f;
        int width = (int) (srcBitmap.getWidth()*rate);
        int height = (int) (srcBitmap.getHeight()*rate);
        Bitmap bitmap = Bitmap.createBitmap(srcBitmap,x,y,width,height);

3)将内存中的一个bitmap保存为一张本地图片:

  Bitmap srcBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.girl);
        try {
            FileOutputStream fos = new FileOutputStream("fileName");
            srcBitmap.compress(Bitmap.CompressFormat.JPEG,100,fos);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
当一个View超出屏幕时,你可以使用ScrollView或者HorizontalScrollView来解决这个问题。 如果你想拖动一个ImageView,并且希望它不会超出屏幕,你可以使用以下代码: ```java imageView.setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: { // 手指按下时记录位置 lastX = event.getRawX(); lastY = event.getRawY(); break; } case MotionEvent.ACTION_MOVE: { // 移动的距离 float dx = event.getRawX() - lastX; float dy = event.getRawY() - lastY; // 获取imageView的参数 RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) v.getLayoutParams(); // 移动imageView lp.leftMargin += dx; lp.topMargin += dy; // 确定imageView不会超出屏幕 int screenWidth = getResources().getDisplayMetrics().widthPixels; int screenHeight = getResources().getDisplayMetrics().heightPixels; if (lp.leftMargin < 0) { lp.leftMargin = 0; } else if (lp.leftMargin + v.getWidth() > screenWidth) { lp.leftMargin = screenWidth - v.getWidth(); } if (lp.topMargin < 0) { lp.topMargin = 0; } else if (lp.topMargin + v.getHeight() > screenHeight) { lp.topMargin = screenHeight - v.getHeight(); } // 重新设置imageView的参数 v.setLayoutParams(lp); // 更新位置记录 lastX = event.getRawX(); lastY = event.getRawY(); break; } case MotionEvent.ACTION_UP: { // 手指抬起时不需要做任何事情 break; } } return true; } }); ``` 这个代码片段会允许你拖动ImageView,但是它不会被拖动超出屏幕。如果ImageView被拖动到了屏幕边缘,它会停在那里并且无法继续拖动。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

niuyongzhi

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值