Pemilih foto tersemat

Animasi yang menunjukkan proses pemilihan alat pilih foto berkelanjutan

Pemilih foto sematan adalah bentuk pengalaman pemilihan foto yang berbeda, yang memungkinkan interaksi langsung dalam antarmuka pengguna aplikasi. Fitur ini menawarkan opsi integrasi dan penyesuaian yang ditingkatkan dibandingkan dengan pemilih foto klasik. Saat dirender di SurfaceView menggunakan metode setChildSurfacePackage, versi yang disematkan mempertahankan fitur keamanan dan privasi yang sama dengan versi yang tidak disematkan.

Dengan pemilih foto yang disematkan, pengguna dapat terus memilih foto dan video dari perangkat dan library foto cloud mereka tanpa kehilangan fokus di aplikasi klien. Aplikasi klien tetap aktif, aktivitasnya dalam status dilanjutkan dan dapat merespons pilihan pengguna secara real time.

Pemilih foto sematan menawarkan integrasi UI yang lebih lancar, tetapi mempertahankan fitur keamanan dan privasi yang sama dengan pemilih foto standar karena dirender di SurfaceView khusus.

Ketersediaan perangkat

Pemilih foto sematan didukung di perangkat yang menjalankan Android 14 (level API 34) dengan SDK Extensions versi 15 atau yang lebih tinggi.

Perangkat yang tidak sesuai dengan kemampuan ini dapat mengandalkan pemilih foto klasik atau versi backport menggunakan layanan Google Play.

Dependensi library Jetpack

Sertakan library pemilih foto Jetpack sebagai dependensi:

// 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")

Anda dapat mengintegrasikan pemilih foto sematan menggunakan Jetpack Compose (direkomendasikan) atau View.

Integrasi Jetpack Compose

Fungsi composable EmbeddedPhotoPicker menyediakan mekanisme untuk menyertakan UI pemilih foto yang disematkan langsung dalam layar Jetpack Compose Anda. Composable ini membuat SurfaceView yang menghosting UI pemilih foto yang disematkan. Layanan ini mengelola koneksi ke layanan EmbeddedPhotoPicker, menangani interaksi pengguna, dan mengomunikasikan URI media yang dipilih ke aplikasi yang memanggil dengan beberapa parameter untuk dikerjakan:

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
    },
)

Pilihan berkelanjutan

Animasi yang menunjukkan proses pemilihan alat pilih foto berkelanjutan

Pemilih foto yang disematkan memungkinkan pengguna terus memilih dan membatalkan pilihan item dari koleksi foto tanpa menutup pemilih. Item yang dipilih dan dibatalkan pilihannya di UI aplikasi disinkronkan dengan alat pilih foto, sehingga memberikan pengalaman pengguna yang lancar.

Batalkan pilihan Uri menggunakan metode deselectUri atau deselectUris dari pickerState untuk memberi tahu pemilih sematan bahwa pengguna telah membatalkan pilihan item dari UI aplikasi. Anda harus memperbarui status UI aplikasi sendiri secara manual, karena memanggil metode ini tidak akan memberi tahu aplikasi Anda tentang URI yang baru dicabut melalui callback 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
}

Mempersonalisasi pemilih foto

Pemilih foto yang disematkan menawarkan opsi personalisasi, sehingga Anda dapat menyesuaikan tampilan dan perilakunya agar terintegrasi lebih baik dengan desain dan pengalaman pengguna aplikasi Anda.

Warna aksen

Secara default, pemilih foto tersemat mengandalkan warna dinamis yang disediakan oleh sistem yang dapat ditetapkan pengguna di seluruh aplikasi dalam opsi tema perangkat. Warna aksen akan digunakan untuk berbagai elemen utama di pemilih foto. Semua warna lainnya akan ditetapkan berdasarkan panduan material Android. Untuk mempersonalisasi warna aksen pemilih, tentukan opsi EmbeddedPhotoPickerFeatureInfo:

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

EmbeddedPhotoPicker(
    embeddedPhotoPickerFeatureInfo = info,
    ...
)
Tanpa menyetel warna aksen Dengan warna aksen (puncak) Dengan warna aksen (diperluas)
Screenshot pemilih foto tanpa menyetel warna aksen Screenshot pemilih foto dengan warna aksen (puncak) Screenshot pemilih foto dengan warna aksen (diperluas)

Warna aksen harus benar-benar buram. Nilai alfa (transparansi) diabaikan. Hanya warna dengan nilai luminans (kecerahan) antara 0,05 dan 0,9 yang diizinkan.

Dimensi

Secara default, ukuran pemilih sematan tidak dibatasi, tetapi Anda dapat menentukan pengubah untuk membatasinya:

EmbeddedPhotoPicker(
    modifier = Modifier.height(500.dp),
    ...
)
Tanpa batas (diperluas) Dengan batas 500 dp (diperluas)
Screenshot pemilih foto Screenshot pemilih foto

Integrasi tampilan

Untuk menambahkan pemilih foto sematan menggunakan View, tambahkan entri ke file tata letak Anda:

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

Kemudian, lakukan inisialisasi pemilih foto dalam metode onCreate aktivitas Anda dengan melakukan hal berikut:

  1. Mendapatkan referensi ke EmbeddedPhotoPickerView dari tata letak
  2. Tambahkan EmbeddedPhotoPickerStateChangeListener untuk menangani peristiwa pemilihan
  3. Konfigurasi pemilih foto dengan EmbeddedPhotoPickerFeatureInfo, termasuk setelan kustom seperti warna aksen
// 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()
    )
}

Anda dapat memanggil dengan berbagai metode EmbeddedPhotoPickerSession untuk berinteraksi dengan pemilih yang disematkan:

// 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)