Android(安卓)3D翻转效果实践
16lz
2021-01-26
孤岛.jpg
前言
android中3D效果大部分是用
android.graphics.Camera
来实现的,本篇讲述Camera
的一个实例来简单了解其使用
效果展示
3D翻转效果.gif实现
布局文件activity_main.xml
:
<?xml version="1.0" encoding="utf-8"?>
- 布局文件很简单,上面是实现3D翻转的自定义
view
,下面是一个SeekBar
MainActivity
主要代码:
private My3DView myView; private SeekBar seekBar; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); myView = (My3DView) findViewById(R.id.my); seekBar = (SeekBar) findViewById(R.id.seek); seekBar.setMax(90); seekBar.setKeyProgressIncrement(1); seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { myView.setRotateDegree(progress); } @Override public void onStartTrackingTouch(SeekBar seekBar) { } @Override public void onStopTrackingTouch(SeekBar seekBar) { } }); }
-
Activity
代码也很简单,通过监听SeekBar
的值改变,传0~90
给自定义myView
,调用其方法setRotateDegree()
来改变翻转状态
自定义My3DView
代码:
public class My3DView extends View { Paint mPaint;//画笔 Bitmap b1;//图1 Bitmap b2;//图2 Camera camera;//实现翻转的核心类 Matrix matrix;//存储变化后的矩阵 int currentDegree;//当前翻转角度 float axisY;//旋转轴的Y坐标 int viewWidth;//控件宽 int viewHeight;//控件高 public My3DView(Context context, @Nullable AttributeSet attrs) { super(context, attrs); init(); } /** * 初始化 */ private void init() { camera = new Camera(); matrix = new Matrix(); mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); mPaint.setStyle(Paint.Style.FILL); b1 = BitmapFactory.decodeResource(getResources(), R.drawable.img1); b2 = BitmapFactory.decodeResource(getResources(), R.drawable.img2); axisY = 0; currentDegree = 0; } /** * 测量大小,根据控件大小按比例缩放图片,使得图片填充整个控件 * @param widthMeasureSpec * @param heightMeasureSpec */ @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); viewWidth = getMeasuredWidth(); viewHeight = getMeasuredHeight(); if(viewWidth != 0 && viewHeight != 0) { b1 = scaleBitmap(b1); b2 = scaleBitmap(b2); } } /** * 按比例缩放图片 * @param origin * @return */ private Bitmap scaleBitmap(Bitmap origin) { if(origin == null) { return null; } int height = origin.getHeight(); int width = origin.getWidth(); float scaleWidth = ((float) viewWidth) / width; float scaleHeight = ((float) viewHeight) / height; Matrix mt = new Matrix(); mt.postScale(scaleWidth, scaleHeight); Bitmap newBitmap = Bitmap.createBitmap(origin, 0, 0, width, height, mt, false); return newBitmap; } /** * 绘制,实现翻转效果 * @param canvas */ @Override protected void onDraw(Canvas canvas) { //绘制下面那张图片 camera.save(); camera.rotateX(-currentDegree);//设置旋转角度 camera.getMatrix(matrix);//获取到旋转后的矩阵 camera.restore(); matrix.preTranslate(-viewWidth / 2, 0);//绕自己的Top旋转 matrix.postTranslate(viewWidth / 2, axisY);//旋转完后移动图片到轴线下面 canvas.drawBitmap(b1, matrix, mPaint); //绘制上面那张图片 camera.save(); camera.rotateX(90-currentDegree); camera.getMatrix(matrix); camera.restore(); matrix.preTranslate(-viewWidth / 2, -viewHeight);//绕自己的bottom旋转 matrix.postTranslate(viewWidth / 2, axisY);//旋转完后移动图片到轴线上面 canvas.drawBitmap(b2, matrix, mPaint); } /** * 设置当前翻转角度,并重新绘制 * @param degree */ public void setRotateDegree(int degree) { currentDegree = degree; axisY = degree / 90f * viewHeight; invalidate(); }}
- 从调用
setRotateDegree(int degree)
为入口,axisY = degree / 90f * viewHeight
计算两张图片的旋转轴的Y坐标,也就是两张图的相交线的Y坐标。invalidate()
重新绘制,调用onDraw()
方法 -
onDraw()
方法中,Camera
旋转要注意需要先将矩阵平移至坐标中心点,这也是使用Camera
使用需要注意的地方 - 特别需要留意
Camera
变换的坐标系和绘制坐标系是不一样的,最后附上Camera
坐标系
更多相关文章
- Android实现步进式录像进度条
- Android(安卓)应用界面绘制流程
- Surface与SurfaceHolder.Callback
- Android(安卓)屏幕旋转 处理 AsyncTask 和 ProgressDialog 的最
- Android 简单的自定义view loading circle
- Android:自定义View实现随滑动由箭头变对勾的指示按钮
- android 画环形的资料
- Android自定义view贝塞尔曲线
- android camera 拍照加图片处理