日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

HarmonyOS图片,HarmonyOS App开发造轮子--自定义圆形图片组件

發布時間:2023/12/20 编程问答 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 HarmonyOS图片,HarmonyOS App开发造轮子--自定义圆形图片组件 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、背景

在采用Java配合xml布局編寫鴻蒙app頁面的時候,發現sdk自帶的Image組件并不能將圖片設置成圓形,反復了翻閱了官方API手冊(主要查閱了Compont和Image相關的API),起初發現了一個setCornerRadius方法,于是想著將圖片寬度和高度設置為一樣,然后調用該方法將radios設置為寬度或者高度的一半,以為可以實現圓形圖片的效果,后來發現不行。于是乎想著能不能通過繼承原有的Image自己來動手重新自定義一個支持圓形的圖片組件。

二、思路:

1、對比之前自己在其他程序開發中自定義組件的思路,首先尋找父組件Image和Component相關的Api,看看是否具備OnDraw方法。

2、了解Canvas相關Api操作,特別是涉及到位圖的操作。

通過翻閱大量資料,發現了兩個關鍵的api,分別是Component的addDrawTask方法和其內部靜態接口DrawTask

三、自定義組件模塊

1、新建一個工程之后,創建一個獨立的Java FA模塊,然后刪除掉里面所有布局以及自動生成的java代碼,然后自己創建一個class繼承ImageView

2、寫一個類繼承ImageView,在其中暴露出public的設置圓形圖片的api方法以供后面調用;

3、在原有的Image組件獲取到位圖之后,利用該位圖數據利用addDrawTask方法配合Canvas進行位圖輸出形狀的重新繪制,這里需要使用Canvas的一個

關鍵api方法drawPixelMapHolderRoundRectShape;

4、注意,為了讓Canvas最后輸出的圖片為圓形,需要將圖片在布局中的寬度和高度設置成一樣,否則輸出的為圓角矩形或者橢圓形。

最后封裝后的詳細代碼如下: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;//目標區域

private?RectFloat?rectSrc;//源區域

public?RoundImage(Context?context)?{

this(context,null);

}

public?RoundImage(Context?context,?AttrSet?attrSet)?{

this(context,attrSet,null);

}

/**

*?加載包含該控件的xml布局,會執行該構造函數

*?@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){

//添加繪制任務

this.addDrawTask((view,?canvas)?->?{

if?(pixelMapHolder?==?null){

return;

}

synchronized?(pixelMapHolder)?{

//給目標區域賦值,寬度和高度取自xml配置文件中的屬性

rectDst?=?new?RectFloat(0,0,getWidth(),getHeight());

//繪制圓角圖片

canvas.drawPixelMapHolderRoundRectShape(pixelMapHolder,?rectSrc,?rectDst,?radius,?radius);

pixelMapHolder?=?null;

}

});

}

//使用canvas繪制圓形

private?void?onCircleDraw(){

//添加繪制任務,自定義組件的核心api調用,該接口的參數為Component下的DrawTask接口

this.addDrawTask((view,?canvas)?->?{

if?(pixelMapHolder?==?null){

return;

}

synchronized?(pixelMapHolder)?{

//給目標區域賦值,寬度和高度取自xml配置文件中的屬性

rectDst?=?new?RectFloat(0,0,getWidth(),getHeight());

//使用canvas繪制輸出圓角矩形的位圖,該方法第4個參數和第5個參數為radios參數,

//?繪制圖片,必須把圖片的寬度和高度先設置成一樣,然后把它們設置為圖片寬度或者高度一半時則繪制的為圓形

canvas.drawPixelMapHolderRoundRectShape(pixelMapHolder,?rectSrc,?rectDst,?getWidth()/2,?getHeight()/2);

pixelMapHolder?=?null;

}

});

}

/**

*獲取原有Image中的位圖資源后重新檢驗繪制該組件

*?@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();//重新檢驗該組件

}else{

pixelMapHolder?=?null;

setPixelMap(null);

}

}

/**

*?通過資源ID獲取位圖對象

**/

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;

}

/**

*?對外調用的api,設置圓形圖片方法

*?@param?resId

*/

public?void?setPixelMapAndCircle(int?resId){

PixelMap?pixelMap?=?getPixelMap(resId);

putPixelMap(pixelMap);

onCircleDraw();

}

/**

*?對外調用的api,設置圓角圖片方法

*?@param?resId

*?@param?radius

*/

public?void?setPixelMapAndRoundRect(int?resId,int?radius){

PixelMap?pixelMap?=?getPixelMap(resId);

putPixelMap(pixelMap);

onRoundRectDraw(radius);

}

}

5、修改config.json文件,代碼如下{

"app":?{

"bundleName":?"com.xdw.customview",

"vendor":?"xdw",

"version":?{

"code":?1,

"name":?"1.0"

},

"apiVersion":?{

"compatible":?4,

"target":?4,

"releaseType":?"Beta1"

}

},

"deviceConfig":?{},

"module":?{

"package":?"com.xdw.customview",

"deviceType":?[

"phone",

"tv",

"tablet",

"car",

"wearable"

],

"reqPermissions":?[

{

"name":?"ohos.permission.INTERNET"

}

],

"distro":?{

"deliveryWithInstall":?true,

"moduleName":?"roundimage",

"moduleType":?"har"

}

}

}

這樣該模塊就可以導出后續給其他所有工程引用了,后面還可以編譯之后發布到gradle上直接通過添加依賴來進行使用(這個是后話),下面我們先通過本地依賴導入的方式來調用這個自定義組件模塊吧。

四、其他工程調用該自定義組件并測試效果

1、再來新建一個工程,然后將之前的模塊導入到新建的工程中(DevEco暫時不支持自動導入外部模塊的操作,需要手動導入操作,請關注我的另外一篇博客)

2、在gradle中引用導入的模塊的組件,代碼如下:

文章后續內容和相關附件可以點擊下面的原文鏈接前往學習

總結

以上是生活随笔為你收集整理的HarmonyOS图片,HarmonyOS App开发造轮子--自定义圆形图片组件的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。