绘图技术:
2D:Android基本组件构成
3D:通过OpenGL ES技术实现
两种图形引擎技术:Skia(View及其子类通过它画出来的)和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);
}
}
绘制弧线:
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实现
编程实现:
1.实例化动画类:Animation
2.设置动画属性
3.调用动画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();
}