自定義View-第五步:繪制圖片

前言

根據(jù)Gcssloop所學(xué)習(xí)的自定義View整理與筆記驾茴。

準(zhǔn)備

** 禁用GPU硬件加速**

  1. 在AndroidManifest.xml文件為application標(biāo)簽添加如下的屬性即可為整個(gè)應(yīng)用程序開啟/關(guān)閉硬件加速:
<application android:hardwareAccelerated="false" ...>
  1. 在Activity 標(biāo)簽下使用 hardwareAccelerated 屬性開啟或關(guān)閉硬件加速:
<activity android:hardwareAccelerated="false" />  
  1. 在Window 層級(jí)使用如下代碼開啟硬件加速:(Window層級(jí)不支持關(guān)閉硬件加速)
getWindow().setFlags(  
WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED,  
WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED); 
  1. View 級(jí)別如下關(guān)閉硬件加速:(view 層級(jí)上不支持開啟硬件加速)
setLayerType(View.LAYER_TYPE_SOFTWARE, null);

或者使用android:layerType=”software”來關(guān)閉硬件加速

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
    android:layout_width="fill_parent"  
    android:layout_height="fill_parent"  
    android:orientation="vertical"  
    android:paddingLeft="2dp"  
    android:layerType="software"  
    android:paddingRight="2dp" >  

一哑蔫、drawPicture:錄制Canvas中繪制的內(nèi)容

** 使用Picture前請(qǐng)關(guān)閉硬件加速,以免引起不必要的問題!**
詳情請(qǐng)進(jìn)入這里->Android的硬件加速及可能導(dǎo)致的問題

首先乃沙,了解一下Picture的方法吧~

public int getWidth ()//獲取寬度
public int getHeight ()//獲取高度
public Canvas beginRecording (int width, int height)//開始錄制 (返回一個(gè)Canvas熬甫,在Canvas中所有的繪制都會(huì)存儲(chǔ)在Picture中)
public void endRecording ()//結(jié)束錄制
public void draw (Canvas canvas)//將Picture中內(nèi)容繪制到Canvas中

現(xiàn)在開始使用啦?(?*)

  1. 第一步:使用Picture錄制內(nèi)容
//錄制內(nèi)容
private void recording() {
    Canvas canvas = picture.beginRecording(500, 500);
    canvas.translate(250, 250);
    canvas.drawCircle(0, 0, 100, paint);
    picture.endRecording();
}
  • 第二步:將錄制的內(nèi)容顯示出來(三種方式)
    1. 使用Picture提供的draw方法繪制。
// 將Picture中的內(nèi)容繪制在Canvas上,一般不使用 
       picture.draw(canvas);

效果圖為:


  1. 使用Canvas提供的drawPicture方法繪制试读,會(huì)縮放杠纵。
public void drawPicture (Picture picture)
public void drawPicture (Picture picture, Rect dst)
public void drawPicture (Picture picture, RectF dst)

舉個(gè)栗子:

        paint.setColor(Color.RED);
        canvas.drawRect(0, 0, 100, 200, paint);
        paint.setColor(Color.BLACK);
        canvas.drawPicture(picture, new RectF(0, 0, 100, 200));

效果圖為:


**繪制的內(nèi)容根據(jù)選區(qū)進(jìn)行了縮放**
  1. 將Picture包裝成為PictureDrawable,使用PictureDrawable的draw方法繪制钩骇,不會(huì)縮放淡诗。
  paint.setColor(Color.RED);
  canvas.drawRect(0, 0, 250, picture.getHeight(), paint);
 paint.setColor(Color.BLACK);
 // 包裝成為Drawable
 PictureDrawable drawable = new PictureDrawable(picture);
// 設(shè)置繪制區(qū)域 -- 注意此處所繪制的實(shí)際內(nèi)容不會(huì)縮放
drawable.setBounds(0, 0, 250, picture.getHeight());
// 繪制
drawable.draw(canvas);

效果圖:


此處setBounds是設(shè)置在畫布上的繪制區(qū)域,并非根據(jù)該區(qū)域進(jìn)行縮放伊履,也不是剪裁Picture韩容,每次都從Picture的左上角開始繪制

ps:三種方法的主要區(qū)別:
是否對(duì)Canvas有影響: 1有影響;2,3不影響
此處指繪制完成后是否會(huì)影響Canvas的狀態(tài)(Matrix clip等)
可操作性強(qiáng)弱: 1可操作性較弱;2,3可操作性較強(qiáng)
此處的可操作性可以簡(jiǎn)單理解為對(duì)繪制結(jié)果可控程度。

接下來上代碼嘍

二唐瀑、drawBitmap

看到bitmap有點(diǎn)怕怕的群凶,哈哈,內(nèi)存泄漏的大麻煩啊哄辣,GcsSloop簡(jiǎn)單的講解了一下请梢,那我也跟著簡(jiǎn)單的學(xué)一下講一下吧赠尾,嘿嘿
1.第一步:通過BitmapFactory從不同位置獲取Bitmap

//資源文件(drawable/mipmap/raw)中獲取
Bitmap bitmap = BitmapFactory.decodeResource(mContext.getResources(),R.raw.bitmap);
//資源文件(assets)
Bitmap bitmap=null;
try {
 InputStream is = mContext.getAssets().open("bitmap.png");
 bitmap = BitmapFactory.decodeStream(is);
 is.close();
} catch (IOException e) {
 e.printStackTrace();
}
//內(nèi)存卡文件
Bitmap bitmap = BitmapFactory.decodeFile("/sdcard/bitmap.png");
//網(wǎng)絡(luò)文件
Bitmap bitmap = BitmapFactory.decodeStream(is);
is.close();

2.第二步:繪制Bitmap

  1. 第一種
/** * Draw the bitmap using the specified matrix. * 
* @param bitmap The bitmap to draw
 * @param matrix The matrix used to transform the bitmap when it is drawn
 * @param paint  May be null. The paint used to draw the bitmap
 */
public void drawBitmap(@NonNull Bitmap bitmap, @NonNull Matrix matrix, @Nullable Paint paint) {
    nativeDrawBitmapMatrix(mNativeCanvasWrapper, bitmap, matrix.ni(),            
paint != null ? paint.getNativeInstance() : 0);
}

demo:

canvas.drawBitmap(bitmap,new Matrix(),new Paint());

2.第二種

 /** 
* @param bitmap The bitmap to be drawn
 * @param left   The position of the left side of the bitmap being drawn 
* @param top    The position of the top side of the bitmap being drawn 
* @param paint  The paint used to draw the bitmap (may be null) 
*/
public void drawBitmap(@NonNull Bitmap bitmap, float left, float top, @Nullable Paint paint) {
    throwIfCannotDraw(bitmap);
    native_drawBitmap(mNativeCanvasWrapper, bitmap, left, top, 
           paint != null ? paint.getNativeInstance() : 0, mDensity, mScreenDensity, bitmap.mDensity);
}

**left、top:此處指定的是與坐標(biāo)原點(diǎn)的距離毅弧,并非是與屏幕頂部和左側(cè)的距離, 雖然默認(rèn)狀態(tài)下兩者是重合的气嫁,但是也請(qǐng)注意分別兩者的不同。
**

demo:

canvas.drawBitmap(bitmap,200,200,new Paint());

3.第三種

 /* 
@param bitmap The bitmap to be drawn 
* @param src    May be null. The subset of the bitmap to be drawn
 * @param dst    The rectangle that the bitmap will be scaled/translated to fit into
 * @param paint  May be null. The paint used to draw the bitmap
 */
public void drawBitmap(@NonNull Bitmap bitmap, @Nullable Rect src, @NonNull Rect dst,        @Nullable Paint paint);

demo:

// 將畫布坐標(biāo)系移動(dòng)到畫布中央
canvas.translate(200, 200);
// 指定圖片繪制區(qū)域(左上角的四分之一)
Rect src = new Rect(0, 0, bitmap.getWidth() / 2, bitmap.getHeight() / 2);
// 指定圖片在屏幕上顯示的區(qū)域
Rect dst = new Rect(0, 0, 100, 200);
// 繪制圖片
canvas.drawBitmap(bitmap, src, dst, null);
效果
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末够坐,一起剝皮案震驚了整個(gè)濱河市寸宵,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌元咙,老刑警劉巖梯影,帶你破解...
    沈念sama閱讀 219,490評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異庶香,居然都是意外死亡甲棍,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,581評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門赶掖,熙熙樓的掌柜王于貴愁眉苦臉地迎上來感猛,“玉大人,你說我怎么就攤上這事奢赂〕猓” “怎么了?”我有些...
    開封第一講書人閱讀 165,830評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵呈驶,是天一觀的道長(zhǎng)拷泽。 經(jīng)常有香客問我,道長(zhǎng)袖瞻,這世上最難降的妖魔是什么司致? 我笑而不...
    開封第一講書人閱讀 58,957評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮聋迎,結(jié)果婚禮上脂矫,老公的妹妹穿的比我還像新娘。我一直安慰自己霉晕,他們只是感情好庭再,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,974評(píng)論 6 393
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著牺堰,像睡著了一般拄轻。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上伟葫,一...
    開封第一講書人閱讀 51,754評(píng)論 1 307
  • 那天恨搓,我揣著相機(jī)與錄音,去河邊找鬼。 笑死斧抱,一個(gè)胖子當(dāng)著我的面吹牛常拓,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播辉浦,決...
    沈念sama閱讀 40,464評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼弄抬,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了宪郊?” 一聲冷哼從身側(cè)響起掂恕,我...
    開封第一講書人閱讀 39,357評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎废膘,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體慕蔚,經(jīng)...
    沈念sama閱讀 45,847評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡丐黄,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,995評(píng)論 3 338
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了孔飒。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片灌闺。...
    茶點(diǎn)故事閱讀 40,137評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖坏瞄,靈堂內(nèi)的尸體忽然破棺而出桂对,到底是詐尸還是另有隱情,我是刑警寧澤鸠匀,帶...
    沈念sama閱讀 35,819評(píng)論 5 346
  • 正文 年R本政府宣布蕉斜,位于F島的核電站,受9級(jí)特大地震影響缀棍,放射性物質(zhì)發(fā)生泄漏宅此。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,482評(píng)論 3 331
  • 文/蒙蒙 一爬范、第九天 我趴在偏房一處隱蔽的房頂上張望父腕。 院中可真熱鬧,春花似錦青瀑、人聲如沸璧亮。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,023評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽枝嘶。三九已至,卻和暖如春哑诊,著一層夾襖步出監(jiān)牢的瞬間躬络,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,149評(píng)論 1 272
  • 我被黑心中介騙來泰國(guó)打工搭儒, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留穷当,地道東北人提茁。 一個(gè)月前我還...
    沈念sama閱讀 48,409評(píng)論 3 373
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像馁菜,于是被迫代替她去往敵國(guó)和親茴扁。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,086評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容