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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

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

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

一、背景

在采用Java配合xml布局編寫鴻蒙app頁面的時(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);

}

}

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"

}

}

}

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

四、其他工程調(diào)用該自定義組件并測試效果

1、再來新建一個(gè)工程,然后將之前的模塊導(dǎo)入到新建的工程中(DevEco暫時(shí)不支持自動(dòng)導(dǎo)入外部模塊的操作,需要手動(dòng)導(dǎo)入操作,請(qǐng)關(guān)注我的另外一篇博客)

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

文章后續(xù)內(nèi)容和相關(guān)附件可以點(diǎn)擊下面的原文鏈接前往學(xué)習(xí)

總結(jié)

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

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。