Add PdfBox library for future parsing
Change buttons to chips
This commit is contained in:
parent
df3b9ac93b
commit
04a64bd621
|
@ -51,4 +51,6 @@ dependencies {
|
|||
testImplementation(libs.junit)
|
||||
androidTestImplementation(libs.androidx.junit)
|
||||
androidTestImplementation(libs.androidx.espresso.core)
|
||||
|
||||
implementation(libs.pdfbox.android)
|
||||
}
|
|
@ -11,6 +11,8 @@ import android.view.Display
|
|||
import android.view.Menu
|
||||
import android.view.WindowManager
|
||||
import android.widget.ImageView
|
||||
import androidx.activity.SystemBarStyle
|
||||
import androidx.activity.enableEdgeToEdge
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
import com.google.android.material.navigation.NavigationView
|
||||
import androidx.navigation.findNavController
|
||||
|
@ -23,6 +25,7 @@ import androidx.appcompat.app.AppCompatActivity
|
|||
import androidx.core.view.WindowCompat
|
||||
import androidx.core.view.WindowInsetsCompat
|
||||
import com.lhw.pdf.databinding.ActivityMainBinding
|
||||
import com.tom_roush.pdfbox.android.PDFBoxResourceLoader
|
||||
import java.io.File
|
||||
import java.io.FileOutputStream
|
||||
import java.io.InputStream
|
||||
|
@ -37,6 +40,11 @@ class MainActivity : AppCompatActivity() {
|
|||
private val thumbnailHeight = 700
|
||||
private var renderAutoCrop = true
|
||||
private var pagesPerLandscape = 3F
|
||||
private set(pages) {
|
||||
field = pages
|
||||
updatePresentations()
|
||||
}
|
||||
private var usePdfBox = false
|
||||
private val presentations = mutableMapOf<Int, MyPresentation>()
|
||||
private lateinit var pdfDocument: PdfDocument
|
||||
private val showPages = mutableListOf<Boolean>()
|
||||
|
@ -151,12 +159,15 @@ class MainActivity : AppCompatActivity() {
|
|||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
//enableEdgeToEdge()
|
||||
super.onCreate(savedInstanceState)
|
||||
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
|
||||
displayManager = getSystemService(Context.DISPLAY_SERVICE) as DisplayManager
|
||||
//val windowInsetsController = WindowCompat.getInsetsController(window, window.decorView)
|
||||
//windowInsetsController.hide(WindowInsetsCompat.Type.systemBars()) //Doesn't seem to actually fill the vacant space by default
|
||||
|
||||
PDFBoxResourceLoader.init(this)
|
||||
|
||||
binding = ActivityMainBinding.inflate(layoutInflater)
|
||||
setContentView(binding.root)
|
||||
|
||||
|
@ -169,7 +180,7 @@ class MainActivity : AppCompatActivity() {
|
|||
if (!file.exists()) {
|
||||
file = inputStreamToCache(defaultCachedFileName, resources.openRawResource(R.raw.testpdf))
|
||||
}
|
||||
pdfDocument = PdfDocument(file, true)
|
||||
pdfDocument = PdfDocument(file, usePdfBox = false, autoCrop = true)
|
||||
// Then overwrite it with any pdf sent via intent
|
||||
handleIntent(intent)
|
||||
|
||||
|
@ -184,26 +195,24 @@ class MainActivity : AppCompatActivity() {
|
|||
presentations.values.forEach {it.setScrollProgress(progress)}
|
||||
}
|
||||
|
||||
binding.appBarMain.crop.setOnClickListener { view ->
|
||||
renderAutoCrop = !renderAutoCrop
|
||||
val s = if (renderAutoCrop) "On" else "Off"
|
||||
Snackbar.make(view, "Toggling Auto Crop $s", Snackbar.LENGTH_LONG)
|
||||
.setAction("Action", null)
|
||||
.setAnchorView(R.id.crop).show()
|
||||
binding.appBarMain.contentMain.chipPages1.setOnCheckedChangeListener { _, checked -> if (checked) pagesPerLandscape = 1F }
|
||||
binding.appBarMain.contentMain.chipPages15.setOnCheckedChangeListener { _, checked -> if (checked) pagesPerLandscape = 1.5F }
|
||||
binding.appBarMain.contentMain.chipPages2.setOnCheckedChangeListener { _, checked -> if (checked) pagesPerLandscape = 2F }
|
||||
binding.appBarMain.contentMain.chipPages25.setOnCheckedChangeListener { _, checked -> if (checked) pagesPerLandscape = 2.5F }
|
||||
binding.appBarMain.contentMain.chipPages3.setOnCheckedChangeListener { _, checked -> if (checked) pagesPerLandscape = 3F }
|
||||
binding.appBarMain.contentMain.chipPages35.setOnCheckedChangeListener { _, checked -> if (checked) pagesPerLandscape = 3.5F }
|
||||
binding.appBarMain.contentMain.chipPages4.setOnCheckedChangeListener { _, checked -> if (checked) pagesPerLandscape = 4F }
|
||||
binding.appBarMain.contentMain.chipPages5.setOnCheckedChangeListener { _, checked -> if (checked) pagesPerLandscape = 5F }
|
||||
binding.appBarMain.contentMain.chipPages6.setOnCheckedChangeListener { _, checked -> if (checked) pagesPerLandscape = 6F }
|
||||
binding.appBarMain.contentMain.chipPages8.setOnCheckedChangeListener { _, checked -> if (checked) pagesPerLandscape = 8F }
|
||||
binding.appBarMain.contentMain.chipPages10.setOnCheckedChangeListener { _, checked -> if (checked) pagesPerLandscape = 10F }
|
||||
binding.appBarMain.contentMain.chipAutoCrop.setOnCheckedChangeListener { _, checked ->
|
||||
renderAutoCrop = checked
|
||||
updatePresentations()
|
||||
}
|
||||
binding.appBarMain.zoomIn.setOnClickListener { view ->
|
||||
pagesPerLandscape = max(pagesPerLandscape - 0.5F, 1F)
|
||||
Snackbar.make(view, "Aiming for $pagesPerLandscape pages at a time", Snackbar.LENGTH_LONG)
|
||||
.setAction("Action", null)
|
||||
.setAnchorView(R.id.zoom_in).show()
|
||||
updatePresentations()
|
||||
}
|
||||
binding.appBarMain.zoomOut.setOnClickListener { view ->
|
||||
pagesPerLandscape = min(pagesPerLandscape + 0.5F, 10F)
|
||||
Snackbar.make(view, "Aiming for $pagesPerLandscape pages at a time", Snackbar.LENGTH_LONG)
|
||||
.setAction("Action", null)
|
||||
.setAnchorView(R.id.zoom_out).show()
|
||||
binding.appBarMain.contentMain.chipUsePdfBox.setOnCheckedChangeListener { _, checked ->
|
||||
usePdfBox = checked
|
||||
pdfDocument.usePdfBox = usePdfBox
|
||||
updatePresentations()
|
||||
}
|
||||
val drawerLayout: DrawerLayout = binding.drawerLayout
|
||||
|
|
|
@ -7,25 +7,40 @@ import android.graphics.Rect
|
|||
import android.graphics.RectF
|
||||
import android.graphics.pdf.PdfRenderer
|
||||
import android.os.ParcelFileDescriptor
|
||||
import com.tom_roush.pdfbox.pdmodel.PDDocument
|
||||
import com.tom_roush.pdfbox.rendering.PDFRenderer
|
||||
import java.io.File
|
||||
import kotlin.math.max
|
||||
import kotlin.math.min
|
||||
|
||||
class PdfDocument(private val fileCached: File, private val autoCrop: Boolean = false) {
|
||||
class PdfDocument(private val fileCached: File, var usePdfBox: Boolean = true, private val autoCrop: Boolean = false) {
|
||||
// Stock Android PdfRenderer - fast but limited
|
||||
private val pfd = ParcelFileDescriptor.open(fileCached, ParcelFileDescriptor.MODE_READ_ONLY)
|
||||
private val renderer = PdfRenderer(pfd)
|
||||
val bitmapThumbnails = mutableMapOf<Int, Bitmap>()
|
||||
val bitmapPages = mutableMapOf<Pair<Int, Int>, MutableMap<Int, Bitmap>>() // bitmapPages[<maxWidthPx, maxHeightPx>][pageId]
|
||||
private val pagePtWidths = mutableListOf<Int>()
|
||||
private val pagePtHeights = mutableListOf<Int>()
|
||||
// PdfBox parser/renderer - powerful but slow
|
||||
private val pdfDocument = PDDocument.load(fileCached)
|
||||
private val boxRenderer = PDFRenderer(pdfDocument)
|
||||
private val boxPagePtWidths = mutableListOf<Float>()
|
||||
private val boxPagePtHeights = mutableListOf<Float>()
|
||||
|
||||
val bitmapThumbnails = mutableMapOf<Int, Bitmap>()
|
||||
val bitmapPages = mutableMapOf<Pair<Int, Int>, MutableMap<Int, Bitmap>>() // bitmapPages[<maxWidthPx, maxHeightPx>][pageId]
|
||||
private val pageAutoCropRects = mutableListOf<RectF>()
|
||||
// Due to the way thumbnails render, the bottom right is more likely to be cut off
|
||||
private val autoCropSafetyMarginUpper = 2
|
||||
private val autoCropSafetyMarginLower = 16
|
||||
|
||||
private val numPages get() = if (usePdfBox) pdfDocument.numberOfPages else renderer.pageCount
|
||||
|
||||
init {
|
||||
val numPages = renderer.pageCount
|
||||
for (i in 0..<numPages) {
|
||||
// PdfBox
|
||||
val bBox = pdfDocument.getPage(i).bBox
|
||||
boxPagePtWidths.add(bBox.width)
|
||||
boxPagePtHeights.add(bBox.height)
|
||||
// Android
|
||||
val page = renderer.openPage(i)
|
||||
pagePtWidths.add(page.width)
|
||||
pagePtHeights.add(page.height)
|
||||
|
@ -33,6 +48,7 @@ class PdfDocument(private val fileCached: File, private val autoCrop: Boolean =
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
private val rectFIdentity = RectF(0F, 0F, 1F, 1F)
|
||||
private fun renderPage(index: Int, maxWidth: Int, maxHeight: Int, crop: Boolean = false): Bitmap {
|
||||
val cropRect = if (!crop || pageAutoCropRects.size <= index) rectFIdentity else pageAutoCropRects[index]
|
||||
|
@ -42,22 +58,27 @@ class PdfDocument(private val fileCached: File, private val autoCrop: Boolean =
|
|||
val heightFromMaxWidth = (ptHeight * maxWidth/ptWidth).toInt()
|
||||
val (width, height) = if (widthFromMaxHeight > maxWidth) Pair(maxWidth, heightFromMaxWidth) else Pair(widthFromMaxHeight, maxHeight)
|
||||
|
||||
val page = renderer.openPage(index)
|
||||
println("Creating page $index bitmap with width $width and height $height from cropRect $cropRect")
|
||||
val bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
|
||||
val ptToPixel = height/ptHeight
|
||||
val transform = Matrix()
|
||||
val transposePtX = -cropRect.left * ptWidth
|
||||
val transposePtY = -cropRect.top * ptHeight
|
||||
transform.setValues(floatArrayOf(ptToPixel, 0F, transposePtX*ptToPixel, 0F, ptToPixel, transposePtY*ptToPixel, 0F, 0F, 1F))
|
||||
page.render(bitmap, null, transform, PdfRenderer.Page.RENDER_MODE_FOR_DISPLAY)
|
||||
page.close()
|
||||
val bitmap: Bitmap
|
||||
if (usePdfBox) {
|
||||
val scale = width / ptWidth
|
||||
bitmap = boxRenderer.renderImage(index, scale)
|
||||
} else {
|
||||
val page = renderer.openPage(index)
|
||||
println("Creating page $index bitmap with width $width and height $height from cropRect $cropRect")
|
||||
bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
|
||||
val ptToPixel = height / ptHeight
|
||||
val transform = Matrix()
|
||||
val transposePtX = -cropRect.left * ptWidth
|
||||
val transposePtY = -cropRect.top * ptHeight
|
||||
transform.setValues(floatArrayOf(ptToPixel, 0F, transposePtX * ptToPixel, 0F, ptToPixel, transposePtY * ptToPixel, 0F, 0F, 1F))
|
||||
page.render(bitmap, null, transform, PdfRenderer.Page.RENDER_MODE_FOR_DISPLAY)
|
||||
page.close()
|
||||
}
|
||||
return bitmap
|
||||
}
|
||||
|
||||
private fun renderPagesToMap(map: MutableMap<Int, Bitmap>, width: Int, height: Int, crop: Boolean = false, overwrite: Boolean = true) {
|
||||
if (overwrite) map.clear()
|
||||
val numPages = renderer.pageCount
|
||||
for (i in 0..<numPages) {
|
||||
map.computeIfAbsent(i) { renderPage(i, width, height, crop) }
|
||||
}
|
||||
|
@ -72,7 +93,6 @@ class PdfDocument(private val fileCached: File, private val autoCrop: Boolean =
|
|||
println("Thumbnails rendered")
|
||||
if (autoCrop) {
|
||||
println("Auto cropping from thumbnails")
|
||||
val numPages = renderer.pageCount
|
||||
pageAutoCropRects.clear()
|
||||
for (i in 0..<numPages) {
|
||||
println("Auto cropping page $i from thumbnail")
|
||||
|
|
|
@ -22,39 +22,4 @@
|
|||
|
||||
<include android:id="@+id/content_main" layout="@layout/content_main" />
|
||||
|
||||
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||
android:id="@+id/crop"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="bottom|end"
|
||||
android:layout_marginEnd="@dimen/fab_margin"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:importantForAccessibility="no"
|
||||
app:maxImageSize="48dp"
|
||||
app:srcCompat="@android:drawable/ic_menu_crop" />
|
||||
|
||||
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||
android:id="@+id/zoom_in"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="bottom|start"
|
||||
android:layout_marginStart="96dp"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:importantForAccessibility="no"
|
||||
app:maxImageSize="48dp"
|
||||
app:srcCompat="@android:drawable/ic_menu_zoom" />
|
||||
|
||||
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||
android:id="@+id/zoom_out"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="bottom|start"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:importantForAccessibility="no"
|
||||
android:rotationY="180"
|
||||
android:rotationX="180"
|
||||
app:maxImageSize="48dp"
|
||||
app:srcCompat="@android:drawable/ic_menu_zoom" />
|
||||
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
|
@ -18,54 +18,157 @@
|
|||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:navGraph="@navigation/mobile_navigation" />
|
||||
|
||||
<HorizontalScrollView
|
||||
android:id="@+id/thumbnails_disabled_scroll"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="300dp"
|
||||
android:background="#80C01010"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintVertical_bias="0.0">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/thumbnails_disabled_layout"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="horizontal"
|
||||
tools:showIn="@layout/content_main" />
|
||||
</HorizontalScrollView>
|
||||
|
||||
<HorizontalScrollView
|
||||
android:id="@+id/thumbnails_scroll"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:layout_marginTop="300dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/thumbnails_layout"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="horizontal"
|
||||
tools:showIn="@layout/content_main" />
|
||||
</HorizontalScrollView>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/text_displays"
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginTop="308dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:textAlignment="center"
|
||||
android:textSize="20sp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<HorizontalScrollView
|
||||
android:id="@+id/thumbnails_disabled_scroll"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="300dp"
|
||||
android:background="#80C01010">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/thumbnails_disabled_layout"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="horizontal"
|
||||
tools:showIn="@layout/content_main" />
|
||||
</HorizontalScrollView>
|
||||
|
||||
<HorizontalScrollView
|
||||
android:id="@+id/thumbnails_scroll"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="3">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/thumbnails_layout"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="horizontal"
|
||||
tools:showIn="@layout/content_main" />
|
||||
</HorizontalScrollView>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/text_displays"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:textAlignment="center"
|
||||
android:textSize="20sp" />
|
||||
|
||||
<com.google.android.material.chip.ChipGroup
|
||||
android:id="@+id/chip_group_pages"
|
||||
app:singleSelection="true"
|
||||
app:selectionRequired="true"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1">
|
||||
|
||||
<com.google.android.material.chip.Chip
|
||||
android:id="@+id/chip_pages_1"
|
||||
android:checkable="true"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="1 page" />
|
||||
|
||||
<com.google.android.material.chip.Chip
|
||||
android:id="@+id/chip_pages_1.5"
|
||||
android:checkable="true"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="1.5 pages" />
|
||||
|
||||
<com.google.android.material.chip.Chip
|
||||
android:id="@+id/chip_pages_2"
|
||||
android:checkable="true"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="2 pages" />
|
||||
|
||||
<com.google.android.material.chip.Chip
|
||||
android:id="@+id/chip_pages_2.5"
|
||||
android:checkable="true"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="2.5 pages" />
|
||||
|
||||
<com.google.android.material.chip.Chip
|
||||
android:id="@+id/chip_pages_3"
|
||||
android:checkable="true"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:checked="true"
|
||||
android:text="3 pages" />
|
||||
|
||||
<com.google.android.material.chip.Chip
|
||||
android:id="@+id/chip_pages_3.5"
|
||||
android:checkable="true"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="3.5 pages" />
|
||||
|
||||
<com.google.android.material.chip.Chip
|
||||
android:id="@+id/chip_pages_4"
|
||||
android:checkable="true"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="4 pages" />
|
||||
|
||||
<com.google.android.material.chip.Chip
|
||||
android:id="@+id/chip_pages_5"
|
||||
android:checkable="true"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="5 pages" />
|
||||
|
||||
<com.google.android.material.chip.Chip
|
||||
android:id="@+id/chip_pages_6"
|
||||
android:checkable="true"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="6 pages" />
|
||||
|
||||
<com.google.android.material.chip.Chip
|
||||
android:id="@+id/chip_pages_8"
|
||||
android:checkable="true"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="8 pages" />
|
||||
|
||||
<com.google.android.material.chip.Chip
|
||||
android:id="@+id/chip_pages_10"
|
||||
android:checkable="true"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="10 pages" />
|
||||
</com.google.android.material.chip.ChipGroup>
|
||||
|
||||
<com.google.android.material.chip.ChipGroup
|
||||
android:id="@+id/chip_group_toggles"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1">
|
||||
|
||||
<com.google.android.material.chip.Chip
|
||||
android:id="@+id/chip_auto_crop"
|
||||
android:checkable="true"
|
||||
android:checked="true"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Auto Crop" />
|
||||
|
||||
<com.google.android.material.chip.Chip
|
||||
android:id="@+id/chip_use_pdf_box"
|
||||
android:checkable="true"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Use PdfBox renderer (slower)" />
|
||||
</com.google.android.material.chip.ChipGroup>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -12,6 +12,7 @@ lifecycleLivedataKtx = "2.8.4"
|
|||
lifecycleViewmodelKtx = "2.8.4"
|
||||
navigationFragmentKtx = "2.7.7"
|
||||
navigationUiKtx = "2.7.7"
|
||||
pdfboxAndroid = "2.0.27.0"
|
||||
|
||||
[libraries]
|
||||
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
|
||||
|
@ -25,6 +26,7 @@ androidx-lifecycle-livedata-ktx = { group = "androidx.lifecycle", name = "lifecy
|
|||
androidx-lifecycle-viewmodel-ktx = { group = "androidx.lifecycle", name = "lifecycle-viewmodel-ktx", version.ref = "lifecycleViewmodelKtx" }
|
||||
androidx-navigation-fragment-ktx = { group = "androidx.navigation", name = "navigation-fragment-ktx", version.ref = "navigationFragmentKtx" }
|
||||
androidx-navigation-ui-ktx = { group = "androidx.navigation", name = "navigation-ui-ktx", version.ref = "navigationUiKtx" }
|
||||
pdfbox-android = { module = "com.tom-roush:pdfbox-android", version.ref = "pdfboxAndroid" }
|
||||
|
||||
[plugins]
|
||||
android-application = { id = "com.android.application", version.ref = "agp" }
|
||||
|
|
Loading…
Reference in New Issue