Skip to content

Commit 228b855

Browse files
committed
rework entire arch, preserve state, print, share, remove temp files, consolidate options
1 parent ad22540 commit 228b855

29 files changed

Lines changed: 805 additions & 279 deletions

README.md

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,13 @@ This library provides an easy to consume Android Composable that will display PD
77
## Add the dependency
88

99
```Gradle
10-
implementation 'com.pnuema.android:pdfviewer:1.2.3'
10+
implementation 'com.pnuema.android:pdfviewer:1.3.0'
1111
```
1212
```Kotlin(KTS)
13-
implementation("com.pnuema.android:pdfviewer:1.2.3")
13+
implementation("com.pnuema.android:pdfviewer:1.3.0")
1414
```
1515
```TOML
16-
pdfviewer = { module = "com.pnuema.android:pdfviewer", version.ref = "1.2.3" }
16+
pdfviewer = { module = "com.pnuema.android:pdfviewer", version.ref = "1.3.0" }
1717
```
1818

1919
## Usage
@@ -68,6 +68,9 @@ Background color to display behind the rendered pdf. Defaults to `Color.White`
6868
```pageDivider: @Composable```
6969
Composable that will be displayed between each rendered page of the pdf.
7070

71+
```enableActions: Boolean```
72+
Enable long pressing the document to show pdf actions such as print document
73+
7174
### Example
7275

7376
There is an example application included in this repo in the app folder. This will highlight a simple usage of both of the ways to load and display a pdf.
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<network-security-config>
3+
<debug-overrides>
4+
<trust-anchors>
5+
<certificates src="system" />
6+
<certificates src="user" />
7+
</trust-anchors>
8+
</debug-overrides>
9+
</network-security-config>

app/src/main/AndroidManifest.xml

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?xml version="1.0" encoding="utf-8"?>
2-
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
3-
xmlns:tools="http://schemas.android.com/tools">
2+
<manifest
3+
xmlns:android="http://schemas.android.com/apk/res/android">
44

55
<uses-permission android:name="android.permission.INTERNET" />
66

@@ -10,15 +10,14 @@
1010
android:fullBackupContent="@xml/backup_rules"
1111
android:icon="@mipmap/ic_launcher"
1212
android:label="@string/app_name"
13+
android:networkSecurityConfig="@xml/network_security_config"
1314
android:roundIcon="@mipmap/ic_launcher_round"
14-
android:supportsRtl="true"
15-
tools:targetApi="31">
15+
android:supportsRtl="true">
1616
<activity
1717
android:name=".MainActivity"
1818
android:exported="true">
1919
<intent-filter>
2020
<action android:name="android.intent.action.MAIN" />
21-
2221
<category android:name="android.intent.category.LAUNCHER" />
2322
</intent-filter>
2423
</activity>

app/src/main/kotlin/com/example/pdfviewer/MainActivity.kt

Lines changed: 116 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,44 +3,157 @@ package com.example.pdfviewer
33
import android.os.Bundle
44
import androidx.activity.ComponentActivity
55
import androidx.activity.compose.setContent
6+
import androidx.compose.foundation.ExperimentalFoundationApi
67
import androidx.compose.foundation.layout.fillMaxSize
8+
import androidx.compose.foundation.layout.fillMaxWidth
9+
import androidx.compose.foundation.layout.heightIn
710
import androidx.compose.foundation.layout.padding
11+
import androidx.compose.material3.ExperimentalMaterial3Api
12+
import androidx.compose.material3.ModalBottomSheet
13+
import androidx.compose.material3.OutlinedButton
814
import androidx.compose.material3.Scaffold
15+
import androidx.compose.material3.SheetState
916
import androidx.compose.material3.Surface
1017
import androidx.compose.material3.Text
18+
import androidx.compose.material3.rememberModalBottomSheetState
19+
import androidx.compose.runtime.Composable
20+
import androidx.compose.runtime.getValue
21+
import androidx.compose.runtime.mutableStateOf
22+
import androidx.compose.runtime.remember
23+
import androidx.compose.runtime.rememberCoroutineScope
24+
import androidx.compose.runtime.setValue
1125
import androidx.compose.ui.Alignment
1226
import androidx.compose.ui.Modifier
1327
import androidx.compose.ui.graphics.Color
28+
import androidx.compose.ui.hapticfeedback.HapticFeedbackType
29+
import androidx.compose.ui.platform.LocalHapticFeedback
30+
import androidx.compose.ui.res.stringResource
31+
import androidx.compose.ui.text.style.TextAlign
32+
import androidx.compose.ui.unit.dp
1433
import com.example.pdfviewer.ui.theme.PdfViewerTheme
1534
import com.pnuema.android.pdfviewer.PdfViewer
35+
import kotlinx.coroutines.launch
36+
import com.pnuema.android.pdfviewer.rememberPdfOptions
1637

1738
class MainActivity : ComponentActivity() {
39+
@OptIn(ExperimentalMaterial3Api::class, ExperimentalFoundationApi::class)
1840
override fun onCreate(savedInstanceState: Bundle?) {
1941
super.onCreate(savedInstanceState)
2042

2143
setContent {
2244
PdfViewerTheme {
23-
// A surface container using the 'background' color from the theme
45+
val sheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true)
46+
val coroutineScope = rememberCoroutineScope()
47+
var showContextMenu by remember { mutableStateOf(false) }
48+
val pdfOptions = rememberPdfOptions()
49+
2450
Scaffold { padding ->
2551
Surface(
2652
modifier = Modifier
2753
.fillMaxSize()
28-
.padding(top = padding.calculateTopPadding()),
54+
.padding(padding),
2955
color = Color.LightGray
3056
) {
57+
58+
val haptics = LocalHapticFeedback.current
3159
PdfViewer(
3260
url = "https://raw.githubusercontent.com/barnhill/ComposePdfViewer/main/app/src/main/assets/sample.pdf",
61+
options = pdfOptions,
3362
loadingContent = {
3463
Text(
3564
modifier = Modifier.align(Alignment.Center),
3665
text = "Loading..."
3766
)
67+
},
68+
onLongClick = {
69+
haptics.performHapticFeedback(HapticFeedbackType.LongPress)
70+
showContextMenu = !sheetState.isVisible
71+
}
72+
)
73+
/*PdfViewer(
74+
file = FileUtil.getTestFile(this),
75+
options = pdfOptions,
76+
onLongClick = {
77+
haptics.performHapticFeedback(HapticFeedbackType.LongPress)
78+
showContextMenu = !sheetState.isVisible
79+
}
80+
)*/
81+
}
82+
83+
if (showContextMenu) {
84+
PdfOptionsMenu(
85+
sheetState = sheetState,
86+
onDismissRequest = { showContextMenu = false },
87+
onPrintClicked = {
88+
coroutineScope.launch {
89+
sheetState.hide()
90+
pdfOptions.print()
91+
}.invokeOnCompletion {
92+
if (!sheetState.isVisible) {
93+
showContextMenu = false
94+
}
95+
}
96+
},
97+
onShareClicked = {
98+
coroutineScope.launch {
99+
sheetState.hide()
100+
pdfOptions.share()
101+
}.invokeOnCompletion {
102+
if (!sheetState.isVisible) {
103+
showContextMenu = false
104+
}
105+
}
38106
}
39107
)
40-
/*PdfViewer(file = FileUtil.getTestFile(this))*/
41108
}
42109
}
43110
}
44111
}
45112
}
113+
114+
@OptIn(ExperimentalMaterial3Api::class)
115+
@Composable
116+
private fun PdfOptionsMenu(
117+
modifier: Modifier = Modifier,
118+
sheetState: SheetState,
119+
onDismissRequest: () -> Unit,
120+
onPrintClicked: () -> Unit,
121+
onShareClicked: () -> Unit,
122+
) {
123+
ModalBottomSheet(
124+
modifier = modifier,
125+
sheetState = sheetState,
126+
onDismissRequest = onDismissRequest
127+
) {
128+
OutlinedButton(
129+
modifier = Modifier
130+
.heightIn(48.dp)
131+
.padding(horizontal = 16.dp)
132+
.padding(top = 16.dp)
133+
.fillMaxWidth(),
134+
onClick = onPrintClicked
135+
) {
136+
Text(
137+
modifier = Modifier.fillMaxWidth(),
138+
textAlign = TextAlign.Center,
139+
text = stringResource(R.string.print_button_label)
140+
)
141+
}
142+
143+
OutlinedButton(
144+
modifier = Modifier
145+
.heightIn(48.dp)
146+
.padding(horizontal = 16.dp)
147+
.padding(vertical = 16.dp)
148+
.fillMaxWidth(),
149+
onClick = onShareClicked
150+
) {
151+
Text(
152+
modifier = Modifier.fillMaxWidth(),
153+
textAlign = TextAlign.Center,
154+
text = stringResource(R.string.share_button_label)
155+
)
156+
}
157+
}
158+
}
46159
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<resources>
3+
<string name="document_long_press_content_description">Opciones de PDF</string>
4+
<string name="print_button_label">Imprimir</string>
5+
<string name="share_button_label">Compartir</string>
6+
</resources>
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<resources>
3+
<string name="document_long_press_content_description">Options PDF</string>
4+
<string name="print_button_label">Imprimer</string>
5+
<string name="share_button_label">Partager</string>
6+
</resources>
Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
11
<resources>
2-
<string name="app_name">PdfViewer</string>
2+
<string name="app_name" translatable="false">PdfViewer</string>
3+
4+
<string name="document_long_press_content_description">PDF Options</string>
5+
<string name="print_button_label">Print</string>
6+
<string name="share_button_label">Share</string>
37
</resources>
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<network-security-config>
3+
<debug-overrides>
4+
<trust-anchors>
5+
<certificates src="system" />
6+
</trust-anchors>
7+
</debug-overrides>
8+
</network-security-config>

gradle.properties

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
# http://www.gradle.org/docs/current/userguide/build_environment.html
77
# Specifies the JVM arguments used for the daemon process.
88
# The setting is particularly useful for tweaking memory settings.
9-
org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
9+
org.gradle.jvmargs=-Xmx1048m -Dfile.encoding=UTF-8
1010
# When configured, Gradle will run in incubating parallel mode.
1111
# This option should only be used with decoupled projects. More details, visit
1212
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
@@ -28,7 +28,7 @@ org.jetbrains.dokka.experimental.gradle.pluginMode=V2Enabled
2828
org.jetbrains.dokka.experimental.gradle.pluginMode.noWarn=true
2929

3030
GROUP=com.pnuema.android
31-
VERSION_NAME=1.2.3
31+
VERSION_NAME=1.3.0
3232

3333
POM_NAME=PdfViewer
3434
POM_ARTIFACT_ID=pdfviewer

gradle/libs.versions.toml

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,17 @@
11
[versions]
2-
minSdk = "23"
2+
minSdk = "24"
33
targetSdk = "35"
4-
cronetApi = "119.6045.31"
5-
cronetOkhttp = "0.1.0"
6-
playServicesCronet = "18.1.0"
74
androidx-appcompat = "1.7.0"
85
androidx-compose-ui = "1.7.8"
9-
androidx-material3 = "1.3.1"
6+
androidx-compose-viewmodel = "2.8.7"
7+
androidx-material3 = "1.3.2"
108
material = "1.12.0"
119
androidx-activity = "1.10.1"
12-
androidx-core = "1.15.0"
10+
androidx-core = "1.16.0"
1311
androidx-lifecycle = "2.8.7"
1412
okhttp = "4.12.0"
1513
zoomable = "0.15.1"
16-
compose-bom = "2025.03.01"
14+
compose-bom = "2025.04.00"
1715

1816
#plugins
1917
android-gradle-plugin = "8.9.1"
@@ -33,13 +31,12 @@ androidx-compose-ui = { module = "androidx.compose.ui:ui", version.ref = "androi
3331
androidx-compose-ui-graphics = { module = "androidx.compose.ui:ui-graphics", version.ref = "androidx-compose-ui" }
3432
androidx-compose-ui-tooling-preview = { module = "androidx.compose.ui:ui-tooling-preview", version.ref = "androidx-compose-ui" }
3533
androidx-compose-ui-tooling = { module = "androidx.compose.ui:ui-tooling", version.ref = "androidx-compose-ui" }
36-
cronet-api = { module = "org.chromium.net:cronet-api", version.ref = "cronetApi" }
37-
cronet-okhttp = { module = "com.google.net.cronet:cronet-okhttp", version.ref = "cronetOkhttp" }
34+
androidx-compose-viewmodel = { module = "androidx.lifecycle:lifecycle-viewmodel-compose", version.ref = "androidx-compose-viewmodel" }
3835
okhttp-logging = { module = "com.squareup.okhttp3:logging-interceptor", version.ref = "okhttp" }
3936
material = { module = "com.google.android.material:material", version.ref = "material" }
40-
play-services-cronet = { module = "com.google.android.gms:play-services-cronet", version.ref = "playServicesCronet" }
4137
zoomable = { module = "me.saket.telephoto:zoomable", version.ref = "zoomable" }
4238
okhttp = { module = "com.squareup.okhttp3:okhttp", version.ref = "okhttp" }
39+
okhttp-brotli = { module = "com.squareup.okhttp3:okhttp-brotli", version.ref = "okhttp" }
4340

4441
[plugins]
4542
android-library = { id = "com.android.library", version.ref = "android-gradle-plugin" }

0 commit comments

Comments
 (0)