Android Graphics之PathEffect

#本文基于android sdk 22

在android graphics模块中有一类特效类叫做“path effect”,他们有一个共同的基类“PathEffect”。这些path effect的唯一目的就是给path增加特效,换句话话说只有当paint的style为“STROKE”或者“FILL_AND_STROKE”时,path effect才会生效。添加path effect的方式很简单,只需要调用Paint.setPathEffect()即可。

截止到android sdk 22,共有6中内置的PathEffect。下面表格列出这六种path effect,并给出基本说明。

CornerPathEffect 处理path的各个连接点,可以产生圆角效果,可以控制圆角半径
DashPathEffect 生成虚线效果,可以分别控制实点和虚点长度,可以控制偏移量
PathDashPathEffect 类似于DashPathEffect, 只不过增加了控制实点形状的能力
DiscretePathEffect 沿着path产生毛边的效果,可以控制毛边颗粒间距,以及毛边颗粒偏移距离
ComposePathEffect 可以将任意两种path effect的效果,比如CornerPathEffect和DashPathEffect。不过要注意的是它与SumPathEffect的不同,ComposePathEffect的叠加效果相当于,先生效效果A,然后以A为基础生效效果B。
SumPathEffect 可以叠加任意两种path effect的效果,与Compose不同的是,它相当于同时生效A和B,然后在视图上将两种效果生硬的上下叠加起来。

下面是各种path effect的实例代码和运行结果。

CornerPathEffect

核心代码:


package com.zlsam.learngraphics.patheffect;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.CornerPathEffect;
import android.graphics.Paint;
import android.graphics.Path;
import android.util.AttributeSet;
import android.view.View;

/**
 * Created by zhanglong on 16/8/18.
 */
public class CornerPathEffectView extends View {

private int mCornerRadius = 5;
    private Path mPath;
    private Paint mPaint;

public CornerPathEffectView(Context context) {
        this(context, null);
    }

public CornerPathEffectView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

public CornerPathEffectView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

if (isInEditMode()) {
            // Init path
            mPath = new Path();
            mPath.moveTo(10, 100);
            mPath.lineTo(60, 10);
            mPath.lineTo(120, 190);
            mPath.lineTo(180, 40);
            mPath.lineTo(240, 160);
            mPath.lineTo(300, 10);
            mPath.lineTo(360, 190);
            mPath.lineTo(420, 40);
            mPath.lineTo(480, 160);

// Init paint
            mPaint = new Paint();
            mPaint.setStyle(Paint.Style.STROKE);
            mPaint.setStrokeWidth(2);
            mPaint.setColor(Color.CYAN);
            mPaint.setPathEffect(new CornerPathEffect(mCornerRadius));
            return;
        }

// Init path
        mPath = new Path();
        mPath.moveTo(10, 100);
        mPath.lineTo(60, 10);
        mPath.lineTo(120, 190);
        mPath.lineTo(180, 40);
        mPath.lineTo(240, 160);
        mPath.lineTo(300, 10);
        mPath.lineTo(360, 190);
        mPath.lineTo(420, 40);
        mPath.lineTo(480, 160);

// Init paint
        mPaint = new Paint();
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeWidth(2);
        mPaint.setColor(Color.CYAN);
        mPaint.setPathEffect(new CornerPathEffect(mCornerRadius));
    }

@Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawPath(mPath, mPaint);
    }

public void setCornerRadius(int radius) {
        mCornerRadius = radius;
        mPaint.setPathEffect(new CornerPathEffect(mCornerRadius));
        invalidate();
    }

public int getCornerRadius() {
        return mCornerRadius;
    }
}

运行效果:

DashPathEffect

核心代码:


package com.zlsam.learngraphics.patheffect;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.DashPathEffect;
import android.graphics.Paint;
import android.graphics.Path;
import android.util.AttributeSet;
import android.view.View;

/**
 * Created by zhanglong on 16/8/18.
 */
public class DashPathEffectView extends View {

private float mSolidLength = 1F;
    private float mVirtualLength = 1F;
    private float mPhase = 0;
    private Path mPath;
    private Paint mPaint;

public DashPathEffectView(Context context) {
        this(context, null);
    }

public DashPathEffectView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

public DashPathEffectView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        if (isInEditMode()) {
            // Init path
            mPath = new Path();
            mPath.moveTo(10, 100);
            mPath.lineTo(60, 10);
            mPath.lineTo(120, 190);
            mPath.lineTo(180, 40);
            mPath.lineTo(240, 160);
            mPath.lineTo(300, 10);
            mPath.lineTo(360, 190);
            mPath.lineTo(420, 40);
            mPath.lineTo(480, 160);

// Init paint
            mPaint = new Paint();
            mPaint.setStyle(Paint.Style.STROKE);
            mPaint.setStrokeWidth(2);
            mPaint.setColor(Color.CYAN);
            mPaint.setPathEffect(new DashPathEffect(new float[] {mSolidLength, mVirtualLength}, mPhase));
            return;
        }

// Init path
        mPath = new Path();
        mPath.moveTo(10, 100);
        mPath.lineTo(60, 10);
        mPath.lineTo(120, 190);
        mPath.lineTo(180, 40);
        mPath.lineTo(240, 160);
        mPath.lineTo(300, 10);
        mPath.lineTo(360, 190);
        mPath.lineTo(420, 40);
        mPath.lineTo(480, 160);

// Init paint
        mPaint = new Paint();
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeWidth(2);
        mPaint.setColor(Color.CYAN);
        mPaint.setPathEffect(new DashPathEffect(new float[] {mSolidLength, mVirtualLength}, mPhase));
    }

@Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawPath(mPath, mPaint);
    }

public void setSolidLength(float length) {
        mSolidLength = length;
        mPaint.setPathEffect(new DashPathEffect(new float[]{mSolidLength, mVirtualLength}, mPhase));
        invalidate();
    }

public float getSolidLength() {
        return mSolidLength;
    }

public void setVirtualLength(float length) {
        mVirtualLength = length;
        mPaint.setPathEffect(new DashPathEffect(new float[] {mSolidLength, mVirtualLength}, mPhase));
        invalidate();
    }

public float getVirtualLength() {
        return mVirtualLength;
    }

public void setPhase(float phase) {
        mPhase = phase;
        mPaint.setPathEffect(new DashPathEffect(new float[] {mSolidLength, mVirtualLength}, mPhase));
        invalidate();
    }

public float getPhase() {
        return mPhase;
    }

}

运行效果:

PathDashPathEffect

核心代码:


package com.zlsam.learngraphics.patheffect;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PathDashPathEffect;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.View;

/**
 * Created by zhanglong on 16/8/18.
 */
public class PathDashPathEffectView extends View {

private Path mPath;
    private Paint mPaint;

public PathDashPathEffectView(Context context) {
        this(context, null);
    }

public PathDashPathEffectView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

public PathDashPathEffectView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        if (isInEditMode()) {
            // Init path
            mPath = new Path();
            mPath.moveTo(10, 100);
            mPath.lineTo(60, 10);
            mPath.lineTo(120, 190);
            mPath.lineTo(180, 40);
            mPath.lineTo(240, 160);
            mPath.lineTo(300, 10);
            mPath.lineTo(360, 190);
            mPath.lineTo(420, 40);
            mPath.lineTo(480, 160);

// Init paint
            mPaint = new Paint();
            mPaint.setStyle(Paint.Style.STROKE);
            mPaint.setStrokeWidth(2);
            mPaint.setColor(Color.CYAN);

Path path = new Path();
            path.addOval(new RectF(0, 0, 10, 20), Path.Direction.CCW);
            mPaint.setPathEffect(new PathDashPathEffect(path, 20, 0, PathDashPathEffect.Style.ROTATE));
            return;
        }

// Init path
        mPath = new Path();
        mPath.moveTo(10, 100);
        mPath.lineTo(60, 10);
        mPath.lineTo(120, 190);
        mPath.lineTo(180, 40);
        mPath.lineTo(240, 160);
        mPath.lineTo(300, 10);
        mPath.lineTo(360, 190);
        mPath.lineTo(420, 40);
        mPath.lineTo(480, 160);

// Init paint
        mPaint = new Paint();
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeWidth(2);
        mPaint.setColor(Color.CYAN);
        Path path = new Path();
        path.addOval(new RectF(0, 0, 10, 20), Path.Direction.CCW);
        mPaint.setPathEffect(new PathDashPathEffect(path, 20, 0, PathDashPathEffect.Style.ROTATE));
    }

@Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawPath(mPath, mPaint);
    }
}

运行结果:

DiscretePathEffect

核心代码:


package com.zlsam.learngraphics.patheffect;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.DiscretePathEffect;
import android.graphics.Paint;
import android.graphics.Path;
import android.util.AttributeSet;
import android.view.View;

/**
 * Created by zhanglong on 16/8/18.
 */
public class DiscretePathEffectView extends View {

private float mSegmentLength = 1.0F;
    private float mDeviation = 1.0F;
    private Path mPath;
    private Paint mPaint;

public DiscretePathEffectView(Context context) {
        this(context, null);
    }

public DiscretePathEffectView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

public DiscretePathEffectView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        if (isInEditMode()) {
            // Init path
            mPath = new Path();
            mPath.moveTo(10, 100);
            mPath.lineTo(60, 10);
            mPath.lineTo(120, 190);
            mPath.lineTo(180, 40);
            mPath.lineTo(240, 160);
            mPath.lineTo(300, 10);
            mPath.lineTo(360, 190);
            mPath.lineTo(420, 40);
            mPath.lineTo(480, 160);

// Init paint
            mPaint = new Paint();
            mPaint.setStyle(Paint.Style.STROKE);
            mPaint.setStrokeWidth(2);
            mPaint.setColor(Color.CYAN);
            mPaint.setPathEffect(new DiscretePathEffect(mSegmentLength, mDeviation));
            return;
        }

// Init path
        mPath = new Path();
        mPath.moveTo(10, 100);
        mPath.lineTo(60, 10);
        mPath.lineTo(120, 190);
        mPath.lineTo(180, 40);
        mPath.lineTo(240, 160);
        mPath.lineTo(300, 10);
        mPath.lineTo(360, 190);
        mPath.lineTo(420, 40);
        mPath.lineTo(480, 160);

// Init paint
        mPaint = new Paint();
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeWidth(2);
        mPaint.setColor(Color.CYAN);
        mPaint.setPathEffect(new DiscretePathEffect(mSegmentLength, mDeviation));
    }

@Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawPath(mPath, mPaint);
    }

public void setSegmentLength(float length) {
        mSegmentLength = length;
        mPaint.setPathEffect(new DiscretePathEffect(mSegmentLength, mDeviation));
        invalidate();
    }

public float getSegmentLength() {
        return mSegmentLength;
    }

public void setDeviation(float deviation) {
        mDeviation = deviation;
        mPaint.setPathEffect(new DiscretePathEffect(mSegmentLength, mDeviation));
        invalidate();
    }

public float getDeviation() {
        return mDeviation;
    }
}

运行结果:

ComposePathEffect

核心代码:


package com.zlsam.learngraphics.patheffect;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ComposePathEffect;
import android.graphics.CornerPathEffect;
import android.graphics.DashPathEffect;
import android.graphics.Paint;
import android.graphics.Path;
import android.util.AttributeSet;
import android.view.View;

/**
 * Created by zhanglong on 16/8/18.
 */
public class ComposePathEffectView extends View {

private int mCornerRadius = 0;
    private float mSolidLength = 1F;
    private float mVirtualLength = 1F;
    private float mPhase = 0;
    private Path mPath;
    private Paint mPaint;

public ComposePathEffectView(Context context) {
        this(context, null);
    }

public ComposePathEffectView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

public ComposePathEffectView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        if (isInEditMode()) {
            // Init path
            mPath = new Path();
            mPath.moveTo(10, 100);
            mPath.lineTo(60, 10);
            mPath.lineTo(120, 190);
            mPath.lineTo(180, 40);
            mPath.lineTo(240, 160);
            mPath.lineTo(300, 10);
            mPath.lineTo(360, 190);
            mPath.lineTo(420, 40);
            mPath.lineTo(480, 160);

// Init paint
            mPaint = new Paint();
            mPaint.setStyle(Paint.Style.STROKE);
            mPaint.setStrokeWidth(2);
            mPaint.setColor(Color.CYAN);
           mPaint.setPathEffect(new ComposePathEffect(new DashPathEffect(new float[] {mSolidLength, mVirtualLength}, mPhase), new CornerPathEffect(mCornerRadius)));
            return;
        }

// Init path
        mPath = new Path();
        mPath.moveTo(10, 100);
        mPath.lineTo(60, 10);
        mPath.lineTo(120, 190);
        mPath.lineTo(180, 40);
        mPath.lineTo(240, 160);
        mPath.lineTo(300, 10);
        mPath.lineTo(360, 190);
        mPath.lineTo(420, 40);
        mPath.lineTo(480, 160);

// Init paint
        mPaint = new Paint();
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeWidth(2);
        mPaint.setColor(Color.CYAN);
       mPaint.setPathEffect(new ComposePathEffect(new DashPathEffect(new float[] {mSolidLength, mVirtualLength}, mPhase), new CornerPathEffect(mCornerRadius)));
    }

@Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawPath(mPath, mPaint);
    }

public void setCornerRadius(int radius) {
        mCornerRadius = radius;
        mPaint.setPathEffect(new ComposePathEffect(new DashPathEffect(new float[]{mSolidLength, mVirtualLength}, mPhase), new CornerPathEffect(mCornerRadius)));
        invalidate();
    }

public int getCornerRadius() {
        return mCornerRadius;
    }

public void setSolidLength(float length) {
        mSolidLength = length;
       mPaint.setPathEffect(new ComposePathEffect(new DashPathEffect(new float[] {mSolidLength, mVirtualLength}, mPhase), new CornerPathEffect(mCornerRadius)));
        invalidate();
    }

public float getSolidLength() {
        return mSolidLength;
    }

public void setVirtualLength(float length) {
        mVirtualLength = length;
       mPaint.setPathEffect(new ComposePathEffect(new DashPathEffect(new float[] {mSolidLength, mVirtualLength}, mPhase), new CornerPathEffect(mCornerRadius)));
        invalidate();
    }

public float getVirtualLength() {
        return mVirtualLength;
    }

public void setPhase(float phase) {
        mPhase = phase;
       mPaint.setPathEffect(new ComposePathEffect(new DashPathEffect(new float[] {mSolidLength, mVirtualLength}, mPhase), new CornerPathEffect(mCornerRadius)));
        invalidate();
    }

public float getPhase() {
        return mPhase;
    }

}

运行结果:

SumPathEffect

核心代码:


package com.zlsam.learngraphics.patheffect;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.CornerPathEffect;
import android.graphics.DashPathEffect;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.SumPathEffect;
import android.util.AttributeSet;
import android.view.View;

/**
 * Created by zhanglong on 16/8/18.
 */
public class SumPathEffectView extends View {

private int mCornerRadius = 0;
    private float mSolidLength = 1F;
    private float mVirtualLength = 1F;
    private float mPhase = 0;
    private Path mPath;
    private Paint mPaint;

public SumPathEffectView(Context context) {
        this(context, null);
    }

public SumPathEffectView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

public SumPathEffectView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

if (isInEditMode()) {
            // Init path
            mPath = new Path();
            mPath.moveTo(10, 100);
            mPath.lineTo(60, 10);
            mPath.lineTo(120, 190);
            mPath.lineTo(180, 40);
            mPath.lineTo(240, 160);
            mPath.lineTo(300, 10);
            mPath.lineTo(360, 190);
            mPath.lineTo(420, 40);
            mPath.lineTo(480, 160);

// Init paint
            mPaint = new Paint();
            mPaint.setStyle(Paint.Style.STROKE);
            mPaint.setStrokeWidth(2);
            mPaint.setColor(Color.CYAN);
           mPaint.setPathEffect(new SumPathEffect(new DashPathEffect(new float[] {mSolidLength, mVirtualLength}, mPhase), new CornerPathEffect(mCornerRadius)));
            return;
        }

// Init path
        mPath = new Path();
        mPath.moveTo(10, 100);
        mPath.lineTo(60, 10);
        mPath.lineTo(120, 190);
        mPath.lineTo(180, 40);
        mPath.lineTo(240, 160);
        mPath.lineTo(300, 10);
        mPath.lineTo(360, 190);
        mPath.lineTo(420, 40);
        mPath.lineTo(480, 160);

// Init paint
        mPaint = new Paint();
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeWidth(2);
        mPaint.setColor(Color.CYAN);
       mPaint.setPathEffect(new SumPathEffect(new DashPathEffect(new float[] {mSolidLength, mVirtualLength}, mPhase), new CornerPathEffect(mCornerRadius)));
    }

@Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawPath(mPath, mPaint);
    }

public void setCornerRadius(int radius) {
        mCornerRadius = radius;
        mPaint.setPathEffect(new SumPathEffect(new DashPathEffect(new float[]{mSolidLength, mVirtualLength}, mPhase), new CornerPathEffect(mCornerRadius)));
        invalidate();
    }

public int getCornerRadius() {
        return mCornerRadius;
    }

public void setSolidLength(float length) {
        mSolidLength = length;
       mPaint.setPathEffect(new SumPathEffect(new DashPathEffect(new float[] {mSolidLength, mVirtualLength}, mPhase), new CornerPathEffect(mCornerRadius)));
        invalidate();
    }

public float getSolidLength() {
        return mSolidLength;
    }

public void setVirtualLength(float length) {
        mVirtualLength = length;
       mPaint.setPathEffect(new SumPathEffect(new DashPathEffect(new float[] {mSolidLength, mVirtualLength}, mPhase), new CornerPathEffect(mCornerRadius)));
        invalidate();
    }

public float getVirtualLength() {
        return mVirtualLength;
    }

public void setPhase(float phase) {
        mPhase = phase;
       mPaint.setPathEffect(new SumPathEffect(new DashPathEffect(new float[] {mSolidLength, mVirtualLength}, mPhase), new CornerPathEffect(mCornerRadius)));
        invalidate();
    }

public float getPhase() {
        return mPhase;
    }
}

运行结果:

本文的示例源码下载地址:https://github.com/zhanglong1/AndroidGraphicsDemo

时间: 2024-11-10 14:00:54

Android Graphics之PathEffect的相关文章

Android Paint之PathEffect详解

尊重原创,转载请标明出处    http://blog.csdn.net/abcdef314159 在之前讲Android Paint的使用详解的时候,其中有一个方法setPathEffect(PathEffect effect)没有详细介绍,这篇就结合代码来介绍一下,在之前说过PathEffect共有6个子类ComposePathEffect,CornerPathEffect,DashPathEffect,DiscretePathEffect,PathDashPathEffect,SumPat

Android图形之PathEffect类

1.PathEffect API示例给出了如何应用每一种效果的指导说明.到目前为止,所有的效应都会影响到Paint填充图像的方式:PathEffect是用来控制绘制轮廓(线条)的方式. PathEffect对于绘制Path基本图形特别有用,但是它们也可以应用到任何Paint中从而影响线条绘制的方式. 使用PathEffect,可以改变一个形状的边角的外观并且控制轮廓的外表.Android包含了多个PathEffect,包括: CornerPathEffect  可以使用圆角来代替尖锐的角从而对基

Android中android.graphics下面的绘制图形类Canvas,Paint,Bitmap,Drawable

1.概念区别: 很多网友刚刚开始学习Android平台,对于Drawable.Bitmap.Canvas和Paint它们之间的概念不是很清楚, 其实它们除了Drawable外早在Sun的J2ME中就已经出现了,但是在Android平台中,Bitmap.Canvas相关的都有所变化. 首先让我们理解下Android平台中的显示类是View,但是还提供了底层图形类android.graphics,今天所说的这些均为graphics底层图形接口. Bitmap - 称作位图,一般位图的文件格式后缀为b

Android开发之parseSdkContent failed Could not initialize class android.graphics.Typeface

在进行android开发过程中,忽然发现经常弹出来parseSdkContent failed 这个错误,然后google了下解决办法 方法1: 删除.android文件 重启eclipse. 该方法对我来说还是管用的,确实没有弹出这些东西了.但是在启用SDK Manger或者虚拟机的时候,弹出了parseSdkContent failed Could not initialize class android.graphics.Typeface这个问题,解决google吧. 然后在stackov

android Graphics( 五):drawText()详解

前言:但行好事,莫问前程.只需努力每一天. 一.概述 1.四线格与基线 小时候,我们在刚开始学习写字母时,用的本子是四线格的,我们必须把字母按照规则写在四线格内.比如: 那么问题来了,在canvas在利用drawText绘制文字时,也是有规则的,这个规则就是基线!我们先来看一下什么是基线: 可见基线就是四线格中的第三条线!也就是说,只要基线的位置定了,那文字的位置必然是定了的! 2.canvas.drawText() (1).canvas.drawText()与基线 下面我们来重新看看canva

android.graphics包简介

Tip android.graphics 包 Abstract android.graphics 包android提供的2D开发包,它提供了一些初级图形工具,诸如画布.颜色过滤器.画 笔等 Usage surfaceview结合graphics包可以创建自定义控件 MyTick 绘图时可以想想自己在一个绘图软件中绘画,在一块画布(canvas)上,使用自己调好的笔(Paint)画线(Path)画形状(drawRect drawOval),插入想要的图片(drawBitmap),插入想要的特定格式

《Pro Android Graphics》读书笔记之第六节

Android UI Layouts: Graphics Design Using the ViewGroup Class Android ViewGroup Superclass: A Foundation for Layouts The ViewGroup LayoutParams Class: Layout Parameters Deprecated Layouts: AbsoluteLayout and SlidingDrawer absoluteLayout 3 version 1.5

Android Graphics专题(1)--- Canvas基础

作为Android Graphics专题的开篇,毫无疑问,我们将讨论Android UI技术的核心概念--Canvas. Canvas是Android UI框架的基础,在Android的控件体系中,所有容器类.控件类在实现上都依赖于Canvas,界面的绘制实质上都是Canvas绘制的.本文将讨论Canvs的由来,并通过实例展示Canvas的基础用法. 对于应用开发而言,我们可以不去深究Canvas与Android 控件体系的实现细节,但明白Canvas与控件的关联有助于我们更好的使用Canvas

《Pro Android Graphics》读书笔记之第二节

Android Digital Video: Formats, Concepts and Optimization Android Digital Video Formats: MPEG4 H.264 and WebM VP8 H.263 支持老显示器 MPEG4 SP   supported for commercial video(支持商业视频) 3GP Google在2.3.3中加入对WebM的支持 video Stream 4.0以后版本 recommend using MPEG-4 H