ImageView 显示图片
在 Android 平台上,显示图片的方式有很多种,其中最为简单的就是 ImageView。
1 . 在 lyaout 布局中,声明好 ImageView
<ImageView
android:id="@+id/image_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="fitCenter"/>
2 . 在 Acitivity 中简单的使用
private ImageView mImageView;
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.acitivity_imageview);
mImageView = findViewById(R.id.image_view);
mImageView.setImageResource(R.mipmap.images);
}
SurfaceView 显示图片
SurfaceView 与普通的 view 的区别在于:
- surfaceview 不需要在 UI 线程绘制,可以在子线程绘制
- surfaceview 提供了双缓冲的机制,绘制效率高
- surfaceview 是创建一个置于应用窗口之上的窗口,所以无法不能应用动画、变换和缩放,也没办法叠加
surfaceview 需要实现 SurfaceHolder.Callback 接口,包括三个声明周期
surfaceCreated(SurfaceHolder holder)
surfaceChanged(SurfaceHolder holder, int format, int width, int height)
surfaceDestroyed(SurfaceHolder holder)
具体的实现代码:
public class ImageSurfaceActivity extends AppCompatActivity implements SurfaceHolder.Callback {
private SurfaceView mSurfaceView;
private ExecutorService mThread;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mSurfaceView = new SurfaceView(this);
setContentView(mSurfaceView);
initSurfaceView();
}
private void initSurfaceView() {
// 创建一个只有一个线程的线程池,其实用Thread也可以
mThread = new ThreadPoolExecutor(1, 1, 2000L, TimeUnit.MILLISECONDS,
new LinkedBlockingDeque<Runnable>());
// 添加SurfaceHolder.callback,在回调中可以绘制
mSurfaceView.getHolder().addCallback(this);
}
@Override
public void surfaceCreated(SurfaceHolder surfaceHolder) {
// 执行绘制
mThread.execute(new DrawRunnable());
}
@Override
public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {
}
@Override
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
if (!mThread.isShutdown()) {
mThread.shutdown();
}
}
private class DrawRunnable implements Runnable {
@Override
public void run() {
Bitmap bimap = BitmapFactory.decodeResource(ImageSurfaceActivity.this.getResources(),
R.mipmap.images);
SurfaceHolder surfaceHolder = mSurfaceView.getHolder();
Canvas canvas = surfaceHolder.lockCanvas(); // 获取画布
Paint paint = new Paint();
Rect srcRect = new Rect(0, 0, bimap.getHeight(), bimap.getWidth());
Rect destRect = getBitmapRect(bimap);
canvas.drawBitmap(bimap, srcRect, destRect, paint);
surfaceHolder.unlockCanvasAndPost(canvas);
}
}
/**
* 图片的尺寸和屏幕的尺寸不一样,需要把图片调整居中
**/
private Rect getBitmapRect(Bitmap bimap) {
int bimapHeight = bimap.getHeight();
int bimapWidth = bimap.getWidth();
int viewWidth = mSurfaceView.getWidth();
int viewHeight = mSurfaceView.getHeight();
float bimapRatio = (float) bimapWidth / (float) bimapHeight; // 宽高比
float screenRatio = (float) viewWidth / (float) viewHeight;
int factWidth;
int factHeight;
int x1, y1, x2, y2;
if (bimapRatio > screenRatio) {
factWidth = viewWidth;
factHeight = (int)(factWidth / bimapRatio);
x1 = 0;
y1 = (viewHeight - factHeight) / 2;
} else if (bimapRatio < screenRatio) {
factHeight = viewHeight;
factWidth = (int)(factHeight * bimapRatio);
x1 = (viewWidth - factWidth) / 2;
y1 = 0;
} else {
factWidth = bimapWidth;
factHeight = bimapHeight;
x1 = 0;
y1 = 0;
}
x2 = x1 + factWidth;
y2 = y1 + factHeight;
return new Rect(x1, y1, x2, y2);
}
}
自定义 View 显示图片
自定义 View 中有三个重要的声明周期:
onLayout()
布局
onMeasure()
测量
onDraw()
绘制
Android 的刷新间隔是 16ms
因为我们只是显示图片,不需要特别复杂的操作,只选取onDraw
实现:
private void init() {
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mBitmap = BitmapFactory.decodeResource(getContext().getResources(), R.mipmap.images);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Rect srcRect = new Rect(0, 0, mBitmap.getHeight(), mBitmap.getWidth());
Rect destRect = getBitmapRect(mBitmap); // 获取调整后的bitmap的显示位置
canvas.drawBitmap(mBitmap, srcRect, destRect, mPaint);
}
原创文章,作者:奋斗,如若转载,请注明出处:https://blog.ytso.com/6296.html