Premiers pas
Chargez des octets PDF, réagissez à l'état de chargement et activez la sélection de texte, les liens, les vignettes et le zoom.
Dans ce tutoriel, vous ouvrez un PDF depuis un sélecteur de fichiers, réagissez à son état de chargement et activez la sélection de texte, les liens, une barre latérale de vignettes et le zoom. Chaque extrait se place dans un source set commonMain de Compose Multiplatform.
Avant de commencer
Ajoutez la dépendance décrite dans l'aperçu du lecteur PDF :
commonMain.dependencies {
implementation("dev.nucleusframework:pdfium:152.0.7947.0")
}Charger les octets du PDF
PdfReaderState.open prend un ByteArray — la façon dont vous l'obtenez vous appartient. Pour choisir un fichier avec une boîte de dialogue native, utilisez FileKit :
@Composable
fun PdfPicker() {
val reader = rememberPdfReaderState()
val scope = rememberCoroutineScope()
val picker = rememberFilePickerLauncher(
type = FileKitType.File(extensions = listOf("pdf")),
) { file ->
if (file != null) scope.launch { reader.open(file.readBytes()) }
}
Column(Modifier.fillMaxSize()) {
Button(onClick = { picker.launch() }) { Text("Ouvrir un PDF…") }
if (reader.pageCount > 0) {
PdfReader(state = reader, modifier = Modifier.fillMaxSize())
}
}
}Pour charger depuis une URL, passez les octets depuis n'importe quel client HTTP :
val client = remember { HttpClient() }
LaunchedEffect(url) { reader.open(client.get(url).readRawBytes()) }Réagir à l'état de chargement et aux erreurs
PdfReaderState expose un état snapshot lisible dans n'importe quel composable — isLoading, error, metadata et pageCount :
Box(Modifier.fillMaxSize()) {
when {
reader.isLoading -> CircularProgressIndicator(Modifier.align(Alignment.Center))
reader.error is PdfError.PasswordRequired -> PasswordPrompt { password ->
scope.launch { reader.open(bytes, password) }
}
reader.error is PdfError.InvalidFormat -> Text("PDF invalide")
reader.error != null -> Text("Ouverture impossible : ${reader.error?.message}")
reader.pageCount > 0 -> {
Column {
Text(reader.metadata.title ?: "Sans titre")
PdfReader(state = reader, modifier = Modifier.weight(1f))
}
}
}
}Activer la sélection de texte
Passez selectableText = true sur PdfPage. Glissez sur desktop, appui long sur mobile, et copiez avec Ctrl/Cmd+C :
PdfPage(
state = reader,
pageIndex = pageIndex,
modifier = Modifier.fillMaxWidth(),
selectableText = true,
)Le hit-testing utilise les boîtes par caractère de PDFium (FPDFText_GetCharBox), donc la sélection suit les glyphes rendus plutôt que les métriques de police de Compose.
Gérer les liens
Les liens sont activés par défaut sur PdfPage et PdfReader. Les annotations de lien et les URL ou adresses e-mail détectées dans le texte de la page deviennent des régions cliquables. Les URI externes s'ouvrent via LocalUriHandler ; dans PdfReader, les liens GoTo internes défilent jusqu'à la page cible.
Interceptez les clics avec onLinkClick — renvoyez true pour consommer le clic et sauter le traitement par défaut :
PdfReader(
state = reader,
onLinkClick = { link ->
if (link.uri?.startsWith("mailto:") == true) {
openCustomComposer(link.uri)
true
} else {
false
}
},
)Ajouter une barre latérale de vignettes
PdfThumbnail rend en RenderQuality.PREVIEW et garde son propre LRU, si bien que faire défiler une longue bande n'évince jamais les bitmaps pleine qualité du lecteur :
Row(Modifier.fillMaxSize()) {
LazyColumn(Modifier.width(160.dp).fillMaxHeight()) {
items(reader.pageCount) { i ->
PdfThumbnail(state = reader, pageIndex = i, modifier = Modifier.clickable { /* jumpToPage(i) */ })
}
}
PdfReader(state = reader, modifier = Modifier.weight(1f).fillMaxHeight())
}Zoom et ajustement à la largeur
PdfReaderState.renderScale est un simple Float que chaque PdfPage observe. 1.0 correspond à l'ajustement à la largeur ; changez-le pour re-rendre les pages visibles à la nouvelle taille :
var scale by remember { mutableStateOf(1f) }
LaunchedEffect(scale) { reader.renderScale = scale }
Slider(value = scale, onValueChange = { scale = it }, valueRange = 0.5f..3f)Extraire du texte par programmation
pageText renvoie l'Unicode d'une seule page ; pageTextLayout renvoie des rectangles au niveau des lignes pour la recherche et le surlignage :
scope.launch {
val text = reader.pageText(pageIndex = 0)
println(text)
}L'app d'exemple de la bibliothèque câble un sélecteur, une barre latérale, le zoom et la sélection dans un écran de lecture complet. Voir le module :example du dépôt pour une référence complète.
Et ensuite
- Référence de l'API — chaque type public, ses paramètres et ses valeurs par défaut.
- Aperçu du lecteur PDF — cibles prises en charge et fonctionnement du chemin de rendu.
- Boîtes de dialogue de fichiers natives — le sélecteur FileKit utilisé ci-dessus.