Integrating Gallery Image Selection into Product Review Interfaces with HarmonyOS ArkUI
Developing a product review interface that supports media attachments requires seamless integration between UI components and the system media framework. In HarmonyOS, this is achieved by combining Grid and TextArea components within a scrollable layout, coupled with the @ohos.file.media module for gallery access.
Architecture and Component Layout
The primary interface relies on a vertically scrollable container to accommodate user feedback and media thumbnails. A Grid component dynamically renders selected image URIs, while a TextArea captures textual reviews. State variables track the selected image collection and the current text input.
import { router } from '@kit.ArkUI';
@Entry
@Component
struct ReviewForm {
@State selectedAssets: string[] = []
@State reviewText: string = ''
private readonly maxImageLimit: number = 6
build() {
Scroll() {
Column() {
Text('Product Feedback').fontSize(20).margin({ bottom: 16 })
Grid() {
ForEach(this.selectedAssets, (uri: string, index: number) => {
GridItem() {
Image(uri)
.width(80)
.height(80)
.borderRadius(8)
.onClick(() => this.selectedAssets.splice(index, 1))
}
})
GridItem() {
Button('Add Image')
.width(80)
.height(80)
.onClick(() => {
if (this.selectedAssets.length < this.maxImageLimit) {
router.pushUrl({ url: 'pages/GalleryPicker' })
}
})
}
}
.columnsTemplate('1fr 1fr 1fr')
.rowsGap(10)
.columnsGap(10)
.margin({ bottom: 20 })
TextArea({ text: this.reviewText, placeholder: 'Describe your experience...' })
.width('100%')
.height(150)
.onChange((value: string) => this.reviewText = value)
}
.padding(16)
}
.width('100%')
.height('100%')
}
}
Media Retrieval and Selection Logic
Accessing the device gallery involves querying the media database using the appropriate permissions. The system media APIs allow applications to fetch image URIs from the shared media store. The selection screen filters available assets and passes the chosen paths back to the parent route using route parameters.
import mediaLibrary from '@ohos.file.media';
import router from '@kit.ArkUI';
import { BusinessError } from '@kit.BasicServicesKit';
@Entry
@Component
struct AssetSelector {
@State previewList: string[] = []
private fetcher: mediaLibrary.MediaAsset | null = null
private queryOptions: mediaLibrary.FetchOptions = {
selection: mediaLibrary.FileKey.MEDIA_TYPE + ' = ?',
selectionArgs: ['1'], // 1 represents images
orderBy: mediaLibrary.FileKey.DATE_ADDED + ' DESC'
}
async aboutToAppear() {
try {
const mediaInstance = mediaLibrary.getMediaLibrary()
await mediaInstance.startPhotoAccess()
this.previewList = await this.queryImageAssets()
} catch (error) {
console.error(`Failed to initialize media access: ${(error as BusinessError).message}`)
}
}
async queryImageAssets(): Promise<string[]> {
// Asset retrieval logic would iterate through media database cursors
// returning valid URI strings for UI rendering
return []
}
confirmSelection() {
router.back({ url: 'pages/ReviewForm', params: { assets: this.previewList } })
}
build() {
Column() {
Grid() {
ForEach(this.previewList, (uri: string) => {
GridItem() {
Image(uri)
.width(100)
.height(100)
.objectFit(ImageFit.Cover)
.borderRadius(6)
}
})
}
.columnsTemplate('repeat(auto-fit, minmax(100px, 1fr))')
Button('Apply Selection')
.margin({ top: 20 })
.onClick(() => this.confirmSelection())
}
.width('100%')
.height('100%')
.padding(16)
}
}
State Synchronization and Data Flow
When navigating back from the media picker, the selected asset URIs must be injected into the review form. HarmonyOS routing mechanisms support parameter passing, enabling the ReviewForm to update its @State array dynamically. The layout automatically recomputes the grid once the state changes, enforcing the maximum attachment limit through conditional rendering.
Text input and image attachment operate independently until form submission. Validation routines should verify that at least one field contains data before transmitting the payload to backend services. The TextArea component buffers keystrokes in real time, while the Grid renders thumbnails using system-level URI resolvers to prevent memory leaks.
Environment Configuration
This implementation targets the Stage model architecture and requires API version 9 or higher. The application must declare the ohos.permission.READ_MEDIA permission in the module.json5 configuration file to access external storage media. Compatibility is verified on standard system deployments, including ARM64-based reference hardware. Compilation requires the appropriate SDK toolchain and IDE configuration.