Công cụ chọn ảnh được nhúng

Ảnh động minh hoạ quy trình chọn ảnh liên tục

Bộ chọn ảnh nhúng là một dạng trải nghiệm chọn ảnh khác, cho phép tương tác trực tiếp trong giao diện người dùng của ứng dụng. Thư viện này cung cấp các lựa chọn tuỳ chỉnh và tích hợp nâng cao so với trình chọn ảnh cũ. Vì được kết xuất trên một SurfaceView bằng phương thức setChildSurfacePackage, nên phiên bản này vẫn duy trì các tính năng bảo mật và quyền riêng tư giống như phiên bản không được nhúng.

Với công cụ chọn ảnh được nhúng, người dùng có thể liên tục chọn ảnh và video từ cả thiết bị và thư viện ảnh trên đám mây mà không bị mất tiêu điểm trong ứng dụng khách. Ứng dụng khách vẫn hoạt động, hoạt động của ứng dụng ở trạng thái tiếp tục và có thể phản hồi lựa chọn của người dùng theo thời gian thực.

Công cụ chọn ảnh nhúng mang đến khả năng tích hợp giao diện người dùng liền mạch hơn nhưng vẫn duy trì các tính năng bảo mật và quyền riêng tư tương tự như công cụ chọn ảnh tiêu chuẩn vì công cụ này được kết xuất trên một SurfaceView đặc biệt.

Thiết bị được hỗ trợ

Công cụ chọn ảnh nhúng được hỗ trợ trên các thiết bị chạy Android 14 (API cấp 34) có SDK Extensions phiên bản 15 trở lên.

Những thiết bị không có các chức năng này có thể dựa vào công cụ chọn ảnh phiên bản cũ hoặc phiên bản được điều chỉnh cho phiên bản cũ bằng cách sử dụng dịch vụ Google Play.

Phần phụ thuộc của thư viện Jetpack

Thêm thư viện bộ chọn ảnh Jetpack làm phần phụ thuộc:

// For apps using Jetpack Compose
implementation("androidx.photopicker:photopicker-compose:1.0.0-alpha01")

// For apps using Views
implementation("androidx.photopicker:photopicker:1.0.0-alpha01")

Bạn có thể tích hợp bộ chọn ảnh nhúng bằng Jetpack Compose (nên dùng) hoặc Khung hiển thị.

Tích hợp Jetpack Compose

Hàm có khả năng kết hợp EmbeddedPhotoPicker cung cấp một cơ chế để đưa giao diện người dùng của công cụ chọn ảnh được nhúng trực tiếp vào màn hình Jetpack Compose. Thành phần kết hợp này tạo ra một SurfaceView lưu trữ giao diện người dùng của công cụ chọn ảnh được nhúng. Lớp này quản lý kết nối với dịch vụ EmbeddedPhotoPicker, xử lý các hoạt động tương tác của người dùng và truyền đạt URI nội dung nghe nhìn đã chọn cho ứng dụng gọi bằng một số ít tham số để hoạt động:

val coroutineScope = rememberCoroutineScope()
val pickerState = rememberEmbeddedPhotoPickerState()

EmbeddedPhotoPicker(
    state = pickerState,
    onUriPermissionGranted = { uris ->
        _attachments.value += uris
    },
    onUriPermissionRevoked = { uris ->
        _attachments.value -= uris
    },
    onSelectionComplete = {
        // Hide the embedded photo picker as the user is done with the
        // photo/video selection
    },
)

Lựa chọn liên tục

Ảnh động minh hoạ quy trình chọn ảnh liên tục

Công cụ chọn ảnh nhúng cho phép người dùng liên tục chọn và bỏ chọn các mục trong thư viện ảnh mà không cần đóng công cụ chọn. Các mục được chọn và bỏ chọn trong giao diện người dùng của ứng dụng sẽ được đồng bộ hoá với công cụ chọn ảnh, mang đến trải nghiệm liền mạch cho người dùng.

Bỏ chọn Uri bằng phương thức deselectUri hoặc deselectUris từ pickerState để thông báo cho bộ chọn được nhúng rằng người dùng đã bỏ chọn một mục khỏi giao diện người dùng của ứng dụng. Bạn cần cập nhật trạng thái giao diện người dùng của ứng dụng theo cách thủ công, vì việc gọi các phương thức này sẽ không thông báo cho ứng dụng của bạn về bất kỳ URI mới bị thu hồi nào thông qua lệnh gọi lại onUriPermissionRevoked.

coroutineScope.launch {
    // Signal unselected media to the picker
    pickerState.deselectUris(uris)
    // Remove them from the list of selected media to be reflected in the app's UI
    _attachments.value -= uris
}

Cá nhân hoá công cụ chọn ảnh

Bộ chọn ảnh nhúng cung cấp các lựa chọn cá nhân hoá, cho phép bạn điều chỉnh giao diện và hành vi của bộ chọn này để tích hợp tốt hơn với thiết kế và trải nghiệm người dùng của ứng dụng.

Màu nhấn

Theo mặc định, công cụ chọn ảnh nhúng sẽ dựa vào các màu linh động do hệ thống cung cấp mà người dùng có thể đặt trên các ứng dụng trong các lựa chọn tạo giao diện cho thiết bị. Màu nhấn sẽ được dùng cho nhiều phần tử chính trong bộ chọn ảnh. Tất cả các màu khác sẽ được đặt dựa trên nguyên tắc về Material của Android. Để cá nhân hoá màu nhấn của bộ chọn, hãy xác định lựa chọn EmbeddedPhotoPickerFeatureInfo:

val info = EmbeddedPhotoPickerFeatureInfo.Builder().setAccentColor(0xFF0000).build()

EmbeddedPhotoPicker(
    embeddedPhotoPickerFeatureInfo = info,
    ...
)
Không đặt màu nhấn Có màu nhấn (đỉnh) Có màu nhấn (mở rộng)
Ảnh chụp màn hình của công cụ chọn ảnh mà không đặt màu nhấn Ảnh chụp màn hình công cụ chọn ảnh có màu nhấn (đỉnh) Ảnh chụp màn hình công cụ chọn ảnh có màu nhấn (đã mở rộng)

Màu nhấn phải hoàn toàn mờ đục. Giá trị alpha (độ trong suốt) sẽ bị bỏ qua. Bạn chỉ được phép sử dụng những màu có giá trị độ chói (độ sáng) từ 0,05 đến 0,9.

Kích thước

Theo mặc định, kích thước của bộ chọn được nhúng không bị giới hạn nhưng bạn có thể chỉ định một giá trị sửa đổi để giới hạn kích thước đó:

EmbeddedPhotoPicker(
    modifier = Modifier.height(500.dp),
    ...
)
Không giới hạn (mở rộng) Có giới hạn 500 dp (đã mở rộng)
Ảnh chụp màn hình công cụ chọn ảnh Ảnh chụp màn hình công cụ chọn ảnh

Tích hợp khung hiển thị

Để thêm bộ chọn ảnh nhúng bằng Khung hiển thị, hãy thêm một mục vào tệp bố cục:

<view class="androidx.photopicker.EmbeddedPhotoPickerView"
    android:id="@+id/photopicker"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

Sau đó, hãy khởi chạy công cụ chọn ảnh trong phương thức onCreate của hoạt động bằng cách làm như sau:

  1. Lấy thông tin tham chiếu đến EmbeddedPhotoPickerView từ bố cục
  2. Thêm EmbeddedPhotoPickerStateChangeListener để xử lý các sự kiện chọn
  3. Định cấu hình công cụ chọn ảnh bằng EmbeddedPhotoPickerFeatureInfo, bao gồm mọi chế độ cài đặt tuỳ chỉnh như màu nhấn
// Keep track of the selected media
private val _attachments = MutableStateFlow(emptyList<Uri>())
val attachments = _attachments.asStateFlow()

private lateinit var picker: EmbeddedPhotoPickerView
private var openSession: EmbeddedPhotoPickerSession? = null

val pickerListener = object : EmbeddedPhotoPickerStateChangeListener {
    override fun onSessionOpened(newSession: EmbeddedPhotoPickerSession) {
        // Keep reference to the session to notify the embedded picker of user
        // interactions on the calling app
        openSession = newSession
    }

    override fun onSessionError(throwable: Throwable) {}

    override fun onUriPermissionGranted(uris: List<Uri>) {
        // Add newly selected media to our tracked list
        _attachments += uris
    }

    override fun onUriPermissionRevoked(uris: List<Uri>) {
        // Remove newly unselected media from our tracked list
        _attachments -= uris
    }

    override fun onSelectionComplete() {
        // Hide the embedded photo picker as the user is done with the
        // photo/video selection
    }
}

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

    setContentView(R.layout.main_view)
    picker = findViewById(R.id.photopicker)

    // Attach the embedded picker event listener to update the app's UI
    picker.addEmbeddedPhotoPickerStateChangeListener(pickerListener)

    // Customize embedded picker's features: accent color, max selectable items,
    // pre-selected URIs, filter out mime types
    picker.setEmbeddedPhotoPickerFeatureInfo(
        // Set a custom accent color
        EmbeddedPhotoPickerFeatureInfo.Builder().setAccentColor(0xFF0000).build()
    )
}

Bạn có thể gọi bằng các phương thức khác nhau của EmbeddedPhotoPickerSession để tương tác với bộ chọn được nhúng:

// Notify the embedded picker of a configuration change
openSession.notifyConfigurationChanged(newConfig)

// Update the embedded picker to expand following a user interaction
openSession.notifyPhotoPickerExpanded(/* expanded: */ true)

// Resize the embedded picker
openSession.notifyResized(/* width: */ 512, /* height: */ 256)

// Show/hide the embedded picker (after a form has been submitted)
openSession.notifyVisibilityChanged(/* visible: */ false)

// Remove unselected media from the embedded picker after they have been
// unselected from the host app's UI
openSession.requestRevokeUriPermission(removedUris)