下載本文檔
版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、自定義view實(shí)現(xiàn)圓角圖片前兩天想實(shí)現(xiàn)一個(gè)圓角圖片的效果,通過網(wǎng)絡(luò)搜索后找到一些答案。這里自己再記錄一下,加深一下自己的認(rèn)識(shí)和知識(shí)理解。實(shí)現(xiàn)圓角圖片的思路是自定義一個(gè)ImageView,然后通過Ondraw()重繪的功能,將drawable和一個(gè)圓形進(jìn)行重疊繪制,這樣就可以達(dá)到圓角的效果了。下面開始具體實(shí)現(xiàn)圓角圖片的過程。第一步:寫自定義屬性文件首先我們需要定義一個(gè)屬性。在values目錄下面新建一個(gè)xml文件,這個(gè)文件用來自定義一些屬性,這樣我們就可以寫出自己的控件了。12345678910我來簡(jiǎn)單解釋一下,declare-styleable這個(gè)標(biāo)簽就是用來自定義屬性的,attr標(biāo)簽用來定義
2、具體的屬性,format可以指定很多種格式,具體有哪些屬性,這里不做過多介紹了,請(qǐng)看博客中的介紹://mayingcai1987/article/details/6216655。在本例子中dimension表示尺寸的意思,這個(gè)應(yīng)該在平常的開發(fā)中也用到。同時(shí)還有一個(gè)enum的枚舉類型,我們之前在用系統(tǒng)控件的時(shí)候,比如android:orientation=vertical就是比較典型的枚舉類型,只不過在本例中我們自己實(shí)現(xiàn)了這個(gè)枚舉類型。定義好這個(gè)之后,我們就可以開始寫我們的自定義view的代碼了。最后注意的一點(diǎn),這里的這個(gè)xml的名字可以隨便命名(不過最好命名的比較有意
3、義),android系統(tǒng)會(huì)自動(dòng)找到的。第二步,自定義View這一步是本文中最重要的一步,也是實(shí)現(xiàn)自定義view的核心。那么我們從目的出發(fā)來探討實(shí)現(xiàn)圓角image的方式。那么我們的目的是將圖片變圓,在這里一般人可能有想到兩種方式將圖片變圓 1.把本來圖片修改為圓形,其他地方都是透明2.只是讓顯示的時(shí)候,動(dòng)態(tài)的裁剪到一些部分,然后讓圖片變圓。這兩種方法的優(yōu)劣我想大家一眼就能看明白。直接修改圖片,帶來的后果是,我如果換了一種方式了,不再是圓角,而是星型,那么我們的圖片已經(jīng)毀掉了,沒辦法在重用了。而第二種方式就可以,無論我們換什么樣的表現(xiàn)方式,我們是需要換一種裁剪的算法,就可以實(shí)現(xiàn)不同的形狀的圖片了,
4、那么很顯然,第二種方法是以不變應(yīng)萬變的。那么現(xiàn)在,我們選定了第二種方式,那怎么實(shí)現(xiàn)呢?有人說我們自己寫一個(gè)類,直接繼承自view,然后所有的繪圖和大小的計(jì)算我們都自己來搞,這樣行嗎?當(dāng)然可行,但是我們可能是在重復(fù)造輪子,因?yàn)槲覀円呀?jīng)有了一個(gè)ImageView,而且它里面給我們做了很多關(guān)于圖片的操作,我們何不繼承自ImageView,然后做少量的工作,就可以實(shí)現(xiàn)圓角效果呢。方案確定,好,那我們就開始實(shí)現(xiàn)自己的類。1public class RoundImageView extends ImageView 我們定義一個(gè)RoundImageView 繼承自ImageView12private int
5、 mBorderRadius;private int mType;然后兩個(gè)成員變量,分別對(duì)應(yīng)于自定義屬性文件中的BorderRadius和RoundType。接下來我們重寫構(gòu)造函數(shù)12345678910111213public RoundImageView(Context context, AttributeSet attrs) super(context, attrs);mPaint = new Paint(); mPaint.setAntiAlias(true);TypedArray a = context.obtainStyledAttributes(attrs,R.styleable.
6、RoundImageAttrs);mBorderRadius = a.getDimensionPixelSize(R.styleable.RoundImageAttrs_BorderRadius,(int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 10, getResources().getDisplayMetrics();mType = a.getInt(R.styleable.RoundImageAttrs_RoundType,0);a.recycle();Log.i(Log,mBorderRadius:+mBorderR
7、adius+type:+mType);首先是mPaint的初始化,這是一個(gè)畫刷,用來畫圖形的,后面會(huì)說。接下來是最為關(guān)鍵的代碼,context.obtainStyledAttributes(attrs,R.styleable.RoundImageAttrs),這句代碼用來獲取控件上的自定義屬性。然后下面兩句12mBorderRadius = a.getDimensionPixelSize(R.styleable.RoundImageAttrs_BorderRadius,(int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 10,
8、 getResources().getDisplayMetrics();mType = a.getInt(R.styleable.RoundImageAttrs_RoundType,0);分別獲取這兩個(gè)屬性的值,第一個(gè)比較復(fù)雜,涉及到默認(rèn)值單位的轉(zhuǎn)換,(這里10的代表默認(rèn)值)第二個(gè)就是獲取RoundImageAttrs_RoundType,獲取完畢后,記得一定要調(diào)用a.recycle();對(duì)資源進(jìn)行釋放。以便后面的其他代碼可以訪問這些屬性資源。(理解的不透徹,但記住釋放就ok)到現(xiàn)在為止我們完成了萬里長(zhǎng)征第一步,獲取到了我們自定義控件的屬性了。接下來就是我們的重頭戲,重繪圖片。下面我們重寫了O
9、nDraw函數(shù)1234567891011121314151617181920212223242526272829303132333435Overrideprotected void onDraw(Canvas canvas) /super.onDraw(canvas);Bitmap bitmap = mWeakBitmap = nullnull:mWeakBitmap.get();if(bitmap = null | bitmap.isRecycled() Drawable drable = getDrawable();int width = drable.getIntrinsicWidth(
10、);int height = drable.getIntrinsicHeight();if(drable!=null)bitmap = Bitmap.createBitmap(getWidth(),getHeight(),Config.ARGB_8888);Canvas dcanvas = new Canvas(bitmap);drable.draw(dcanvas);if(mMashBitmap = null | mMashBitmap.isRecycled()mMashBitmap = getShapeBitmap();mPaint.reset();mPaint.setFilterBitm
11、ap(false);mPaint.setXfermode(mXfermode);dcanvas.drawBitmap(mMashBitmap, 0,0, mPaint);mPaint.setXfermode(null);canvas.drawBitmap(bitmap, 0,0, null);mWeakBitmap = new WeakReference(bitmap); elsemPaint.setXfermode(null);canvas.drawBitmap(bitmap, 0,0, null);return;上面的代碼可能第一次看比較迷惑,各種paint還有canvas,drawabl
12、e,各種區(qū)分不清。下面我結(jié)合代碼都說說。1Bitmap bitmap = mWeakBitmap = nullnull:mWeakBitmap.get();這句話是從一個(gè)弱引用中取得Bitmap圖像,我們?cè)诔晒?chuàng)建圓形圖像后,會(huì)保存起來,以供后面刷新使用。接下來我們判斷bitmap,如果為空說明還沒有創(chuàng)建過。接下來我們通過getDrawable();獲取當(dāng)前ImageView的drawable,里面包含了原本的圖像。下面我們創(chuàng)建了一個(gè)臨時(shí)的Bitmap對(duì)象,這個(gè)對(duì)象將保存經(jīng)過我們處理之后的圖像bitmap = Bitmap.createBitmap(getWidth(),getHeight()
13、,Config.ARGB_8888); 然后我們創(chuàng)建一個(gè)Canvas dcanvas = new Canvas(bitmap); drable.draw(dcanvas); 通過drawable的draw方法將原來ImageView的圖像繪制到dcanvas上(其實(shí)也是畫到bitmap上)。接下來我們獲取圖形(這里是圓形,后面大家可以自己定義形狀)mMashBitmap = getShapeBitmap();(這個(gè)函數(shù)我們后面介紹),然后我們?cè)O(shè)置了paint的屬性 private Xfermode mXfermode = new PorterDuffXfermode(Mode.DST_IN);
14、 mPaint.setXfermode(mXfermode);這個(gè)mXfermode代表的意思是,當(dāng)用paint畫圖時(shí),新繪制的圖像與原圖像的關(guān)系。給大家一張圖,就很容易理解各種繪制方式了。1,在本例子中用的就是DST_IN,想必這張圖一看就明白。paint配置完后,我們就開始將新的形狀繪制到原來的圖像上1dcanvas.drawBitmap(mMashBitmap, 0,0, mPaint); 此時(shí),bitmap中保存的就是疊加之后的圖片了,也就是我們最終需要的圓角圖片了。最后我們將這個(gè)bitmap繪制到OnDraw函數(shù)給我們傳遞進(jìn)來的canvas上,所有工作就基本做完了。canvas.dr
15、awBitmap(bitmap, 0,0, null);最后將繪制好的圖片保存起來。mWeakBitmap = new WeakReference(bitmap);下一次執(zhí)行ondraw 的時(shí)候,我們就直接用保存好的bitmap進(jìn)行繪制了,也就是我們代碼中else的部分。最艱難的部分說完了,哈哈,如果不理解還是得多看幾遍。接下來的工作就輕松了很多,對(duì)了,我們還沒有實(shí)現(xiàn)之前那個(gè)繪制形狀的函數(shù)呢。我們來繪制把。很容易的。1234567891011121314private Bitmap getShapeBitmap()Bitmap bit = Bitmap.createBitmap(getWidt
16、h(),getHeight(),Config.ARGB_8888);Canvas can = new Canvas(bit);Paint pa = new Paint(Paint.ANTI_ALIAS_FLAG);pa.setColor(Color.BLACK);if(mType = 0)can.drawCircle(getWidth()/2, getHeight()/2, mBorderRadius, pa);return bit;看看上面的代碼,是不是很熟悉,我們之前已經(jīng)接觸過基本的畫圖方法了。想必,不用解釋了,一眼都能看明白。這里我只實(shí)現(xiàn)了畫圓的,大家可以各自發(fā)揮想想,畫出各種各樣的形狀,哈哈,是不是很容易,我們自己實(shí)現(xiàn)了圓角圖像,同時(shí)對(duì)于android自定義view的繪制也有了大致了解。對(duì)了,這里面還有一個(gè)問題,如果用戶想動(dòng)態(tài)修改圖片怎么辦,我們?cè)趦?nèi)存里面保存了一個(gè)舊的圖片,該怎么更新呢。其實(shí)好辦,我們只需要做下面的操作就行123
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 企業(yè)生產(chǎn)事故調(diào)查制度
- 郵政安全生產(chǎn)懲罰制度
- 生產(chǎn)車間垃圾分類制度
- 藥品生產(chǎn)經(jīng)營(yíng)管理制度
- 制漿造紙安全生產(chǎn)管理制度
- 租賃站安全生產(chǎn)責(zé)任制度
- 制造業(yè)安全生產(chǎn)考核制度
- 生產(chǎn)車間制造安裝現(xiàn)場(chǎng)管理制度
- 針織廠生產(chǎn)質(zhì)量管理制度
- 生產(chǎn)耗工管理制度及流程
- 蓬深102井鉆井工程(重新報(bào)批)項(xiàng)目環(huán)境影響報(bào)告表
- 大模型金融領(lǐng)域可信應(yīng)用參考框架
- (新教材)2025年人教版七年級(jí)上冊(cè)歷史期末復(fù)習(xí)??贾R(shí)點(diǎn)梳理復(fù)習(xí)提綱(教師版)
- 中國(guó)全色盲診療專家共識(shí)2026
- 鋼鐵工藝流程課件
- 自流平地面施工安全方案
- 2025年小學(xué)六年級(jí)數(shù)學(xué)試題探究題
- 紋樣設(shè)計(jì)上課課件
- 密閉施工安全培訓(xùn)課件
- 人工智能賦能循證教學(xué)研究
- 建筑工程勞務(wù)人員管理制度與實(shí)施策略
評(píng)論
0/150
提交評(píng)論