Pemilih foto tersemat

Animasi yang menampilkan proses pemilihan pemilih foto berkelanjutan

Alat pilih foto tersemat adalah bentuk pengalaman pemilihan foto yang berbeda, yang memungkinkan interaksi langsung dalam antarmuka pengguna aplikasi. Alat ini menawarkan opsi integrasi dan penyesuaian yang ditingkatkan dibandingkan dengan pemilih foto klasik. Karena dirender di SurfaceView menggunakan metode setChildSurfacePackage, fitur keamanan dan privasi yang sama dengan versi yang tidak disematkan tetap dipertahankan.

Dengan pemilih foto tersemat, pengguna dapat terus memilih foto dan video dari perangkat dan galeri 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.

Alat pilih foto tersemat menawarkan integrasi UI yang lebih lancar, tetapi mempertahankan fitur keamanan dan privasi yang sama seperti alat pilih foto standar karena dirender di SurfaceView khusus.

Ketersediaan perangkat

Pemilih foto tersemat 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 tersemat langsung dalam layar Jetpack Compose Anda. Composable ini membuat SurfaceView yang menghosting UI pemilih foto tersemat. Pemilih foto mengelola koneksi ke layanan EmbeddedPhotoPicker, menangani interaksi pengguna, dan mengomunikasikan URI media yang dipilih ke aplikasi panggilan dengan beberapa parameter untuk berfungsi:

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

Pemilihan berkelanjutan

Animasi yang menampilkan proses pemilihan pemilih foto berkelanjutan

Pemilih foto tersemat memungkinkan pengguna memilih dan membatalkan pilihan item secara terus-menerus dari galeri foto tanpa menutup pemilih. Item yang dipilih dan tidak dipilih 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 tersemat bahwa pengguna telah membatalkan pilihan item dari UI aplikasi. Anda perlu mengupdate status UI aplikasi Anda 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

Alat pilih foto tersemat menawarkan opsi untuk personalisasi, sehingga Anda dapat menyesuaikan tampilan dan perilakunya agar lebih terintegrasi dengan desain dan pengalaman pengguna aplikasi Anda.

Warna aksen

Secara default, pemilih foto sematan 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 pedoman 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 sepenuhnya 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 tersemat 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. Menambahkan EmbeddedPhotoPickerStateChangeListener untuk menangani peristiwa pemilihan
  3. Konfigurasikan 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 tersemat:

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