圖形圖形,自定義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);


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM