孤岛.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坐标系
Camera坐标系.png

更多相关文章

  1. Android实现步进式录像进度条
  2. Android(安卓)应用界面绘制流程
  3. Surface与SurfaceHolder.Callback
  4. Android(安卓)屏幕旋转 处理 AsyncTask 和 ProgressDialog 的最
  5. Android 简单的自定义view loading circle
  6. Android:自定义View实现随滑动由箭头变对勾的指示按钮
  7. android 画环形的资料
  8. Android自定义view贝塞尔曲线
  9. android camera 拍照加图片处理

随机推荐

  1. android EditText 只能输入无法删除的解
  2. Android(安卓)menu 使用初步
  3. Android(安卓)存储文件数据与读出文件数
  4. Android(安卓)实现不同字体颜色的TextVie
  5. Android(安卓)之 发送短信
  6. android app 与电脑wifi通信
  7. [置顶] 基于Android2.3.5系统:Java JDK AD
  8. android 按两次返回键退出
  9. [置顶] 论坛
  10. android对话框弹出方式动画