最近做了圆形相机,使用surfaceView来承载。
public final class CircleSurfaceView extends SurfaceView implements SurfaceHolder.Callback{
public CircleSurfaceView(Context context) {
super(context);
init();
}
public CircleSurfaceView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public CircleSurfaceView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
this.setFocusable(true);
this.setFocusableInTouchMode(true);
}
@Override
public void draw(Canvas canvas) {
Path path = new Path();
// 坐标转换为实际像素
int w = getWidth();
int h = getHeight();
int radius = Math.min(w >> 1, h >> 1);
ALog.d(String.format(Locale.getDefault(),"w %d h %d radius %d", w, h, radius));
path.addCircle(w >> 1, h >> 1, radius, Path.Direction.CW);
canvas.setDrawFilter(new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG|Paint.FILTER_BITMAP_FLAG));
if (Build.VERSION.SDK_INT >= 26) {
canvas.clipPath(path);
} else {
canvas.clipPath(path, Region.Op.REPLACE);
}
super.draw(canvas);
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
ALog.d("surface Created");
setWillNotDraw(false);
//do camera action.... todo....
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
ALog.d("surface Changed " + width + ", " + height);
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
if(mSurfaceHolderChanged != null) mSurfaceHolderChanged.invoke(null);
}
}
主要就是修改draw函数。
来源自https://blog.csdn.net/qunqunstyle99/article/details/80864214,参考和实践的。
主要是评论下方,提点。
ImageView则修改onDraw(Canvas).
但是,重要的你会发现你的界面,摄像头还是拉伸的。
这个时候,我们需要关注下xml的画面比例即可。
<RelativeLayout
android:id="@+id/fr_recording_rl"
android:layout_marginTop="40dp"
android:layout_width="351dp"
android:layout_centerHorizontal="true"
android:layout_height="351dp">
<!-- surfaceView camera -->
<CircleSurfaceView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="33dp"
android:layout_marginStart="0dp"
android:layout_marginEnd="0dp"
android:layout_marginBottom="33dp"
android:layout_centerInParent="true"
android:id="@+id/fr_camera_surface_view"/>
</RelativeLayout>
你看,我的原型外层是351dp的正方形。内部,通过marginTop,bottom,而左右不设置值。
来保证他的比例与camera的分辨率达到一个比较好的比例即可。
如果你在xml中设置的比例也是方的。而摄像头一般都是1280/720这种比例,你的画面注定就要拉伸了。
后续有空,补充:
onMesure,onDraw,draw的区别和各自影响。