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

HarmonyOS自定義組件之圖層的使用

開發(fā) 前端 OpenHarmony
HarmonyOS目前已經(jīng)有較豐富的自定義組件了,但是多數(shù)自定義組件都沒有講到圖層這個概念,都是使用默認圖層進行繪制。這里就通過幾個小例子介紹一下HarmonyOS自定義組件中圖層概念和使用。

[[441917]]

想了解更多內(nèi)容,請訪問:

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

https://harmonyos.51cto.com

前言

HarmonyOS目前已經(jīng)有較豐富的自定義組件了,但是多數(shù)自定義組件都沒有講到圖層這個概念,都是使用默認圖層進行繪制。這里就通過幾個小例子介紹一下HarmonyOS自定義組件中圖層概念和使用。

使用說明

1.HarmonyOS的繪制入口

1.1 DrawTask接口

HarmonyOS的Component組件對外提供了一個DrawTask接口,通過addDrawTask方法為組件添加一個DrawTask,讓開發(fā)者可以進行自定義繪制邏輯。首先我們看下DrawTask的描述:

  1. public interface DrawTask { 
  2.       int BETWEEN_BACKGROUND_AND_CONTENT = 1; 
  3.       int BETWEEN_CONTENT_AND_FOREGROUND = 2; 
  4.  
  5.       void onDraw(Component component, Canvas canvas); 
  6.   } 

 1.2 onDraw繪制方法

這個接口中只有一個onDraw方法,做移動開發(fā)的同學對這個名稱的方法應該都很熟悉,在這個回調(diào)里系統(tǒng)提供了一塊canvas畫布,我們可以調(diào)用canvas的api進行一些基礎(chǔ)圖形的組合繪制。

2.HarmonyOS圖層介紹

2.1 圖層概念介紹

HarmonyOS為每個組件定義了5個圖層,從下往上分別為:Background -> UserLayer1 -> Content -> UserLayer2 -> Foreground,并且繪制流程也是按照從下往上的順序進行繪制的,這點其實和我們熟悉的View的繪制流程基本一致。這中設(shè)計和PS中的圖層概念基本一致,通過構(gòu)建多個圖層分別進行操作,最終再合成為一個圖層渲染到屏幕上。我們可以用下面這圖來理解:

#星光計劃2.0#HarmonyOS自定義組件之圖層的使用-鴻蒙HarmonyOS技術(shù)社區(qū)

在這個圖層結(jié)構(gòu)中,有兩個layer是提供給上層應用使用的,分別如圖中的UserLayer1和UserLayer2。他們分別位于背景與內(nèi)容之間,內(nèi)容與前景之間。其中,背景,內(nèi)容,前景為系統(tǒng)私有,應用層無法對其進行干預。(這里補充說明一點,從官方API文檔說明來看是存在Foreground圖層的,但是實際中尚不清楚系統(tǒng)是如何使用該圖層,個人猜測應該是留給列表的滾動條這類場景使用。)

2.2 圖層概念實踐

在第一節(jié)的DrawTask接口介紹中,里面定義和圖層相關(guān)的兩個常量:BETWEEN_BACKGROUND_AND_CONTENT 和 BETWEEN_CONTENT_AND_FOREGROUND,對應的就是上圖中的兩個User Layer。

下面我們用代碼來實踐一下這個圖層結(jié)構(gòu)和這兩個常量的作用。

自定義一個Text組件,分別在上圖中的兩個UserLayer中繪制不同顏色的實心矩形:

  1. public class CustomText extends Text { 
  2.  
  3.     public CustomText(Context context, AttrSet attrSet) { 
  4.         super(context, attrSet); 
  5.         init(); 
  6.     } 
  7.  
  8.     private void prepare() { 
  9.         // 繪制紅色背景 
  10.         ShapeElement background = new ShapeElement(); 
  11.         background.setShaderType(ShapeElement.RECTANGLE); 
  12.         background.setRgbColor(new RgbColor(255,0,0)); 
  13.         setBackground(background); 
  14.         // 繪制白色文字 
  15.         setText("你好你好你好你好你好"); 
  16.         setTextColor(Color.WHITE); 
  17.     } 
  18.  
  19.     private void init() { 
  20.         prepare(); 
  21.         // 在BETWEEN_BACKGROUND_AND_CONTENT圖層上繪制藍色矩形 
  22.         addDrawTask(new BackDrawTask(), DrawTask.BETWEEN_BACKGROUND_AND_CONTENT); 
  23.         // 在BETWEEN_CONTENT_AND_FOREGROUND圖層上繪制綠色矩形 
  24.         addDrawTask(new ForeDrawTask(), DrawTask.BETWEEN_CONTENT_AND_FOREGROUND); 
  25.     } 
  26.  
  27.     // BETWEEN_BACKGROUND_AND_CONTENT 
  28.     private static class BackDrawTask implements DrawTask { 
  29.         @Override 
  30.         public void onDraw(Component component, Canvas canvas) { 
  31.             final int offset = 50; 
  32.             Paint paint = new Paint(); 
  33.             paint.setStyle(Paint.Style.FILL_STYLE); 
  34.             paint.setColor(Color.BLUE); 
  35.             canvas.drawRect(new Rect(offset, offset, component.getWidth() - offset, component.getHeight() - offset), paint); 
  36.         } 
  37.     } 
  38.  
  39.     // BETWEEN_CONTENT_AND_FOREGROUND 
  40.     private static class ForeDrawTask implements DrawTask { 
  41.         @Override 
  42.         public void onDraw(Component component, Canvas canvas) { 
  43.             final int offset = 100; 
  44.             Paint paint = new Paint(); 
  45.             paint.setStyle(Paint.Style.FILL_STYLE); 
  46.             paint.setColor(Color.GREEN); 
  47.             canvas.drawRect(new Rect(offset, offset, component.getWidth() - offset, component.getHeight() - offset), paint); 
  48.         } 
  49.     } 

布局代碼如下:

  1. <DirectionalLayout 
  2.     xmlns:ohos="http://schemas.huawei.com/res/ohos" 
  3.     ohos:height="match_parent" 
  4.     ohos:width="match_parent" 
  5.     ohos:alignment="center" 
  6.     ohos:orientation="vertical"
  7.  
  8.     <com.example.myapplication.CustomText 
  9.         ohos:height="300vp" 
  10.         ohos:width="300vp" 
  11.         ohos:layout_alignment="horizontal_center" 
  12.         ohos:text_size="40vp" /> 
  13.  
  14. </DirectionalLayout> 

 運行項目,我們來看下實際的渲染效果,的確符合預期。

#星光計劃2.0#HarmonyOS自定義組件之圖層的使用-鴻蒙HarmonyOS技術(shù)社區(qū)

從目視的垂直方向,從底部往上的內(nèi)容依次是:

最底層的紅色背景(Background),

自定義的藍色矩形(BackDrawTask),

Text自己的文本內(nèi)容(Content),

自定義的綠色矩形(ForeDrawTask)。

3.HarmonyOS圖層的使用

3.1 繼承Component的自定義組件

當我們繼承Component去實現(xiàn)自定義組件時,這時候不論選用哪個圖層進行繪制都是一樣。因為兩個UserLayer都是位于Background圖層之上,而默認的Component組件并沒有內(nèi)容層和前景的默認繪制,因此可以忽略這兩個圖層。

3.2 通過圖層實現(xiàn)水波紋效果

當我們繼承系統(tǒng)組件,系統(tǒng)組件的內(nèi)容層和前景層都有內(nèi)部繪制邏輯,因此我們慎重選擇UserLayer圖層了。

給自定義Button添加一個水波紋的觸摸反饋效果**(水波紋效果是需要繪制在button文字之下,button背景之上,因此使用 BETWEEN_BACKGROUND_AND_CONTENT)**:

  1. public class CustomButton extends Button implements Component.TouchEventListener, Component.DrawTask { 
  2.     private float downX, downY; 
  3.     private int maxRadius; 
  4.     private float currentRadius; 
  5.     private final Paint paint = new Paint(); 
  6.  
  7.     { 
  8.         paint.setColor(Color.YELLOW); 
  9.         paint.setStyle(Paint.Style.FILL_STYLE); 
  10.     } 
  11.  
  12.     private AnimatorValue av = new AnimatorValue(); 
  13.  
  14.     public CustomButton(Context context, AttrSet attrSet) { 
  15.         super(context, attrSet); 
  16.         av.setValueUpdateListener((animatorValue, v) -> { 
  17.             currentRadius = maxRadius * v; 
  18.             invalidate(); 
  19.         }); 
  20.         init(); 
  21.     } 
  22.  
  23.     @Override 
  24.     public boolean onTouchEvent(Component component, TouchEvent touchEvent) { 
  25.         if (touchEvent.getAction() == TouchEvent.PRIMARY_POINT_DOWN) { 
  26.             if (maxRadius == 0) { 
  27.                 int w = component.getWidth(); 
  28.                 int h = component.getHeight(); 
  29.                 maxRadius = (int) Math.sqrt(w * w + h * h); 
  30.             } 
  31.             int index = touchEvent.getIndex(); 
  32.             MmiPoint pointer = touchEvent.getPointerPosition(index); 
  33.             downX = pointer.getX(); 
  34.             downY = pointer.getY(); 
  35.             av.cancel(); 
  36.             av.start(); 
  37.             return true
  38.         } else if (touchEvent.getAction() == TouchEvent.PRIMARY_POINT_UP) { 
  39.             av.cancel(); 
  40.             currentRadius = 0; 
  41.             invalidate(); 
  42.             return true
  43.         } 
  44.         return false
  45.     } 
  46.  
  47.     private void init() { 
  48.         setTouchEventListener(this); 
  49.         addDrawTask(this, DrawTask.BETWEEN_BACKGROUND_AND_CONTENT); 
  50.     } 
  51.  
  52.     @Override 
  53.     public void onDraw(Component component, Canvas canvas) { 
  54.         canvas.drawCircle(downX, downY, currentRadius, paint); 
  55.     } 

效果如下:

#星光計劃2.0#HarmonyOS自定義組件之圖層的使用-鴻蒙HarmonyOS技術(shù)社區(qū)

3.3 通過圖層實現(xiàn)蒙層效果

給自定義Image增加一個顏色遮罩效果**(圖片蒙層是在圖片內(nèi)容上加一個遮罩,因此需要在圖片之上進行蒙層繪制,因此使用 BETWEEN_CONTENT_AND_FOREGROUND)**:

  1. public class CustomImage extends Image implements Component.DrawTask { 
  2.     private final Paint paint = new Paint(); 
  3.  
  4.     { 
  5.         paint.setColor(Color.YELLOW); 
  6.         paint.setStyle(Paint.Style.FILL_STYLE); 
  7.         paint.setAlpha(0.3f); 
  8.     } 
  9.  
  10.     public CustomImage(Context context, AttrSet attrSet) { 
  11.         super(context, attrSet); 
  12.         // 圖片蒙層是在圖片內(nèi)容上加一個遮罩,因此需要在內(nèi)容層和前景層進行蒙層繪制 
  13.         addDrawTask(this, DrawTask.BETWEEN_CONTENT_AND_FOREGROUND); 
  14.     } 
  15.  
  16.     @Override 
  17.     public void onDraw(Component component, Canvas canvas) { 
  18.         canvas.drawRect(new Rect(0, 0, component.getWidth(), component.getHeight()), paint); 
  19.     } 

4.效果展示

效果如下,左邊為原始Image,右邊的為添加蒙版的Image:

#星光計劃2.0#HarmonyOS自定義組件之圖層的使用-鴻蒙HarmonyOS技術(shù)社區(qū)

總結(jié)

以上就是關(guān)于鴻蒙圖層的介紹,核心內(nèi)容概括如下:

  • HarmonyOS為每個組件定義了5個圖層,從下往上分別為:Background、UserLayer1、Content、UserLayer2、Foreground。
  • HarmonyOS自定義組件能夠使用的圖層有兩個,分別位于Background和Content、Content和Foreground之間。
  • 靈活的選擇繪制圖層,可以實現(xiàn)特殊的UI效果,例如水波紋觸摸反饋、圖片遮罩蒙層效果等。

文章相關(guān)附件可以點擊下面的原文鏈接前往下載

https://harmonyos.51cto.com/resource/1612

想了解更多內(nèi)容,請訪問:

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

https://harmonyos.51cto.com

 

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

2021-11-01 10:21:36

鴻蒙HarmonyOS應用

2022-06-30 14:02:07

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

2022-07-15 16:45:35

slider滑塊組件鴻蒙

2022-06-20 15:43:45

switch開關(guān)鴻蒙

2022-07-12 16:56:48

自定義組件鴻蒙

2022-04-24 15:17:56

鴻蒙操作系統(tǒng)

2022-05-20 14:34:20

list組件鴻蒙操作系統(tǒng)

2021-03-09 15:23:45

鴻蒙HarmonyOS應用開發(fā)

2023-02-20 15:20:43

啟動頁組件鴻蒙

2021-11-24 10:02:53

鴻蒙HarmonyOS應用

2022-02-16 15:25:31

JS代碼Canvas鴻蒙

2022-10-25 15:12:24

自定義組件鴻蒙

2022-10-26 15:54:46

canvas組件鴻蒙

2022-02-16 08:12:03

組件樣式元素

2021-09-15 10:19:15

鴻蒙HarmonyOS應用

2022-07-06 20:24:08

ArkUI計時組件

2022-02-21 15:16:30

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

2021-12-21 15:22:22

鴻蒙HarmonyOS應用

2021-12-30 16:10:52

鴻蒙HarmonyOS應用

2021-11-22 10:00:33

鴻蒙HarmonyOS應用
點贊
收藏

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