图形图形,自定义View

1.Drawable


Drawable是一个通用的抽象类,它的目的是告诉你什么东西是可以画的
。你会发现基于Drawable类扩展出各种绘图的类包括:BitmapDrawable、
ShapeDrawable、PictureDrawable、LayerDrawable,当然你可以继承它来
创建你自己的绘图类。
定义和实例化一个Drawable
从资源图像文件中创建
从XML文件中创建


1)从资源图像文件中创建


    一个比较简单的方法是添加一个图片到你的程序中,然后通过资源文件引用这个文件,支持的文件类型有PNG(首选的) JPG(可接受的)GIF(不建议)。
    图片资源添加到res/drawable/目录中
引用它到你的代码或你的XML布局中
引用它也可以用资源编号

在layout布局中,通过@drawable/xxx来引用drawable一个图像文件。

<ImageView 
        android:id="@+id/image"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
           android:src="@drawable/ic_launcher"
        />

在java代码中
ImageView image = (ImageView) findViewById(R.id.image);
image.setBackgroundResource(R.drawable.ic_launcher);

ps:如何获取 res 中的资源
主要类:Resources(android.content.res包)
Resources r = this.getContext().getResources();
主要方法:
getXXXX()
例如:
int getColor(int id)
Drawable getDrawable(int id)
String getString(int id) 直接获取res中存放的资源
String[] getStringArray(int id)//获取一个String数组
InputStream openRawResource(int id)? 获取资源的数据流,
                              读取资源数据
void parseBundleExtras(XmlResourceParser parser, Bundle outBundle)从
XML文件中获取数据

2)从XML文件中创建


    图片资源添加到res/drawable/目录中
在XML中定义Drawable
引用它也可以用资源编号

下边代码定义了TransitionDrawable的使用:

<?xml version="1.0" encoding="utf-8"?>
<transition xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/ic_launcher"/>
    <item android:drawable="@drawable/a"/>
</transition>

可以在layout布局中,设置ImageView的background属性:

android:background="@drawable/mydrawwable"

在代码中

Drawable d = image.getBackground();
TransitionDrawable td = (TransitionDrawable)d;
td.startTransition(2000);//实现两张图片间切换

设置background

Resources res = getResources();
TransitionDrawable ttd = (TransitionDrawable) res.getDrawable(R.drawable.mydrawable);
image.setBackgroundDrawable(ttd);


2.

1)如何自定义一个View


step1.写一个类,继承View,或者你要扩展那个控件类
step2.提供构造方法:
有三个:
public View(Context context) {}//构造函数往往用在new xxxView()中
后边两种构造方法,是由系统调用。它自动把xml属性赋值给AttributeSet
public View(Context context, AttributeSet attrs) {}
public View(Context context, AttributeSet attrs, int defStyle){}
step3.
方式A.在layout的xml文件中

<com.anjoyo.view.CustomView
        android:id="@+id/cv"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:background="#ffffff"
        />

此时提供下边两种构造方法。

方式B.在java代码中直接new

protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        CustomView cv = new CustomView(this);
        setContentView(cv);
    }

此时必须提供一个参数那个构造方法。

3.ShapeDrawable使用


如画一个椭圆

public class CustomView extends View {
    public CustomView(Context context) {
        super(context);
    }
    @Override
    protected void onDraw(Canvas canvas) {
        ShapeDrawable sd = new ShapeDrawable(new OvalShape());
        Paint paint = sd.getPaint();
        paint.setColor(Color.RED);
        sd.setBounds(10, 10, 300+10, 100+10);
        sd.draw(canvas);
    }
}

4.NinePatchDrawable


NinePatchDrawable 绘画的是一个可以伸缩的位图图像,
Android会自动调整大小来容纳显示的内容。
NinePatchDrawable是一个标准的PNG图像,它包括额外
的1个像素的边界,你必须保存它后缀为.9.png,并且保
持到工程的res/drawable目录中。
    Android提供绘制工具,在sdk/tools/draw9patch.bat

==========================================

5.Bitmap和BitmapFactory


Bitmap
方式1: 建立空的Bitmap
   

Bitmap vBitmap=Bitmap.createBitmap(vWidth,vHeight,<Bitmap.Config>);

方式2: 取得Resource 的Bitmap
   
Bitmap vBitmap=BitmapFactory.decodeResource(vContext.getResources(),R.drawable.<drawable_name>);
如:Bitmap bitmap = BitmapFactory
                        .decodeResource(getResources(), R.drawable.ic_launcher);
方式3: 取得图档的Bitmap
   
Bitmap vBitmap=BitmapFactory.decodeStream(vContentResolver.openInputStream(uri));

要获取位图信息,比如位图大小、像素、density、透明度、
颜色格式等,获取得到Bitmap就迎刃而解了,这里只是辅
助说明以下2点:
在Bitmap中对RGB颜色格式使用Bitmap.Config定义,
仅包括ALPHA_8、ARGB_4444、ARGB_8888、RGB_565,
缺少了一些其他的,比如说RGB_555,在开发中可能需
要注意这个小问题;
Bitmap还提供了compress()接口来压缩图片,不过
Android SDK只支持PNG、JPG格式的压缩;其他格式
的需要Android开发人员自己补充了。

----ps:
注意ImageView android:background和android:src区别
android:background是设置ImageView的背景
在java代码中:
设置:
setBackgroundResource(int resID)、setBackgroundDrawable(Drawable drawable)
、setBackgroundColor(int color)
获取:
getBackground() 返回值为Drawable对象

android:src指的是ImageView显示的图像
在java代码中:
设置:
iv.setImageBitmap(bm)
iv.setImageResource()
iv.setImageDrawable()
获取:
iv.getDrawable()
...


代码:

Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);
ImageView iv = (ImageView) findViewById(R.id.image);
iv.setImageBitmap(bitmap);

Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);
BitmapDrawable bd = new BitmapDrawable(bitmap);
ImageView iv = (ImageView) findViewById(R.id.image);
iv.setImageDrawable(bd);

6.绘图-Canvas、Paint、Path
Canvas
在Android中,把Canvas当做画布,可以在画布上绘制我们想要的任何东西。

方法:
clipXXX
裁剪,通过Path, Rect ,Region 的不同组合,几乎可以
支持任意现状的裁剪区域。如: ClipPath, ClipRect, ClipRegion
drawXXX
绘制,可绘制图片,图形等。如:drawBtimap、drawLine
save()
方法作用:用来保存canvas状态的。save()时可以得到一个
返回值,是用来确定保存时间的。使用restoreToCount()
方法时可以把此值当参数传递,可以还原到指定的保存
时间。
restore()
方法作用:用来恢复canvas状态的,还原到上一次savie()
时的状态。
translate()
translate(float dx,float dy);
方法作用:移动canvas和它的原点到不同的位置上。
默认原点坐标为(0,0)
    参数:dx,左右偏移量(正数是向右移动)
        dy,上下偏移量(正数是向下移动)
rotate()
rotate(float degrees);
方法作用:以原点为中心对canvas旋转。
默认原点坐标为(0,0)
    参数:degrees 旋转弧度
scale()
scale(float sx,float sy);
方法作用:增减图形在canvas中的像素数目,对形状,位图
进行缩小或者放大。
    参数:sx,横轴缩放大小
       sy,数轴缩放大小
scale(float sx,float sy, float px, float py);
        px,设置原点的位置(与rotate中的px正好相反,正数是向左移动)
        py,设置原点的位置(与rotate中的py正好相反,正数是向上移动)

Paint
Paint类包含样式和颜色有关如何绘制几何形状,文本和位图的信息。Canvas是一块画布,具体的文本和位图如何显示,这就是在Paint类中定义了。
Paint有哪些功能?
    字体、大小(TextSize)、颜色 (TextColor)、对齐方式(TextAlign)、粗体(Bold)、斜体(Italic)、下划线(Underline)等
    字体类型:Typeface类——(BOLD,BOLD_ITALIC,ITALIC,NORMAL)
使用Paint显示String
    Paint p = new Paint();
    String familyName = “宋体”;
    Typeface font = Typeface.create(familyName,Typeface.BOLD);
    p.setColor(Color.RED);
    p.setTypeface(font);
    p.setTextSize(22);
    canvas.drawText(mstrTitle,0,100,p);

ps:

如何访问assets文件夹下的资源:


step1.获取Resources对象

Resources res = getResources();

step2.获取AssetManager对象
AssetManager am = res.getAsset();

例子:

public class PaintTestView extends View {

    public PaintTestView(Context context) {
        super(context);
    }
    @Override
    protected void onDraw(Canvas canvas) {
        Paint paint = new Paint();
        paint.setColor(Color.RED);
        AssetManager am = getResources().getAssets();
        Typeface.createFromAsset(am, "a/b/ff.t");
        Typeface typeface = Typeface.create("黑体", Typeface.ITALIC);
        paint.setTypeface(typeface);
        paint.setTextSize(22);
        canvas.drawText("你好", 100, 100, paint);
    }
}

 

 

补充

1.使用BitmapFactory获取位图
decodeStream(InputStream is)
decodeResource(Resources res,int resId)
BitmapFactory的所有函数都是static,这个辅助类可以通过资源ID、路径、文件、数据流等方式来
获取位图。


2.Canvas
在Android中,把Canvas当做画布,可以在画布上绘制我们想要的任何东西。

方法:
clipXXX
裁剪,通过Path, Rect ,Region 的不同组合,几乎可以支持
任意形状的裁剪区域。如: ClipPath, ClipRect,
ClipRegion
 
drawXXX
绘制,可绘制图片,图形等。
如:drawBtimap、drawLine

save()
方法作用:用来保存canvas状态的。
save()时可以得到一个返回值,是用来确定保存时间的。
使用restoreToCount()方法时可以把此值当参数传递,
可以还原到指定的保存时间。

restore()
方法作用:用来恢复canvas状态的,还原到上一次
save()时的状态。

translate()
translate(float dx,float dy);
方法作用:移动canvas和它的原点到不同的位置上。
默认原点坐标为(0,0)
    参数:dx,左右偏移量(正数是向右移动)
        dy,上下偏移量(正数是向下移动)
       
rotate()
rotate(float degrees);
方法作用:以原点为中心对canvas旋转。默认原点坐标为(0,0)
    参数:degrees 旋转弧度
   
   
scale()
scale(float sx, float sy); 
方法作用:增减图形在canvas中的像素数目,对形状,位图进行缩小或者放大。
    参数:sx,横轴缩放大小
               sy,数轴缩放大小
scale(float sx, float sy, float px, float py);
        px,设置原点的位置(与rotate中的px正好相反,正数是向左移动)
        py,设置原点的位置(与rotate中的py正好相反,正数是向上移动)
       
3.Paint
Paint类包含样式和颜色有关如何绘制几何形状,文本和位图的信息。
Canvas是一块画布,具体的文本和位图如何显示,这就是在Paint类中定义了。

Paint有哪些功能?
    字体、大小(TextSize)、颜色 (TextColor)、对齐方式(TextAlign)、粗体(Bold)、斜体(Italic)、下划线(Underline)等
    字体类型:Typeface类——(BOLD,BOLD_ITALIC,ITALIC,NORMAL)
使用Paint显示String
    Paint p = new Paint();
    String familyName = “宋体”;
    Typeface font = Typeface.create(familyName,Typeface.BOLD);
    p.setColor(Color.RED);
    p.setTypeface(font);
    p.setTextSize(22);
    canvas.drawText(mstrTitle,0,100,p);

4.Path
对于Android游戏开发或者说2D绘图中来讲Path 路径可以用强大这个词来
形容。在Photoshop中我们可能还记得使用钢笔工具绘制路径的方法。
Path路径类在位于 android .graphics.Path中,Path的构造方法比较简单
,如下
Path cwj=new Path();  //构造方法 
下面我们画一个封闭的原型路径,我们使用Path类的addCircle方法
cwj.addCircle(10,10,50,Direction.CW); //参数一为x轴水平位置,
参数二为y轴垂直位置,第三个参数为圆形的半径,最后是绘制的方向,
CW为顺时针方向,而CCW是逆时针方向 (Clock Wise)(Counter Close Wise)


ps.自定义style
<com.anjoyo.view.MyView
        android:layout_width="fill_parent"
        style="@style/myviewstyle"
        />

<style name="myviewstyle">
        <item name="android:layout_height">fill_parent</item>
        <item name="android:background">#ffffff</item>
    </style>
   
5.特效-Matrix、Shader
Matrix
Matrix类拥有一个3x3矩阵转换坐标。
Matrix的操作,总共分为translate(平移),rotate(旋转),scale(缩放
)和skew(倾斜)四种

Matrix 提供set, post和pre三种操作方式,除了translate,其他三种操作
都可以指定中心点。
set是直接设置Matrix的值,每次set一次,整个Matrix的数组都会变掉。
post是后乘,当前的矩阵乘以参数给出的矩阵。可以连续多次使用post,
来完成所需的整个变换。例如,要将一个图片旋转30度,然后平移到(100,
100)的地方,那么可以这样做:
Matrix m = new Matrix();
m.postRotate(30);
m.postTranslate(100, 100);


pre是前乘,参数给出的矩阵乘以当前的矩阵。所以操作是在当前矩阵的最
前面发生的。例如上面的例子,如果用pre的话,就要这样:
    Matrix m = new Matrix();  
    m.setTranslate(100, 100); 
    m.preRotate(30); 
     旋转、缩放和倾斜都可以围绕一个中心点来进行,如果不指定,
     默认情况下,是围绕(0,0)点来进行。
例子:
    @Override
    protected void onDraw(Canvas canvas) {
        Matrix matrix = new Matrix();
       
        //matrix.postRotate(30);
        matrix.postTranslate(100, 100);
        matrix.postRotate(30, getWidth()/2, getHeight()/2);
        canvas.drawBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher), matrix, new Paint());
    }

Shader
Android中提供了Shader类专门用来渲染图像以及一些几何图形

Shader shader = new BitmapShader(…..)
Shader shader = new LinearGradient(…..)

Paint paint = new Paint();
Paint.setShader(shader);


Android中提供了Shader类专门用来渲染图像以及一些几何图形,
Shader下面包括几个直接子类,分别是BitmapShader、
ComposeShader、LinearGradient、RadialGradient、SweepGradient。
BitmapShader主要用来渲染图像,
LinearGradient 用来进行梯度渲染,RadialGradient 用来进行环形渲染,
SweepGradient 用来进行梯度渲染,ComposeShader则是一个 混合渲染,
可以和其它几个子类组合起来使用。
Shader类的使用,都需要先构建Shader对象,然后通过Paint的
setShader方法设置渲染对象,然后设置渲染对象,然后再绘制
时使用这个Paint对象即可。当然,用不同的渲染时需要构建不
同的对象。  下面是一个简单的示例,其实用起来比较简单了
只是方法参数比较多。

例子:
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.a);
BitmapShader bitmapShader = new BitmapShader(bitmap, Shader.TileMode.REPEAT, Shader.TileMode.MIRROR);
ShapeDrawable shapeDrawable = new ShapeDrawable(new OvalShape());
Paint paint = shapeDrawable.getPaint();
paint.setShader(bitmapShader);
/* 设置显示区域 */
shapeDrawable.setBounds(0, 0, 200, 300);
shapeDrawable.draw(canvas);

posted on 2013-01-03 15:02  @与非  阅读(3265)  评论(0编辑  收藏  举报