鴻蒙HarmonyOS App開發(fā)造輪子之自定義圓形圖片組件的實(shí)例代碼
一、背景
在采用Java配合xml布局編寫鴻蒙app頁(yè)面的時(shí)候,發(fā)現(xiàn)sdk自帶的Image組件并不能將圖片設(shè)置成圓形,反復(fù)了翻閱了官方API手冊(cè)(主要查閱了Compont和Image相關(guān)的API),起初發(fā)現(xiàn)了一個(gè)setCornerRadius方法,于是想著將圖片寬度和高度設(shè)置為一樣,然后調(diào)用該方法將radios設(shè)置為寬度或者高度的一半,以為可以實(shí)現(xiàn)圓形圖片的效果,后來發(fā)現(xiàn)不行。于是乎想著能不能通過繼承原有的Image自己來動(dòng)手重新自定義一個(gè)支持圓形的圖片組件。
二、思路:
1、對(duì)比之前自己在其他程序開發(fā)中自定義組件的思路,首先尋找父組件Image和Component相關(guān)的Api,看看是否具備OnDraw方法。
2、了解Canvas相關(guān)Api操作,特別是涉及到位圖的操作。
通過翻閱大量資料,發(fā)現(xiàn)了兩個(gè)關(guān)鍵的api,分別是Component的addDrawTask方法和其內(nèi)部靜態(tài)接口DrawTask
三、自定義組件模塊
1、新建一個(gè)工程之后,創(chuàng)建一個(gè)獨(dú)立的Java FA模塊,然后刪除掉里面所有布局以及自動(dòng)生成的java代碼,然后自己創(chuàng)建一個(gè)class繼承ImageView
2、寫一個(gè)類繼承ImageView,在其中暴露出public的設(shè)置圓形圖片的api方法以供后面調(diào)用;
3、在原有的Image組件獲取到位圖之后,利用該位圖數(shù)據(jù)利用addDrawTask方法配合Canvas進(jìn)行位圖輸出形狀的重新繪制,這里需要使用Canvas的一個(gè)
關(guān)鍵api方法drawPixelMapHolderRoundRectShape;
4、注意,為了讓Canvas最后輸出的圖片為圓形,需要將圖片在布局中的寬度和高度設(shè)置成一樣,否則輸出的為圓角矩形或者橢圓形。
最后封裝后的詳細(xì)代碼如下:
package com.xdw.customview; import ohos.agp.components.AttrSet; import ohos.agp.components.Image; import ohos.agp.render.PixelMapHolder; import ohos.agp.utils.RectFloat; import ohos.app.Context; import ohos.hiviewdfx.HiLog; import ohos.hiviewdfx.HiLogLabel; import ohos.media.image.ImageSource; import ohos.media.image.PixelMap; import ohos.media.image.common.PixelFormat; import ohos.media.image.common.Rect; import ohos.media.image.common.Size; import java.io.InputStream; /** * Created by 夏德旺 on 2021/1/1 11:00 */ public class RoundImage extends Image { private static final HiLogLabel LABEL = new HiLogLabel(HiLog.DEBUG, 0, "RoundImage"); private PixelMapHolder pixelMapHolder;//像素圖片持有者 private RectFloat rectDst;//目標(biāo)區(qū)域 private RectFloat rectSrc;//源區(qū)域 public RoundImage(Context context) { this(context,null); } public RoundImage(Context context, AttrSet attrSet) { this(context,attrSet,null); } /** * 加載包含該控件的xml布局,會(huì)執(zhí)行該構(gòu)造函數(shù) * @param context * @param attrSet * @param styleName */ public RoundImage(Context context, AttrSet attrSet, String styleName) { super(context, attrSet, styleName); HiLog.error(LABEL,"RoundImage"); } public void onRoundRectDraw(int radius){ //添加繪制任務(wù) this.addDrawTask((view, canvas) -> { if (pixelMapHolder == null){ return; } synchronized (pixelMapHolder) { //給目標(biāo)區(qū)域賦值,寬度和高度取自xml配置文件中的屬性 rectDst = new RectFloat(0,0,getWidth(),getHeight()); //繪制圓角圖片 canvas.drawPixelMapHolderRoundRectShape(pixelMapHolder, rectSrc, rectDst, radius, radius); pixelMapHolder = null; } }); } //使用canvas繪制圓形 private void onCircleDraw(){ //添加繪制任務(wù),自定義組件的核心api調(diào)用,該接口的參數(shù)為Component下的DrawTask接口 this.addDrawTask((view, canvas) -> { if (pixelMapHolder == null){ return; } synchronized (pixelMapHolder) { //給目標(biāo)區(qū)域賦值,寬度和高度取自xml配置文件中的屬性 rectDst = new RectFloat(0,0,getWidth(),getHeight()); //使用canvas繪制輸出圓角矩形的位圖,該方法第4個(gè)參數(shù)和第5個(gè)參數(shù)為radios參數(shù), // 繪制圖片,必須把圖片的寬度和高度先設(shè)置成一樣,然后把它們?cè)O(shè)置為圖片寬度或者高度一半時(shí)則繪制的為圓形 canvas.drawPixelMapHolderRoundRectShape(pixelMapHolder, rectSrc, rectDst, getWidth()/2, getHeight()/2); pixelMapHolder = null; } }); } /** *獲取原有Image中的位圖資源后重新檢驗(yàn)繪制該組件 * @param pixelMap */ private void putPixelMap(PixelMap pixelMap){ if (pixelMap != null) { rectSrc = new RectFloat(0, 0, pixelMap.getImageInfo().size.width, pixelMap.getImageInfo().size.height); pixelMapHolder = new PixelMapHolder(pixelMap); invalidate();//重新檢驗(yàn)該組件 }else{ pixelMapHolder = null; setPixelMap(null); } } /** * 通過資源ID獲取位圖對(duì)象 **/ private PixelMap getPixelMap(int resId) { InputStream drawableInputStream = null; try { drawableInputStream = getResourceManager().getResource(resId); ImageSource.SourceOptions sourceOptions = new ImageSource.SourceOptions(); sourceOptions.formatHint = "image/png"; ImageSource imageSource = ImageSource.create(drawableInputStream, null); ImageSource.DecodingOptions decodingOptions = new ImageSource.DecodingOptions(); decodingOptions.desiredSize = new Size(0, 0); decodingOptions.desiredRegion = new Rect(0, 0, 0, 0); decodingOptions.desiredPixelFormat = PixelFormat.ARGB_8888; PixelMap pixelMap = imageSource.createPixelmap(decodingOptions); return pixelMap; } catch (Exception e) { e.printStackTrace(); } finally { try{ if (drawableInputStream != null){ drawableInputStream.close(); } }catch (Exception e) { e.printStackTrace(); } } return null; } /** * 對(duì)外調(diào)用的api,設(shè)置圓形圖片方法 * @param resId */ public void setPixelMapAndCircle(int resId){ PixelMap pixelMap = getPixelMap(resId); putPixelMap(pixelMap); onCircleDraw(); } /** * 對(duì)外調(diào)用的api,設(shè)置圓角圖片方法 * @param resId * @param radius */ public void setPixelMapAndRoundRect(int resId,int radius){ PixelMap pixelMap = getPixelMap(resId); putPixelMap(pixelMap); onRoundRectDraw(radius); } }
到此這篇關(guān)于鴻蒙HarmonyOS App開發(fā)造輪子之自定義圓形圖片組件的文章就介紹到這了,更多相關(guān)鴻蒙HarmonyOS自定義圓形圖片組件內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
springmvc圖片上傳及json數(shù)據(jù)轉(zhuǎn)換過程詳解
這篇文章主要介紹了springmvc圖片上傳及json數(shù)據(jù)轉(zhuǎn)換過程詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-10-10java讀取excel文件并復(fù)制(copy)文件到指定目錄示例
這篇文章主要介紹了java讀取excel文件并復(fù)制文件到指定目錄示例,需要的朋友可以參考下2014-02-02Java畢業(yè)設(shè)計(jì)實(shí)戰(zhàn)項(xiàng)目之倉(cāng)庫(kù)管理系統(tǒng)的實(shí)現(xiàn)流程
這是一個(gè)使用了java+SSM+Maven+Bootstrap+mysql開發(fā)的倉(cāng)庫(kù)管理系統(tǒng),是一個(gè)畢業(yè)設(shè)計(jì)的實(shí)戰(zhàn)練習(xí),具有一個(gè)倉(cāng)庫(kù)管理系統(tǒng)該有的所有功能,感興趣的朋友快來看看吧2022-01-01SpringBoot和VUE源碼直接整合打包成jar的踩坑記錄
這篇文章主要介紹了SpringBoot和VUE源碼直接整合打包成jar的踩坑記錄,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-03-03