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)
|
testImplementation(libs.junit)
|
||||||
androidTestImplementation(libs.androidx.junit)
|
androidTestImplementation(libs.androidx.junit)
|
||||||
androidTestImplementation(libs.androidx.espresso.core)
|
androidTestImplementation(libs.androidx.espresso.core)
|
||||||
|
|
||||||
|
implementation(libs.pdfbox.android)
|
||||||
}
|
}
|
|
@ -11,6 +11,8 @@ import android.view.Display
|
||||||
import android.view.Menu
|
import android.view.Menu
|
||||||
import android.view.WindowManager
|
import android.view.WindowManager
|
||||||
import android.widget.ImageView
|
import android.widget.ImageView
|
||||||
|
import androidx.activity.SystemBarStyle
|
||||||
|
import androidx.activity.enableEdgeToEdge
|
||||||
import com.google.android.material.snackbar.Snackbar
|
import com.google.android.material.snackbar.Snackbar
|
||||||
import com.google.android.material.navigation.NavigationView
|
import com.google.android.material.navigation.NavigationView
|
||||||
import androidx.navigation.findNavController
|
import androidx.navigation.findNavController
|
||||||
|
@ -23,6 +25,7 @@ import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.core.view.WindowCompat
|
import androidx.core.view.WindowCompat
|
||||||
import androidx.core.view.WindowInsetsCompat
|
import androidx.core.view.WindowInsetsCompat
|
||||||
import com.lhw.pdf.databinding.ActivityMainBinding
|
import com.lhw.pdf.databinding.ActivityMainBinding
|
||||||
|
import com.tom_roush.pdfbox.android.PDFBoxResourceLoader
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.FileOutputStream
|
import java.io.FileOutputStream
|
||||||
import java.io.InputStream
|
import java.io.InputStream
|
||||||
|
@ -37,6 +40,11 @@ class MainActivity : AppCompatActivity() {
|
||||||
private val thumbnailHeight = 700
|
private val thumbnailHeight = 700
|
||||||
private var renderAutoCrop = true
|
private var renderAutoCrop = true
|
||||||
private var pagesPerLandscape = 3F
|
private var pagesPerLandscape = 3F
|
||||||
|
private set(pages) {
|
||||||
|
field = pages
|
||||||
|
updatePresentations()
|
||||||
|
}
|
||||||
|
private var usePdfBox = false
|
||||||
private val presentations = mutableMapOf<Int, MyPresentation>()
|
private val presentations = mutableMapOf<Int, MyPresentation>()
|
||||||
private lateinit var pdfDocument: PdfDocument
|
private lateinit var pdfDocument: PdfDocument
|
||||||
private val showPages = mutableListOf<Boolean>()
|
private val showPages = mutableListOf<Boolean>()
|
||||||
|
@ -151,12 +159,15 @@ class MainActivity : AppCompatActivity() {
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
//enableEdgeToEdge()
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
|
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
|
||||||
displayManager = getSystemService(Context.DISPLAY_SERVICE) as DisplayManager
|
displayManager = getSystemService(Context.DISPLAY_SERVICE) as DisplayManager
|
||||||
//val windowInsetsController = WindowCompat.getInsetsController(window, window.decorView)
|
//val windowInsetsController = WindowCompat.getInsetsController(window, window.decorView)
|
||||||
//windowInsetsController.hide(WindowInsetsCompat.Type.systemBars()) //Doesn't seem to actually fill the vacant space by default
|
//windowInsetsController.hide(WindowInsetsCompat.Type.systemBars()) //Doesn't seem to actually fill the vacant space by default
|
||||||
|
|
||||||
|
PDFBoxResourceLoader.init(this)
|
||||||
|
|
||||||
binding = ActivityMainBinding.inflate(layoutInflater)
|
binding = ActivityMainBinding.inflate(layoutInflater)
|
||||||
setContentView(binding.root)
|
setContentView(binding.root)
|
||||||
|
|
||||||
|
@ -169,7 +180,7 @@ class MainActivity : AppCompatActivity() {
|
||||||
if (!file.exists()) {
|
if (!file.exists()) {
|
||||||
file = inputStreamToCache(defaultCachedFileName, resources.openRawResource(R.raw.testpdf))
|
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
|
// Then overwrite it with any pdf sent via intent
|
||||||
handleIntent(intent)
|
handleIntent(intent)
|
||||||
|
|
||||||
|
@ -184,26 +195,24 @@ class MainActivity : AppCompatActivity() {
|
||||||
presentations.values.forEach {it.setScrollProgress(progress)}
|
presentations.values.forEach {it.setScrollProgress(progress)}
|
||||||
}
|
}
|
||||||
|
|
||||||
binding.appBarMain.crop.setOnClickListener { view ->
|
binding.appBarMain.contentMain.chipPages1.setOnCheckedChangeListener { _, checked -> if (checked) pagesPerLandscape = 1F }
|
||||||
renderAutoCrop = !renderAutoCrop
|
binding.appBarMain.contentMain.chipPages15.setOnCheckedChangeListener { _, checked -> if (checked) pagesPerLandscape = 1.5F }
|
||||||
val s = if (renderAutoCrop) "On" else "Off"
|
binding.appBarMain.contentMain.chipPages2.setOnCheckedChangeListener { _, checked -> if (checked) pagesPerLandscape = 2F }
|
||||||
Snackbar.make(view, "Toggling Auto Crop $s", Snackbar.LENGTH_LONG)
|
binding.appBarMain.contentMain.chipPages25.setOnCheckedChangeListener { _, checked -> if (checked) pagesPerLandscape = 2.5F }
|
||||||
.setAction("Action", null)
|
binding.appBarMain.contentMain.chipPages3.setOnCheckedChangeListener { _, checked -> if (checked) pagesPerLandscape = 3F }
|
||||||
.setAnchorView(R.id.crop).show()
|
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()
|
updatePresentations()
|
||||||
}
|
}
|
||||||
binding.appBarMain.zoomIn.setOnClickListener { view ->
|
binding.appBarMain.contentMain.chipUsePdfBox.setOnCheckedChangeListener { _, checked ->
|
||||||
pagesPerLandscape = max(pagesPerLandscape - 0.5F, 1F)
|
usePdfBox = checked
|
||||||
Snackbar.make(view, "Aiming for $pagesPerLandscape pages at a time", Snackbar.LENGTH_LONG)
|
pdfDocument.usePdfBox = usePdfBox
|
||||||
.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()
|
|
||||||
updatePresentations()
|
updatePresentations()
|
||||||
}
|
}
|
||||||
val drawerLayout: DrawerLayout = binding.drawerLayout
|
val drawerLayout: DrawerLayout = binding.drawerLayout
|
||||||
|
|
|
@ -7,25 +7,40 @@ import android.graphics.Rect
|
||||||
import android.graphics.RectF
|
import android.graphics.RectF
|
||||||
import android.graphics.pdf.PdfRenderer
|
import android.graphics.pdf.PdfRenderer
|
||||||
import android.os.ParcelFileDescriptor
|
import android.os.ParcelFileDescriptor
|
||||||
|
import com.tom_roush.pdfbox.pdmodel.PDDocument
|
||||||
|
import com.tom_roush.pdfbox.rendering.PDFRenderer
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import kotlin.math.max
|
import kotlin.math.max
|
||||||
import kotlin.math.min
|
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 pfd = ParcelFileDescriptor.open(fileCached, ParcelFileDescriptor.MODE_READ_ONLY)
|
||||||
private val renderer = PdfRenderer(pfd)
|
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 pagePtWidths = mutableListOf<Int>()
|
||||||
private val pagePtHeights = 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>()
|
private val pageAutoCropRects = mutableListOf<RectF>()
|
||||||
// Due to the way thumbnails render, the bottom right is more likely to be cut off
|
// Due to the way thumbnails render, the bottom right is more likely to be cut off
|
||||||
private val autoCropSafetyMarginUpper = 2
|
private val autoCropSafetyMarginUpper = 2
|
||||||
private val autoCropSafetyMarginLower = 16
|
private val autoCropSafetyMarginLower = 16
|
||||||
|
|
||||||
|
private val numPages get() = if (usePdfBox) pdfDocument.numberOfPages else renderer.pageCount
|
||||||
|
|
||||||
init {
|
init {
|
||||||
val numPages = renderer.pageCount
|
|
||||||
for (i in 0..<numPages) {
|
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)
|
val page = renderer.openPage(i)
|
||||||
pagePtWidths.add(page.width)
|
pagePtWidths.add(page.width)
|
||||||
pagePtHeights.add(page.height)
|
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 val rectFIdentity = RectF(0F, 0F, 1F, 1F)
|
||||||
private fun renderPage(index: Int, maxWidth: Int, maxHeight: Int, crop: Boolean = false): Bitmap {
|
private fun renderPage(index: Int, maxWidth: Int, maxHeight: Int, crop: Boolean = false): Bitmap {
|
||||||
val cropRect = if (!crop || pageAutoCropRects.size <= index) rectFIdentity else pageAutoCropRects[index]
|
val cropRect = if (!crop || pageAutoCropRects.size <= index) rectFIdentity else pageAutoCropRects[index]
|
||||||
|
@ -42,9 +58,14 @@ class PdfDocument(private val fileCached: File, private val autoCrop: Boolean =
|
||||||
val heightFromMaxWidth = (ptHeight * maxWidth/ptWidth).toInt()
|
val heightFromMaxWidth = (ptHeight * maxWidth/ptWidth).toInt()
|
||||||
val (width, height) = if (widthFromMaxHeight > maxWidth) Pair(maxWidth, heightFromMaxWidth) else Pair(widthFromMaxHeight, maxHeight)
|
val (width, height) = if (widthFromMaxHeight > maxWidth) Pair(maxWidth, heightFromMaxWidth) else Pair(widthFromMaxHeight, maxHeight)
|
||||||
|
|
||||||
|
val bitmap: Bitmap
|
||||||
|
if (usePdfBox) {
|
||||||
|
val scale = width / ptWidth
|
||||||
|
bitmap = boxRenderer.renderImage(index, scale)
|
||||||
|
} else {
|
||||||
val page = renderer.openPage(index)
|
val page = renderer.openPage(index)
|
||||||
println("Creating page $index bitmap with width $width and height $height from cropRect $cropRect")
|
println("Creating page $index bitmap with width $width and height $height from cropRect $cropRect")
|
||||||
val bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
|
bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
|
||||||
val ptToPixel = height / ptHeight
|
val ptToPixel = height / ptHeight
|
||||||
val transform = Matrix()
|
val transform = Matrix()
|
||||||
val transposePtX = -cropRect.left * ptWidth
|
val transposePtX = -cropRect.left * ptWidth
|
||||||
|
@ -52,12 +73,12 @@ class PdfDocument(private val fileCached: File, private val autoCrop: Boolean =
|
||||||
transform.setValues(floatArrayOf(ptToPixel, 0F, transposePtX * ptToPixel, 0F, ptToPixel, transposePtY * ptToPixel, 0F, 0F, 1F))
|
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.render(bitmap, null, transform, PdfRenderer.Page.RENDER_MODE_FOR_DISPLAY)
|
||||||
page.close()
|
page.close()
|
||||||
|
}
|
||||||
return bitmap
|
return bitmap
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun renderPagesToMap(map: MutableMap<Int, Bitmap>, width: Int, height: Int, crop: Boolean = false, overwrite: Boolean = true) {
|
private fun renderPagesToMap(map: MutableMap<Int, Bitmap>, width: Int, height: Int, crop: Boolean = false, overwrite: Boolean = true) {
|
||||||
if (overwrite) map.clear()
|
if (overwrite) map.clear()
|
||||||
val numPages = renderer.pageCount
|
|
||||||
for (i in 0..<numPages) {
|
for (i in 0..<numPages) {
|
||||||
map.computeIfAbsent(i) { renderPage(i, width, height, crop) }
|
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")
|
println("Thumbnails rendered")
|
||||||
if (autoCrop) {
|
if (autoCrop) {
|
||||||
println("Auto cropping from thumbnails")
|
println("Auto cropping from thumbnails")
|
||||||
val numPages = renderer.pageCount
|
|
||||||
pageAutoCropRects.clear()
|
pageAutoCropRects.clear()
|
||||||
for (i in 0..<numPages) {
|
for (i in 0..<numPages) {
|
||||||
println("Auto cropping page $i from thumbnail")
|
println("Auto cropping page $i from thumbnail")
|
||||||
|
|
|
@ -22,39 +22,4 @@
|
||||||
|
|
||||||
<include android:id="@+id/content_main" layout="@layout/content_main" />
|
<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>
|
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
|
@ -18,16 +18,16 @@
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
app:navGraph="@navigation/mobile_navigation" />
|
app:navGraph="@navigation/mobile_navigation" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
<HorizontalScrollView
|
<HorizontalScrollView
|
||||||
android:id="@+id/thumbnails_disabled_scroll"
|
android:id="@+id/thumbnails_disabled_scroll"
|
||||||
android:layout_width="0dp"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="300dp"
|
android:layout_height="300dp"
|
||||||
android:background="#80C01010"
|
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
|
<LinearLayout
|
||||||
android:id="@+id/thumbnails_disabled_layout"
|
android:id="@+id/thumbnails_disabled_layout"
|
||||||
|
@ -39,13 +39,9 @@
|
||||||
|
|
||||||
<HorizontalScrollView
|
<HorizontalScrollView
|
||||||
android:id="@+id/thumbnails_scroll"
|
android:id="@+id/thumbnails_scroll"
|
||||||
android:layout_width="0dp"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="0dp"
|
android:layout_height="0dp"
|
||||||
android:layout_marginTop="300dp"
|
android:layout_weight="3">
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toTopOf="parent">
|
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/thumbnails_layout"
|
android:id="@+id/thumbnails_layout"
|
||||||
|
@ -60,12 +56,119 @@
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="8dp"
|
android:layout_marginStart="8dp"
|
||||||
android:layout_marginTop="308dp"
|
|
||||||
android:layout_marginEnd="8dp"
|
android:layout_marginEnd="8dp"
|
||||||
android:textAlignment="center"
|
android:textAlignment="center"
|
||||||
android:textSize="20sp"
|
android:textSize="20sp" />
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
<com.google.android.material.chip.ChipGroup
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
android:id="@+id/chip_group_pages"
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
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>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -12,6 +12,7 @@ lifecycleLivedataKtx = "2.8.4"
|
||||||
lifecycleViewmodelKtx = "2.8.4"
|
lifecycleViewmodelKtx = "2.8.4"
|
||||||
navigationFragmentKtx = "2.7.7"
|
navigationFragmentKtx = "2.7.7"
|
||||||
navigationUiKtx = "2.7.7"
|
navigationUiKtx = "2.7.7"
|
||||||
|
pdfboxAndroid = "2.0.27.0"
|
||||||
|
|
||||||
[libraries]
|
[libraries]
|
||||||
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
|
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-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-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" }
|
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]
|
[plugins]
|
||||||
android-application = { id = "com.android.application", version.ref = "agp" }
|
android-application = { id = "com.android.application", version.ref = "agp" }
|
||||||
|
|
Loading…
Reference in New Issue