Android笔记之图形和动画

绘图技术:

2D:Android基本组件构成,使用Skia引擎,View及其子类通过它画出来的

3D:通过OpenGL ES技术实现

2D绘制技术:

画布与画笔:(Canvas与Paint)

Paint常用方法:

setColor(int color):设置颜色
setAlpha(int a):设置透明度(0~255)
setStyle:设置样式
setTextAlign:设置文本对齐方式
setTextSize:设置文本的字号
Canvas常用绘图方法:
drawPoint 绘制单个点
drawPoints 绘制多个点
drawLine 绘制单条线
drawLines 绘制多条线
drawText 绘制文本
drawArc 绘制弧线
drawRect 绘制矩形
drawBitmap 绘制图像

绘制点和线:

private class MyView extends View {
    public MyView(Context context) {
        super(context);
    }
    @Override
    public void onDraw(Canvas canvas) {
        float x = 0.0f, y = 100.0f;
        int height = 100;
        //创建画笔对象
        Paint paint = new Paint();
        //设置画笔颜色
        paint.setColor(Color.RED);
        //设置笔的粗细
        paint.setStrokeWidth(5.0f);
        // 在画布上画线

        canvas.drawLine(x, y, x + canvas.getWidth() - 1, y, paint);
        canvas.drawLine(x, y + height - 1, x + canvas.getWidth(), y+ height - 1, paint);
        //重新设置画笔
        paint.setColor(Color.BLACK);
        paint.setStrokeWidth(10.0f);
        // 准备100个数据
        float[] pts = new float[100];
        for (int i = 0; i < 100; i = i + 2) {
            pts[i] = i * 5;
            pts[i + 1] = i * 15;
        }
        // 在画布上画点
        canvas.drawPoints(pts, 20,10, paint);
    }
}

绘制矩形:

 private class MyView extends View {
        public MyView(Context context) {
            super(context);
        }

        @Override
        public void onDraw(Canvas canvas) {
            //创建画笔
            Paint paint = new Paint();
            //设置画笔颜色
            paint.setColor(Color.RED);
            Rect r1 = new Rect(100, 100, 600, 500);
            //绘制矩形
            canvas.drawRect(r1, paint);
            paint.setColor(Color.BLUE);
            RectF r2 = new RectF(200.0f, 900.0f, 600.0f, 600.0f);
            canvas.drawRect(r2, paint);
        }
    }

绘制弧线Api:

drawArc(RectF oval,float startAngle,float sweepAngle,boolean useCenter,Paint paint)
  • Oval 弧形边界
  • startAngle 圆弧开始的角度
  • sweepAngle 圆弧扫过的角度(顺时针为正,单位是度)
private class MyView extends View {
        public MyView(Context context) {
            super(context);
        }

        @Override
        public void onDraw(Canvas canvas) {
            // 创建画笔
            Paint paint = new Paint();
            // 开启抗锯齿效果
            paint.setAntiAlias(false);
            paint.setColor(Color.BLUE);
            RectF oval1 = new RectF(100.0f, 100.0f, 500.0f, 500.0f);
            canvas.drawRect(oval1, paint);
            paint.setColor(Color.RED);
            // 绘制360度的圆
            canvas.drawArc(oval1, 0, 360, true, paint);
            paint.setColor(Color.BLUE);
            RectF oval2 = new RectF(100.0f, 700.0f, 400.0f, 1000.0f);
            // 绘制90~135度的圆弧,包含圆心
            canvas.drawArc(oval2, 90, 135, true, paint);
            RectF oval3 = new RectF(500.0f, 700.0f, 800.0f, 1000.0f);
            // 绘制90~135度的圆弧,不包含圆心
            canvas.drawArc(oval3, 90, 135, false, paint);
        }
    }

绘制位图:

两种方式获得位图(Bitmap)对象:

使用BitmapFactory获得位图:BitmapFactory工厂从资源文件中创建位图。

使用BitmapDrawable获取位图:通过资源id获得输入流,再创建位图。

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(new MyView(this));
    }

    private class MyView extends View {
        public MyView(Context context) {
            super(context);
        }

        @Override
        public void onDraw(Canvas canvas) {
            //创建Bitmap对象
            Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.cat);

            //创建画笔对象
            Paint paint = new Paint();
            //绘制位图
            canvas.drawBitmap(bitmap, 180, 60, paint);
        }
    }
}

位图变化:

涉及矩阵(Matrix)类

三种变换常用方法:

  • setScale(float sx,float sy,float px,float py):设置缩放矩阵(s为缩放比例,p为缩放中心点坐标
  • setRotate(float degrees,float px,float py):设置旋转矩阵(degrees为旋转度数,p为旋转中心坐标
  • setTranslate(float dx,float dy):设置平移矩阵(dx为x方向平移距离,dy为y方向平移距离
     
public void onDraw(Canvas canvas) {
    Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.cat);

    Matrix matrix = new Matrix();
    matrix.setScale(0.8f, 0.8f, 40, 40);
    matrix.setRotate(40, 300, 600);
    matrix.postTranslate(100, 200);

    //创建画笔对象
    Paint paint = new Paint();
    //绘制位图
    canvas.drawBitmap(bitmap, matrix, paint);
}

调用Android照相机

  • 指定意图:android.media.action.IMAGE_CAPTURE
  • 对应常量:MediaStore.ACTION_IMAGE_CAPTURE

摄像:

  • 指定意图:android.media.action.VIDEO_CAPTURE
  • 对应常量:MediaStore.ACTION_VIDEO_CAPTURE
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE)
startActivityForResult(intent,REQ_CODE_DATA);//REQ_CODE_DATA = 100

Protected void onActivityResult(int requestCode,int resultCode,Intent data){
    //TODO
}

实现两种情况(将图片保存起来;直接使用返回的数据) 

 //返回数据的请求编码
    private final static int REQ_CODE_DATA = 100;
    //保存文件的请求编码
    private final static int REQ_CODE_SAVE = 101;
    //保存的图片文件路径,位于SD卡中
    private final static String FILE_PATH = "/mnt/sdcard/test.jpg";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button buttonTake = (Button) findViewById(R.id.buttonTake);
        buttonTake.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //定义访问照相机意图
                Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                //启动意图,返回请求编码为REQ_CODE_DATA
                startActivityForResult(intent, REQ_CODE_DATA);
            }
        });

        Button buttonTakeSave = (Button) findViewById(R.id.buttonTakeSave);
        buttonTakeSave.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //定义访问照相机意图
                Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                //创建访问文件的URI
                Uri uri = Uri.fromFile(new File(FILE_PATH));
                //设置意图附加信息
                intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
                //启动意图,返回请求Code为REQ_CODE_SAVE
                startActivityForResult(intent, REQ_CODE_SAVE);
            }
        });
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        ImageView imageView = (ImageView) findViewById(R.id.imageView);
        Bitmap bitmap = null;
        if (resultCode == Activity.RESULT_OK) {
            switch (requestCode) {
                case REQ_CODE_DATA: // 判断请求编码是否为REQ_CODE_DATA
                    Bundle extras = data.getExtras();
                    bitmap = (Bitmap) extras.get("data");
                    imageView.setImageBitmap(bitmap);
                    break;

                case REQ_CODE_SAVE: // 判断请求编码是否为REQ_CODE_DATA
                    try {
                        InputStream is = new FileInputStream(FILE_PATH);
                        bitmap = BitmapFactory.decodeStream(is);
                        imageView.setImageBitmap(bitmap);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
            }
        }
    }

注册:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CAMERA" />

Android动画技术:

  • 渐变动画:对Android的视图增加渐变动画效果。
  • 帧变化:显示res资源目录下有序的图片
  • 渐变动画:透明度渐变动画。
  • 平移动画。
  • 缩放动画。
  • 旋转动画。

所有动画都有两种方式实现,编程实现,XML实现!

编程实现:

  • 实例化动画类:Animation
  • 设置动画属性
  • 调用动画startAnimation()方法开始动画

四个基本类:

  • AlphaAnimation
  • TranslateAnimation
  • ScaleAnimation
  • RotateAnimation

AnimationSet是几个动画的集合

XML实现:放在资源目录/res/anim/目录下

<alpha xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="5000"
android:fromAlpha="1.0"
android:toAlpha="0.0" />
<scale xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="5000"
    android:fromXScale="1.0"
    android:fromYScale="1.0"
    android:pivotX="50%"
    android:pivotY="50%"
    android:toXScale="2.0"
    android:toYScale="2.0" />

<rotate xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="5000"
    android:fromDegrees="0.0"
    android:pivotX="50%"
    android:pivotY="50%"
    android:toDegrees="360" />

<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="1500"
    android:fromXDelta="0"
    android:fromYDelta="0"
    android:toXDelta="50"
    android:toYDelta="50" />

渐变动画:

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    Button alphaButton = (Button) findViewById(R.id.alpha_button);
    alphaButton.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            //1. 编程实现
            //Animation anim = new AlphaAnimation(1.0f, 0.0f);
            //anim.setDuration(5000);
            ///2.XML实现
            //从动画XML文件中加载动画对象
       
            Animation anim = AnimationUtils
                            .loadAnimation(MainActivity.this,R.anim.alpha_anim);
            View view = findViewById(R.id.imageView);
            //在视图view上设置并开始动画
            view.startAnimation(anim);
        }
    });

    Button translateButton = (Button) findViewById(R.id.translate_button);
    translateButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            //从动画XML文件中加载动画对象
            Animation anim = AnimationUtils.loadAnimation(MainActivity.this,
            R.anim.translate_anim);
            View view = findViewById(R.id.imageView);
            //在视图view上设置并开始动画
            view.startAnimation(anim);
        }
    });

    Button scaleButton = (Button) findViewById(R.id.scale_button);
    scaleButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            //从动画XML文件中加载动画对象
            Animation anim = AnimationUtils
.loadAnimation(MainActivity.this,R.anim.scale_anim);
            View view = findViewById(R.id.imageView);
            //在视图view上设置并开始动画
            view.startAnimation(anim);
        }
    });

    Button rotateButton = (Button) findViewById(R.id.rotate_button);
    rotateButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            //从动画XML文件中加载动画对象
            Animation anim = AnimationUtils
.loadAnimation(MainActivity.this,R.anim.rotate_anim);
            View view = findViewById(R.id.imageView);
            //在视图view上设置并开始动画
            view.startAnimation(anim);
        }
    });
}

动画插值器(interpolator)

Interpolator是一个接口,主要是对动画播放速度和时间进行控制。

//加速度播放
android.interpolator = “@android:anim/accelerate_interpolator”

属性值:

  • LinearInterpolator 线性播放,均匀播放
  • AccelerateInterpolator 动画加速播放
  • DecelerateInterpolator 动画减速播放
  • AccelerateDecelerateInterpolator 先加速后减速播放
  • CycleInterpolator 重复播放
  • PathInterpolator 路径插值器
  • BounceInterpolator
  • OvershootInterpolator
  • AnticipateInterpolator
  • AnticipateOvershootInterpolator

注:CycleInterpolator插值器很特殊,需要单独的插值器XML

android.Cycles = “10”

使用动画集:

XML实现:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <alpha xmlns:android="http://schemas.android.com/apk/res/android"/>
    <rotate xmlns:android="http://schemas.android.com/apk/res/android"/>
</set> 

代码实现:

AnimationSet set = new AnimationSet(true);// 加速度是否一样
set.addAnimation(animRotate);
set.addAnimation(animScale);
set.addAnimation(animAlpha);
// 启动动画
rlRoot.startAnimation(set);

帧动画:
//ToggleButton点击事件的内容
imgView.setBackgroundResource(R.drawable.frame_animation);
//imgView.setVisibility(ImageView.GONE);

AnimationDrawable frameAnimation = (AnimationDrawable) imgView.getBackground();
if (frameAnimation.isRunning()) {
    frameAnimation.stop();
} else {
    frameAnimation.stop();
    frameAnimation.start();
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值