Selektor zdjęć w ramce

Animacja pokazująca proces ciągłego wybierania zdjęć za pomocą selektora zdjęć

Wbudowany selektor zdjęć to inna forma wybierania zdjęć, która umożliwia interakcję bezpośrednio w interfejsach aplikacji. Zapewnia on lepsze opcje integracji i dostosowywania w porównaniu z klasycznym selektorem zdjęć. Ponieważ jest renderowany na SurfaceView za pomocą metody setChildSurfacePackage, zachowuje te same funkcje bezpieczeństwa i prywatności co wersja nieosadzona.

Dzięki wbudowanemu selektorowi zdjęć użytkownicy mogą stale wybierać zdjęcia i filmy zarówno z urządzenia, jak i z biblioteki zdjęć w chmurze, bez utraty koncentracji w aplikacji klienckiej. Aplikacja kliencka pozostaje aktywna, jej aktywność jest w stanie wznowienia i może reagować na wybory użytkownika w czasie rzeczywistym.

Wbudowany selektor zdjęć zapewnia płynniejszą integrację interfejsu, ale zachowuje te same funkcje bezpieczeństwa i prywatności co standardowy selektor zdjęć, ponieważ jest renderowany na specjalnym elemencie SurfaceView.

Dostępność urządzeń

Wbudowany selektor zdjęć jest obsługiwany na urządzeniach z Androidem 14 (poziom interfejsu API 34) i rozszerzeniami pakietu SDK w wersji 15 lub nowszej.

Urządzenia, które nie spełniają tych wymagań, mogą korzystać z klasycznego selektora zdjęć lub wersji wstecznie przeportowanej za pomocą Usług Google Play.

Zależność biblioteki Jetpack

Dołącz bibliotekę selektora zdjęć Jetpack jako zależność:

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

Wbudowany selektor zdjęć możesz zintegrować za pomocą Jetpack Compose (zalecane) lub widoków.

Integracja z Jetpack Compose

Funkcja typu „composable” EmbeddedPhotoPicker udostępnia mechanizm umożliwiający umieszczenie interfejsu wbudowanego selektora zdjęć bezpośrednio na ekranie Jetpack Compose. Ten element kompozycyjny tworzy obiekt SurfaceView, który zawiera interfejs wbudowanego selektora zdjęć. Zarządza połączeniem z usługą EmbeddedPhotoPicker, obsługuje interakcje użytkownika i przekazuje wybrane identyfikatory URI multimediów do aplikacji wywołującej z kilkoma parametrami:

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

Ciągły wybór

Animacja pokazująca proces ciągłego wybierania zdjęć za pomocą selektora zdjęć

Wbudowany selektor zdjęć umożliwia użytkownikom ciągłe wybieranie i odznaczanie elementów z biblioteki zdjęć bez zamykania selektora. Elementy wybrane i odznaczone w interfejsie aplikacji są synchronizowane z selektorem zdjęć, co zapewnia użytkownikom płynne działanie.

Odznacz Uri, używając metody deselectUri lub deselectUris z pickerState, aby powiadomić wbudowany selektor, że użytkownik odznaczył element w interfejsie aplikacji. Musisz ręcznie zaktualizować stan interfejsu aplikacji, ponieważ wywołanie tych metod nie powiadomi aplikacji o nowo unieważnionych identyfikatorach URI za pomocą wywołania zwrotnego 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
}

Personalizowanie selektora zdjęć

Wbudowany selektor zdjęć oferuje opcje personalizacji, dzięki którym możesz dostosować jego wygląd i działanie, aby lepiej zintegrować go z projektem aplikacji i zapewnić użytkownikom lepsze wrażenia.

Kolor uzupełniający

Domyślnie wbudowany selektor zdjęć korzysta z kolorów dynamicznych dostarczanych przez system, które użytkownik może ustawić w aplikacjach w opcjach motywu urządzenia. Kolor uzupełniający będzie używany w przypadku różnych elementów głównych w selektorze zdjęć. Wszystkie inne kolory zostaną ustawione na podstawie wytycznych dotyczących materiałów na Androida. Aby spersonalizować kolor uzupełniający selektora, zdefiniuj opcję EmbeddedPhotoPickerFeatureInfo:

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

EmbeddedPhotoPicker(
    embeddedPhotoPickerFeatureInfo = info,
    ...
)
Bez ustawiania koloru uzupełniającego Z kolorem uzupełniającym (szczyt) Z kolorem uzupełniającym (rozwinięty)
Zrzut ekranu selektora zdjęć bez ustawionego koloru uzupełniającego Zrzut ekranu selektora zdjęć z kolorem uzupełniającym (szczyt) Zrzut ekranu selektora zdjęć z kolorem uzupełniającym (rozwinięty)

Kolor uzupełniający musi być całkowicie nieprzezroczysty. Wartość alfa (przejrzystość) jest ignorowana. Dozwolone są tylko kolory o wartości luminancji (jasności) od 0,05 do 0,9.

Wymiary

Domyślnie rozmiar osadzonego selektora nie jest ograniczony, ale możesz określić modyfikator, aby go ograniczyć:

EmbeddedPhotoPicker(
    modifier = Modifier.height(500.dp),
    ...
)
Bez limitu (rozwinięte) Z limitem 500 dp (rozwinięty)
Zrzut ekranu selektora zdjęć Zrzut ekranu selektora zdjęć

Integracja widoków

Aby dodać wbudowany selektor zdjęć za pomocą widoków, dodaj wpis do pliku układu:

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

Następnie zainicjuj selektor zdjęć w metodzie onCreate aktywności, wykonując te czynności:

  1. Uzyskiwanie odwołania do elementu EmbeddedPhotoPickerView z układu
  2. Dodaj EmbeddedPhotoPickerStateChangeListener, aby obsługiwać zdarzenia wyboru
  3. Skonfiguruj selektor zdjęć za pomocą EmbeddedPhotoPickerFeatureInfo, w tym ustawienia niestandardowe, takie jak kolor uzupełniający
// 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()
    )
}

Możesz wywoływać różne metody EmbeddedPhotoPickerSession, aby wchodzić w interakcję z umieszczonym selektorem:

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