1、程序介紹
本案例使用TextArea實現多文本輸入,使用mediaLibrary實現在相冊中獲取圖片,使用image生成pixelMap,使用pixelMap的scale(),crop(),rotate()接口實現對圖片的縮放,裁剪,旋轉功能。
案例說明:
發表評價頁面點擊添加圖片/照片,頁面跳轉到圖片選擇頁面。
進入圖片選擇頁面后,選擇需要顯示的圖片,最多選擇6張圖片。
選中圖片后點擊下一步,頁面會跳轉到圖片編輯頁面,點擊縮放,頁面會顯示縮小,放大按鈕,點擊按鈕,可對圖片進行縮小,放大操作。點擊裁剪,頁面會跳出裁剪比例,點擊想要裁剪的比例可以對圖片進行裁剪。點擊旋轉可對圖片進行旋轉。
圖片編輯完成后,點擊確認,頁面會跳轉到發表評價頁面,顯示相關照片。點擊添加圖片/照片可以對圖片進行重新選擇。
點擊返回按鈕,退出應用。
API接口:9
2、知識準備
2.1、TextArea
多行文本輸入框組件,當輸入的文本內容超過組件寬度時會自動換行顯示。
function TextArea(value?:{placeholder?: ResourceStr, text?: ResourceStr, controller?: TextAreaController})
其中,參數定義如下:
參數名 | 參數類型 | 必填 | 參數描述 |
---|---|---|---|
placeholder | ResourceStr | 否 | 設置無輸入時的提示文本 |
text | ResourceStr | 否 | 設置輸入框當前的文本內容 |
controller | TextAreaController | 否 | 設置TextArea控制器 |
其中,屬性可支持如下:
名稱 | 參數類型 | 描述 |
---|---|---|
placeholderColor | ResourceColor | 設置placeholder文本顏色 |
placeholderFont | Font | 設置plaoceholder文本樣式 |
textAlign | TextAlign | 設置文本在輸入框中的水平對齊式默認值:TextAlign.Start |
caretColor | ResourceColor | 設置輸入框光標顏色 |
inputFilter | {value: ResourceStr,error?: (value: string) => void} | 通過正則表達式設置輸入過濾器。匹配表達式的輸入允許顯示,不匹配的輸入將被過濾。僅支持單個字符匹配,不支持字符串匹配。- value:設置正則表達式。- error:正則匹配失敗時,返回被過濾的內容。 |
copyOption | CopyOptions | 設置輸入的文本是否可復制。設置CopyOptions.None時,當前TextArea中的文字無法被復制或剪切,僅支持粘貼。 |
2.2、mediaquery
ohos.mediaquery提供媒體查詢,提供根據不同媒體類型定義不同的樣式。
2.2.1、導入模塊
import mediaquery from '@ohos.mediaquery'
2.2.2、 mediaquery.matchMediaSync
function matchMediaSync(condition: string): MediaQueryListener
設置媒體查詢的查詢條件,并返回對應的監聽句柄。
參數定義如下所示:
參數名 | 類型 | 必填 | 說明 |
---|---|---|---|
condition | string | 是 | 媒體事件的匹配事件 |
返回值定義如下所示:
類型 | 說明 |
---|---|
MediaQueryListener | 媒體事件監聽句柄,用于注冊和銷毀監聽回調 |
2.2.3、MediaQueryListener
媒體查詢的句柄,并包含了申請句柄時的首次查詢結果。
系統能力:SystemCapability.ArkUI.ArkUI.Full
(1)屬性
名稱 | 類型 | 可讀 | 可寫 | 說明 |
---|---|---|---|---|
matches | boolean | 是 | 否 | 是否符合匹配條件 |
media | string | 是 | 否 | 媒體事件的匹配條件 |
(2)on函數
function on(type: 'change', callback: Callback<MediaQueryResult>): void
通過句柄向對應的查詢條件注冊回調,當媒體屬性發生變更時會觸發該回調。
系統能力:SystemCapability.ArkUI.ArkUI.Full
參數:
參數名 | 類型 | 必填 | 說明 |
---|---|---|---|
type | string | 是 | 必須填寫字符串change |
callback | Callback | 是 | 向媒體查詢注冊的回調 |
(3)off函數
function off(type: 'change', callback?: Callback<MediaQueryResult>): void
通過句柄向對應的查詢條件去注冊回調,當媒體屬性發生變更時不在觸發指定的回調。
系統能力:SystemCapability.ArkUI.ArkUI.Full
參數:
參數名 | 類型 | 必填 | 說明 |
---|---|---|---|
type | string | 是 | 必須填寫字符串change |
callback | Callback | 否 | 需要去注冊的回調,如果參數缺省則去注冊該句柄下所有的回調 |
2.2.4、MediaQueryResult
用于執行媒體查詢操作。
系統能力:SystemCapability.ArkUI.ArkUI.Full
(1)屬性
名稱 | 類型 | 可讀 | 可寫 | 說明 |
---|---|---|---|---|
matches | boolean | 是 | 否 | 是否符合匹配條件 |
media | string | 是 | 否 | 媒體事件的匹配條件 |
2.3、mediaLibrary
MediaLibrary支持能力列舉如下:
查詢圖片和視頻相冊
媒體文件操作如創建、重命名、拷貝和刪除
相冊操作如創建、重命名和刪除
MediaLibrary整體框架,如下所示:
詳細請參考:官方文檔
2.4、Grid
網格容器,由“行”和“列”分割的單元格所組成,通過指定“項目”所在的單元格做出各種各樣的布局。
詳細請參考:官方文檔
2.5、@ohos.multimedia.image
本模塊提供圖片處理效果,包括通過屬性創建PixelMap、讀取圖像像素數據、讀取區域內的圖片數據等。
詳細請參考:官方文檔
2.6、@ohos.router
本模塊提供通過不同的url訪問不同的頁面,包括跳轉到應用內的指定頁面、用應用內的某個頁面替換當前頁面、返回上一頁面或指定的頁面等。
詳細請參考:官方文檔
3、程序解析
3.1、申請設備權限
配置文件module.json5中聲明權限,申請應用讀取、寫入用戶外部存儲中的媒體文件信息以及允許應用訪問用戶媒體文件中的地理位置信息。
"requestPermissions": [ { "name": "ohos.permission.READ_MEDIA", "reason": "$string:media_read_permission", "usedScene": { "abilities": [ "MainAbility" ], "when": "inuse" } }, { "name": "ohos.permission.WRITE_MEDIA", "reason": "$string:media_write_permission", "usedScene": { "abilities": [ "MainAbility" ], "when": "inuse" } }, { "name": "ohos.permission.MEDIA_LOCATION", "reason": "$string:media_location_permission", "usedScene": { "abilities": [ "MainAbility" ], "when": "inuse" } }]
3.2、Index.ets
首先,聲明1個pixelMaps數組,用于存放照片或視頻。
@StorageLink('pixelMaps') pixelMaps: Array<image.PixelMap> = []
注意:@StorageLink('pixelMaps')表明通過使用@StorageLink(key)裝飾的狀態變量,與AppStorage建立雙向數據綁定。
其次,在build()調用之前運行aboutToAppear(),負責獲取AppStorage的pixelMaps屬性,然后往當前頁傳入isShowCamera參數。
aboutToAppear() {
logger.info(TAG, 'enter aboutToAppear')
// 與AppStorage建立雙向數據綁定,獲取pixelMaps屬性
if (AppStorage.Get('pixelMaps')) {
this.pixelMaps.push(undefined)
}
// 獲取發起跳轉的頁面往當前頁傳入的參數
if (router.getParams() && router.getParams()['isShowCamera']) {
this.isShowCamera = true
}
}
最后,build()顯示整個頁面。
其中,已選圖片通過Grid和GridItem控件排列顯示。
// 使用網格容器將已選照片顯示出現
Grid() {
// 輪流顯示成1行照片
ForEach(this.pixelMaps, (item, index) => {
GridItem() {
if (index < this.pixelMaps.length - 1) {
Image(item)
.width('100%')
.height(100)
.borderRadius(10)
} else {
// 最后一個為"添加圖片/照片"
Column() {
Image($r('app.media.photo'))
.height(40)
.width(40)
.onClick(() => {
router.push({
url: 'pages/ChoicePhotos'
})
})
Text($r('app.string.add_picture'))
.fontSize(13)
}
.alignItems(HorizontalAlign.Center)
.justifyContent(FlexAlign.Center)
.width('100%')
.height(100)
.borderRadius(10)
.backgroundColor('#F1F3F5')
}
}
})
}
.columnsTemplate('1fr 1fr 1fr 1fr')
.columnsGap(8)
.rowsGap(8)
.margin({ top: 8 })
.width('94%')
.height(105 * (this.pixelMaps.length > 4 ? 2 : 1))
3.3、ChoicePhotos.ets
該頁面為選擇照片頁面。該頁面通過調用ChoicePhoto()顯示頁面。
@Entry @Component struct ChoicePhotos {
build() {
Column() {
ChoicePhoto()
}
}
}
ChoicePhoto()主要負責顯示照片視頻以及添加等功能的界面。
首先,聲明1個MediaLibrary類對象和監聽句柄listener,用于查詢音頻、視頻和圖片文件元數據信息。
private mediaLibraryInstance: mediaLibrary.MediaLibrary = mediaLibrary.getMediaLibrary(getContext(this) as any)
private listener = mediaQuery.matchMediaSync('screen and (min-aspect-ratio: 1.5) or (orientation: landscape)')
其次,調用build()之前做初始化工作,主要是開啟監聽句柄listener的change事件,并獲取設備端保存的圖片資源。
async aboutToAppear() { logger.info(TAG, `aboutToAppear`) this.listener.on('change', this.onLand) this.nextText = await this.convertResourceToString($r('app.string.next')) // 獲取圖片的文件信息 this.getFileAssetsFromType(mediaLibrary.MediaType.IMAGE)}
其中,getFileAssetsFromType()獲取設備端所有的圖片或視頻的文件信息。
async getFileAssetsFromType(mediaType: mediaLibrary.MediaType) { logger.info(TAG, `getFileAssetsFromType`) let context = getContext(this) as any // 獲取媒體庫的實例,用于訪問和修改用戶等個人媒體數據信息(如音頻、視頻、圖片、文檔等) let mediaLibraryInstance = mediaLibrary.getMediaLibrary(context) if (!mediaLibraryInstance) { return } logger.info(TAG, `mediaLibraryInstance = ${JSON.stringify(mediaLibraryInstance)}`) // 創建文件獲取選項,此處參數為獲取image類型的文件資源 let fileKeyObj = mediaLibrary.FileKey let fetchOp = { selections: `${fileKeyObj.MEDIA_TYPE}=?`, selectionArgs: [`${mediaType}`], } // 獲取文件資源 let fetchFileResult = await mediaLibraryInstance.getFileAssets(fetchOp) logger.info(TAG, `fetchFileResult = ${JSON.stringify(fetchFileResult)} , ${fetchFileResult.getCount()}`) if (fetchFileResult && fetchFileResult.getCount() > 0) { this.medias = await fetchFileResult.getAllObject() } logger.info(TAG, `this.medias = ${JSON.stringify(this.medias)}`)}
再次,使用Grid和GridItem控件顯示圖片或視頻。
Grid() { ForEach(this.medias, (item, index) => { GridItem() { Stack({ alignContent: Alignment.TopEnd }) { Image(item.uri) .width('100%') .height('100%') .borderRadius(10) .objectFit(ImageFit.Fill)
if (this.isShowChoices[index]) { this.showChoiceBuild('#e92f4f', this.choiceMedias.indexOf(item) + 1) } else { this.showChoiceBuild('#ffb7b4b4', 0) } } .width('100%') .height('100%') .onClick(() => { this.isShowChoices[index] = !this.isShowChoices[index] if (this.isShowChoices[index]) { if (this.choiceMedias.length > 5) { prompt.showDialog({ message: $r('app.string.choice_number') }) this.isShowChoices[index] = !this.isShowChoices[index] return } this.choiceMedias.push(item) } else { if (this.choiceMedias.indexOf(item) != -1) { this.choiceMedias.splice(this.choiceMedias.indexOf(item), 1) } } }) } .aspectRatio(1) })}
最后,定義1個按鍵事件。一旦選中某個圖片,可進入圖片編輯頁面。
Button(`${this.nextText} ${this.isChoice === true ? `(${this.choiceMedias.length})` : ''}`) .fontSize(20) .height(32) .backgroundColor(this.isChoice === true ? '#E92F4F' : '#fffa8e8e') .margin({ right: 10 }) .borderRadius(20) .onClick(() => { if (this.isChoice === false) { return } this.mediaUris = this.choiceMedias.map((item) => { return item.uri }) // 跳轉到圖片編輯頁面 router.push({ url: 'pages/EditPages', params: { mediaUris: this.mediaUris, isLand: this.isLand } }) })
4、項目編譯
4.1、打開項目
打開DevEco Studio,再打開自定義通知項目。
4.2、編譯程序
點擊菜單欄上的“Build” -> "Rebuild Project"。如果出現無法編譯,則注意查看Event Log界面。如下所示:
點擊Run 'npm install',讓DevEco Studio安裝相關依賴包。
重新點擊菜單欄上的“Build” -> "Rebuild Project"。出現如下錯誤:
點擊上圖紅色框部分,安裝相關服務。
重新點擊菜單欄上的“Build” -> "Rebuild Project",編譯成功。
4.3、安裝程序
點擊“entry”按鈕,將項目程序安裝到設備端。如下圖所示:
如果出現下述報錯,表示無法安裝。如圖所示:
點擊上圖紅色框的藍色字體,彈出"Project Structure"對話框,點擊"Apply",再點擊"OK"。如圖所示:
重新點擊“entry”按鈕,將項目程序安裝到設備端。
5、運行結果
-
APP
+關注
關注
33文章
1575瀏覽量
72606 -
應用開發
+關注
關注
0文章
59瀏覽量
9396 -
OpenHarmony
+關注
關注
25文章
3730瀏覽量
16424
發布評論請先 登錄
相關推薦
評論