自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

鴻蒙HarmonyOS App開發(fā)造輪子-自定義圓形圖片組件

開發(fā) OpenHarmony
文章由鴻蒙社區(qū)產(chǎn)出,想要了解更多內(nèi)容請(qǐng)前往:51CTO和華為官方戰(zhàn)略合作共建的鴻蒙技術(shù)社區(qū)https://harmonyos.51cto.com/#zz

[[375008]]

想了解更多內(nèi)容,請(qǐng)?jiān)L問:

51CTO和華為官方合作共建的鴻蒙技術(shù)社區(qū)

https://harmonyos.51cto.com/#zz 

一、背景

在采用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ì)代碼如下:

  1. package com.xdw.customview; 
  2.  
  3. import ohos.agp.components.AttrSet; 
  4. import ohos.agp.components.Image; 
  5. import ohos.agp.render.PixelMapHolder; 
  6. import ohos.agp.utils.RectFloat; 
  7. import ohos.app.Context; 
  8. import ohos.hiviewdfx.HiLog; 
  9. import ohos.hiviewdfx.HiLogLabel; 
  10. import ohos.media.image.ImageSource; 
  11. import ohos.media.image.PixelMap; 
  12. import ohos.media.image.common.PixelFormat; 
  13. import ohos.media.image.common.Rect; 
  14. import ohos.media.image.common.Size
  15.  
  16. import java.io.InputStream; 
  17.  
  18. /** 
  19.  * Created by 夏德旺 on 2021/1/1 11:00 
  20.  */ 
  21. public class RoundImage extends Image { 
  22.     private static final HiLogLabel LABEL = new HiLogLabel(HiLog.DEBUG, 0, "RoundImage"); 
  23.     private PixelMapHolder pixelMapHolder;//像素圖片持有者 
  24.     private RectFloat rectDst;//目標(biāo)區(qū)域 
  25.     private RectFloat rectSrc;//源區(qū)域 
  26.     public RoundImage(Context context) { 
  27.         this(context,null); 
  28.  
  29.     } 
  30.  
  31.     public RoundImage(Context context, AttrSet attrSet) { 
  32.         this(context,attrSet,null); 
  33.     } 
  34.  
  35.     /** 
  36.      * 加載包含該控件的xml布局,會(huì)執(zhí)行該構(gòu)造函數(shù) 
  37.      * @param context 
  38.      * @param attrSet 
  39.      * @param styleName 
  40.      */ 
  41.     public RoundImage(Context context, AttrSet attrSet, String styleName) { 
  42.         super(context, attrSet, styleName); 
  43.         HiLog.error(LABEL,"RoundImage"); 
  44.     } 
  45.  
  46.  
  47.  
  48.     public void onRoundRectDraw(int radius){ 
  49.         //添加繪制任務(wù) 
  50.         this.addDrawTask((view, canvas) -> { 
  51.             if (pixelMapHolder == null){ 
  52.                 return
  53.             } 
  54.             synchronized (pixelMapHolder) { 
  55.                 //給目標(biāo)區(qū)域賦值,寬度和高度取自xml配置文件中的屬性 
  56.                 rectDst = new RectFloat(0,0,getWidth(),getHeight()); 
  57.                 //繪制圓角圖片 
  58.                 canvas.drawPixelMapHolderRoundRectShape(pixelMapHolder, rectSrc, rectDst, radius, radius); 
  59.                 pixelMapHolder = null
  60.             } 
  61.         }); 
  62.     } 
  63.  
  64.     //使用canvas繪制圓形 
  65.     private void onCircleDraw(){ 
  66.         //添加繪制任務(wù),自定義組件的核心api調(diào)用,該接口的參數(shù)為Component下的DrawTask接口 
  67.         this.addDrawTask((view, canvas) -> { 
  68.             if (pixelMapHolder == null){ 
  69.                 return
  70.             } 
  71.             synchronized (pixelMapHolder) { 
  72.                 //給目標(biāo)區(qū)域賦值,寬度和高度取自xml配置文件中的屬性 
  73.                 rectDst = new RectFloat(0,0,getWidth(),getHeight()); 
  74.                 //使用canvas繪制輸出圓角矩形的位圖,該方法第4個(gè)參數(shù)和第5個(gè)參數(shù)為radios參數(shù), 
  75.                 // 繪制圖片,必須把圖片的寬度和高度先設(shè)置成一樣,然后把它們?cè)O(shè)置為圖片寬度或者高度一半時(shí)則繪制的為圓形 
  76.                 canvas.drawPixelMapHolderRoundRectShape(pixelMapHolder, rectSrc, rectDst, getWidth()/2, getHeight()/2); 
  77.                 pixelMapHolder = null
  78.             } 
  79.         }); 
  80.     } 
  81.  
  82.  
  83.     /** 
  84.      *獲取原有Image中的位圖資源后重新檢驗(yàn)繪制該組件 
  85.      * @param pixelMap 
  86.      */ 
  87.     private void putPixelMap(PixelMap pixelMap){ 
  88.         if (pixelMap != null) { 
  89.             rectSrc = new RectFloat(0, 0, pixelMap.getImageInfo().size.width, pixelMap.getImageInfo().size.height); 
  90.             pixelMapHolder = new PixelMapHolder(pixelMap); 
  91.             invalidate();//重新檢驗(yàn)該組件 
  92.         }else
  93.             pixelMapHolder = null
  94.             setPixelMap(null); 
  95.         } 
  96.     } 
  97.  
  98.  
  99.     /** 
  100.      * 通過資源ID獲取位圖對(duì)象 
  101.      **/ 
  102.     private PixelMap getPixelMap(int resId) { 
  103.         InputStream drawableInputStream = null
  104.         try { 
  105.             drawableInputStream = getResourceManager().getResource(resId); 
  106.             ImageSource.SourceOptions sourceOptions = new ImageSource.SourceOptions(); 
  107.             sourceOptions.formatHint = "image/png"
  108.             ImageSource imageSource = ImageSource.create(drawableInputStream, null); 
  109.             ImageSource.DecodingOptions decodingOptions = new ImageSource.DecodingOptions(); 
  110.             decodingOptions.desiredSize = new Size(0, 0); 
  111.             decodingOptions.desiredRegion = new Rect(0, 0, 0, 0); 
  112.             decodingOptions.desiredPixelFormat = PixelFormat.ARGB_8888; 
  113.             PixelMap pixelMap = imageSource.createPixelmap(decodingOptions); 
  114.             return pixelMap; 
  115.         } catch (Exception e) { 
  116.             e.printStackTrace(); 
  117.         } finally { 
  118.             try{ 
  119.                 if (drawableInputStream != null){ 
  120.                     drawableInputStream.close(); 
  121.                 } 
  122.             }catch (Exception e) { 
  123.                 e.printStackTrace(); 
  124.             } 
  125.         } 
  126.         return null
  127.     } 
  128.  
  129.     /** 
  130.      * 對(duì)外調(diào)用的api,設(shè)置圓形圖片方法 
  131.      * @param resId 
  132.      */ 
  133.     public void setPixelMapAndCircle(int resId){ 
  134.         PixelMap pixelMap = getPixelMap(resId); 
  135.         putPixelMap(pixelMap); 
  136.         onCircleDraw(); 
  137.     } 
  138.  
  139.     /** 
  140.      * 對(duì)外調(diào)用的api,設(shè)置圓角圖片方法 
  141.      * @param resId 
  142.      * @param radius 
  143.      */ 
  144.     public void setPixelMapAndRoundRect(int resId,int radius){ 
  145.         PixelMap pixelMap = getPixelMap(resId); 
  146.         putPixelMap(pixelMap); 
  147.         onRoundRectDraw(radius); 
  148.     } 

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

  1.   "app": { 
  2.     "bundleName""com.xdw.customview"
  3.     "vendor""xdw"
  4.     "version": { 
  5.       "code": 1, 
  6.       "name""1.0" 
  7.     }, 
  8.     "apiVersion": { 
  9.       "compatible": 4, 
  10.       "target": 4, 
  11.       "releaseType""Beta1" 
  12.     } 
  13.   }, 
  14.   "deviceConfig": {}, 
  15.   "module": { 
  16.     "package""com.xdw.customview"
  17.     "deviceType": [ 
  18.       "phone"
  19.       "tv"
  20.       "tablet"
  21.       "car"
  22.       "wearable" 
  23.     ], 
  24.     "reqPermissions": [ 
  25.       { 
  26.         "name""ohos.permission.INTERNET" 
  27.       } 
  28.     ], 
  29.     "distro": { 
  30.       "deliveryWithInstall"true
  31.       "moduleName""roundimage"
  32.       "moduleType""har" 
  33.     } 
  34.   } 

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

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

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

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

  1. dependencies { 
  2.     entryImplementation project(':entry'
  3.     implementation fileTree(dir: 'libs', include: ['*.jar''*.har']) 
  4.     testCompile'junit:junit:4.12' 

 3、在布局中引用自定義的圓形圖片,代碼如下:

  1. <?xml version="1.0" encoding="utf-8"?> 
  2. <DirectionalLayout 
  3.     xmlns:ohos="http://schemas.huawei.com/res/ohos" 
  4.     ohos:height="match_parent" 
  5.     ohos:width="match_parent" 
  6.     ohos:orientation="vertical"
  7.  
  8.     <Text 
  9.         ohos:id="$+id:text_helloworld" 
  10.         ohos:height="match_content" 
  11.         ohos:width="match_content" 
  12.         ohos:background_element="$graphic:background_ability_main" 
  13.         ohos:layout_alignment="horizontal_center" 
  14.         ohos:text="Hello World" 
  15.         ohos:text_size="50" 
  16.         /> 
  17.  
  18.     <com.xdw.customview.RoundImage 
  19.         ohos:id="$+id:image" 
  20.         ohos:height="200vp" 
  21.         ohos:width="200vp"/> 
  22. </DirectionalLayout> 

 4、在Java代碼中進(jìn)行調(diào)用,代碼如下:

  1. package com.example.testcustomview.slice; 
  2.  
  3. import com.example.testcustomview.ResourceTable; 
  4. import com.xdw.customview.RoundImage; 
  5. import ohos.aafwk.ability.AbilitySlice; 
  6. import ohos.aafwk.content.Intent; 
  7.  
  8. public class MainAbilitySlice extends AbilitySlice { 
  9.     @Override 
  10.     public void onStart(Intent intent) { 
  11.         super.onStart(intent); 
  12.         super.setUIContent(ResourceTable.Layout_ability_main); 
  13.         RoundImage roundImage = (RoundImage) findComponentById(ResourceTable.Id_image); 
  14.         roundImage.setPixelMapAndCircle(ResourceTable.Media_man); 
  15.     } 
  16.  
  17.     @Override 
  18.     public void onActive() { 
  19.         super.onActive(); 
  20.     } 
  21.  
  22.     @Override 
  23.     public void onForeground(Intent intent) { 
  24.         super.onForeground(intent); 
  25.     } 

 5、開啟手機(jī)模擬器進(jìn)行測(cè)試,效果如下:


©著作權(quán)歸作者和HarmonyOS技術(shù)社區(qū)共同所有,如需轉(zhuǎn)載,請(qǐng)注明出處,否則將追究法律責(zé)任。

想了解更多內(nèi)容,請(qǐng)?jiān)L問:

51CTO和華為官方合作共建的鴻蒙技術(shù)社區(qū)

https://harmonyos.51cto.com/#zz

 

責(zé)任編輯:jianghua 來源: 鴻蒙社區(qū)
相關(guān)推薦

2022-04-24 15:17:56

鴻蒙操作系統(tǒng)

2022-10-26 15:54:46

canvas組件鴻蒙

2021-11-01 10:21:36

鴻蒙HarmonyOS應(yīng)用

2021-12-30 16:10:52

鴻蒙HarmonyOS應(yīng)用

2021-02-20 12:34:53

鴻蒙HarmonyOS應(yīng)用開發(fā)

2021-09-15 10:19:15

鴻蒙HarmonyOS應(yīng)用

2022-06-30 14:02:07

鴻蒙開發(fā)消息彈窗組件

2022-07-15 16:45:35

slider滑塊組件鴻蒙

2022-07-06 20:24:08

ArkUI計(jì)時(shí)組件

2022-05-26 14:50:15

ArkUITS擴(kuò)展

2021-12-24 15:46:23

鴻蒙HarmonyOS應(yīng)用

2022-02-16 16:09:12

鴻蒙游戲操作系統(tǒng)

2021-11-22 10:00:33

鴻蒙HarmonyOS應(yīng)用

2009-06-24 15:13:36

自定義JSF組件

2021-06-17 14:56:00

鴻蒙HarmonyOS應(yīng)用

2023-02-20 15:20:43

啟動(dòng)頁(yè)組件鴻蒙

2022-10-25 15:12:24

自定義組件鴻蒙

2022-02-21 15:16:30

HarmonyOS鴻蒙操作系統(tǒng)

2022-06-20 15:43:45

switch開關(guān)鴻蒙

2021-12-21 15:22:22

鴻蒙HarmonyOS應(yīng)用
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)