Refactor control view to the template's GalleryFragment
If this works out, it will eventually be renamed appropriately
This commit is contained in:
parent
f24522d728
commit
9ae2b36a3c
|
@ -13,6 +13,7 @@ import android.view.WindowManager
|
|||
import android.widget.ImageView
|
||||
import androidx.activity.SystemBarStyle
|
||||
import androidx.activity.enableEdgeToEdge
|
||||
import androidx.activity.viewModels
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
import com.google.android.material.navigation.NavigationView
|
||||
import androidx.navigation.findNavController
|
||||
|
@ -26,6 +27,7 @@ import androidx.core.view.WindowCompat
|
|||
import androidx.core.view.WindowInsetsCompat
|
||||
import com.google.android.material.chip.Chip
|
||||
import com.lhw.pdf.databinding.ActivityMainBinding
|
||||
import com.lhw.pdf.ui.gallery.GalleryViewModel
|
||||
import com.tom_roush.pdfbox.android.PDFBoxResourceLoader
|
||||
import java.io.File
|
||||
import java.io.FileOutputStream
|
||||
|
@ -34,6 +36,7 @@ import kotlin.math.max
|
|||
import kotlin.math.min
|
||||
|
||||
class MainActivity : AppCompatActivity() {
|
||||
private val viewModel: GalleryViewModel by viewModels()
|
||||
private lateinit var appBarConfiguration: AppBarConfiguration
|
||||
private lateinit var binding: ActivityMainBinding
|
||||
private lateinit var displayManager: DisplayManager
|
||||
|
@ -46,7 +49,6 @@ class MainActivity : AppCompatActivity() {
|
|||
private val presentations = mutableMapOf<Int, MyPresentation>()
|
||||
private lateinit var pdfDocument: PdfDocument
|
||||
private val showPages = mutableListOf<Boolean>()
|
||||
private val thumbnailImageViews = mutableListOf<ImageView>()
|
||||
private val defaultCachedFileName = "cached.pdf"
|
||||
|
||||
private fun setPagesPerLandscape(pages: Float) {
|
||||
|
@ -118,35 +120,7 @@ class MainActivity : AppCompatActivity() {
|
|||
presentation.show()
|
||||
}
|
||||
|
||||
private fun reLayoutThumbnails() {
|
||||
val container = binding.appBarMain.contentMain.thumbnailsLayout
|
||||
val disabledContainer = binding.appBarMain.contentMain.thumbnailsDisabledLayout
|
||||
container.removeAllViewsInLayout()
|
||||
disabledContainer.removeAllViewsInLayout()
|
||||
showPages.map { if (it) container else disabledContainer }.zip(thumbnailImageViews).forEach { (cont, img) ->
|
||||
cont.addView(img)
|
||||
}
|
||||
updatePresentations(false)
|
||||
}
|
||||
|
||||
private fun populateThumbnails() {
|
||||
showPages.clear()
|
||||
for ((index, bitmap) in pdfDocument.bitmapThumbnails) {
|
||||
val img = ImageView(this)
|
||||
img.setImageBitmap(bitmap)
|
||||
img.setOnClickListener {
|
||||
showPages[index] = !showPages[index]
|
||||
//img.setColorFilter(if (showPages[index]) 0 else 0x7F000000, PorterDuff.Mode.DARKEN)
|
||||
reLayoutThumbnails()
|
||||
}
|
||||
thumbnailImageViews.add(img)
|
||||
showPages.add(true)
|
||||
}
|
||||
reLayoutThumbnails()
|
||||
}
|
||||
|
||||
private fun updateDisplayText() {
|
||||
val displayText = binding.appBarMain.contentMain.textDisplays
|
||||
val text = StringBuilder()
|
||||
|
||||
displayManager.displays.forEach {
|
||||
|
@ -159,7 +133,7 @@ class MainActivity : AppCompatActivity() {
|
|||
text.append("\n")
|
||||
}
|
||||
text.append(presentations)
|
||||
displayText.text = text.toString()
|
||||
viewModel.textDisplays.value = text.toString()
|
||||
}
|
||||
|
||||
override fun onSaveInstanceState(outState: Bundle) {
|
||||
|
@ -180,6 +154,11 @@ class MainActivity : AppCompatActivity() {
|
|||
//val windowInsetsController = WindowCompat.getInsetsController(window, window.decorView)
|
||||
//windowInsetsController.hide(WindowInsetsCompat.Type.systemBars()) //Doesn't seem to actually fill the vacant space by default
|
||||
|
||||
savedInstanceState?.getFloat("thumbnailScrollProgress")?.let { viewModel.thumbnailScrollProgress.value = it }
|
||||
savedInstanceState?.getFloat("pagesPerLandscape")?.let { pagesPerLandscape = it }
|
||||
renderAutoCrop = savedInstanceState?.getBoolean("renderAutoCrop") ?: true
|
||||
val lastFileName = savedInstanceState?.getString("fileName") // TODO: proper filenames
|
||||
|
||||
PDFBoxResourceLoader.init(this)
|
||||
|
||||
binding = ActivityMainBinding.inflate(layoutInflater)
|
||||
|
@ -190,7 +169,6 @@ class MainActivity : AppCompatActivity() {
|
|||
setSupportActionBar(binding.appBarMain.toolbar)
|
||||
|
||||
// Load previous pdf, or included test pdf first
|
||||
val lastFileName = savedInstanceState?.getString("fileName") // TODO: proper filenames
|
||||
var file = File(cacheDir, defaultCachedFileName)
|
||||
if (!file.exists()) {
|
||||
file = inputStreamToCache(defaultCachedFileName, resources.openRawResource(R.raw.testpdf))
|
||||
|
@ -199,45 +177,40 @@ class MainActivity : AppCompatActivity() {
|
|||
// Then overwrite it with any pdf sent via intent
|
||||
handleIntent(intent)
|
||||
|
||||
renderAutoCrop = savedInstanceState?.getBoolean("renderAutoCrop") ?: true
|
||||
|
||||
pdfDocument.renderThumbnails(thumbnailWidth, thumbnailHeight)
|
||||
displayManager.getDisplays(DisplayManager.DISPLAY_CATEGORY_PRESENTATION).forEach(::makePresentationView)
|
||||
populateThumbnails() // Populates showPages
|
||||
|
||||
val bitmaps = pdfDocument.bitmapThumbnails.toSortedMap().values.toList()
|
||||
showPages.clear()
|
||||
bitmaps.forEach { _ -> showPages.add(true) }
|
||||
savedInstanceState?.getBooleanArray("showPages")?.forEachIndexed { i, show ->
|
||||
showPages[i] = show
|
||||
}
|
||||
reLayoutThumbnails()
|
||||
viewModel.showPages.value = showPages.toList()
|
||||
viewModel.pageThumbnails.value = bitmaps
|
||||
|
||||
val container = binding.appBarMain.contentMain.thumbnailsLayout
|
||||
val containerScroll = binding.appBarMain.contentMain.thumbnailsScroll
|
||||
containerScroll.viewTreeObserver.addOnScrollChangedListener {
|
||||
thumbnailScrollProgress = containerScroll.scrollX.toFloat() / (container.width - containerScroll.width)
|
||||
presentations.values.forEach {it.setScrollProgress(thumbnailScrollProgress)}
|
||||
}
|
||||
savedInstanceState?.getFloat("thumbnailScrollProgress")?.let { thumbnailScrollProgress = it }
|
||||
containerScroll.scrollTo((thumbnailScrollProgress * (container.width - containerScroll.width)).toInt(), 0)
|
||||
|
||||
savedInstanceState?.getFloat("pagesPerLandscape")?.let { pagesPerLandscape = it }
|
||||
val pageZoomLevels = arrayOf(1F, 1.5F, 2F, 2.5F, 3F, 3.5F, 4F, 5F, 6F, 8F, 10F)
|
||||
val chipGroupPages = binding.appBarMain.contentMain.chipGroupPages
|
||||
pageZoomLevels.forEach { pages ->
|
||||
val chip = Chip(this)
|
||||
chip.text = "$pages pages"
|
||||
chip.isCheckable = true
|
||||
chip.isChecked = (pages == pagesPerLandscape)
|
||||
chip.setOnCheckedChangeListener { _, checked -> if (checked) setPagesPerLandscape(pages) }
|
||||
chipGroupPages.addView(chip)
|
||||
viewModel.pagesPerLandscape.observe(this) {
|
||||
setPagesPerLandscape(it)
|
||||
}
|
||||
binding.appBarMain.contentMain.chipAutoCrop.setOnCheckedChangeListener { _, checked ->
|
||||
renderAutoCrop = checked
|
||||
viewModel.renderAutoCrop.observe(this) {
|
||||
renderAutoCrop = it
|
||||
updatePresentations()
|
||||
}
|
||||
binding.appBarMain.contentMain.chipUsePdfBox.setOnCheckedChangeListener { _, checked ->
|
||||
usePdfBox = checked
|
||||
viewModel.usePdfBox.observe(this) {
|
||||
usePdfBox = it
|
||||
pdfDocument.usePdfBox = usePdfBox
|
||||
updatePresentations()
|
||||
}
|
||||
viewModel.showPages.observe(this) {
|
||||
it.forEachIndexed() {i, shown -> showPages[i] = shown}
|
||||
updatePresentations(false)
|
||||
}
|
||||
viewModel.thumbnailScrollProgress.observe(this) { thumbnailScrollProgress ->
|
||||
presentations.values.forEach {it.setScrollProgress(thumbnailScrollProgress)}
|
||||
}
|
||||
|
||||
val drawerLayout: DrawerLayout = binding.drawerLayout
|
||||
val navView: NavigationView = binding.navView
|
||||
val navController = findNavController(R.id.nav_host_fragment_content_main)
|
||||
|
|
|
@ -1,36 +1,70 @@
|
|||
package com.lhw.pdf.ui.gallery
|
||||
|
||||
import android.graphics.Bitmap
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.ImageView
|
||||
import android.widget.TextView
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.activityViewModels
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import com.google.android.material.chip.Chip
|
||||
import com.lhw.pdf.databinding.FragmentGalleryBinding
|
||||
|
||||
class GalleryFragment : Fragment() {
|
||||
|
||||
private val galleryViewModel: GalleryViewModel by activityViewModels()
|
||||
private var _binding: FragmentGalleryBinding? = null
|
||||
|
||||
// This property is only valid between onCreateView and
|
||||
// onDestroyView.
|
||||
private val binding get() = _binding!!
|
||||
|
||||
private val pageZoomLevels = arrayOf(1F, 1.5F, 2F, 2.5F, 3F, 3.5F, 4F, 5F, 6F, 8F, 10F)
|
||||
private val pageZoomLevelChips = mutableMapOf<Float, Chip>()
|
||||
private val thumbnailImageViews = mutableListOf<ImageView>()
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View {
|
||||
val galleryViewModel =
|
||||
ViewModelProvider(this)[GalleryViewModel::class.java]
|
||||
// val galleryViewModel = ViewModelProvider(this)[GalleryViewModel::class.java]
|
||||
|
||||
_binding = FragmentGalleryBinding.inflate(inflater, container, false)
|
||||
val root: View = binding.root
|
||||
|
||||
val textView: TextView = binding.textGallery
|
||||
galleryViewModel.text.observe(viewLifecycleOwner) {
|
||||
textView.text = it
|
||||
val chipGroupPages = binding.chipGroupPages
|
||||
pageZoomLevels.forEach { pages ->
|
||||
val chip = Chip(context)
|
||||
chip.text = "$pages pages"
|
||||
chip.isCheckable = true
|
||||
chip.setOnCheckedChangeListener { _, checked -> if (checked) galleryViewModel.pagesPerLandscape.value = pages }
|
||||
chipGroupPages.addView(chip)
|
||||
pageZoomLevelChips[pages] = chip
|
||||
}
|
||||
pageZoomLevelChips[galleryViewModel.pagesPerLandscape.value]?.isChecked = true
|
||||
binding.chipAutoCrop.isChecked = galleryViewModel.renderAutoCrop.value!!
|
||||
binding.chipUsePdfBox.isChecked = galleryViewModel.usePdfBox.value!!
|
||||
|
||||
galleryViewModel.textDisplays.observe(viewLifecycleOwner) { binding.textDisplays.text = it }
|
||||
galleryViewModel.usePdfBox.observe(viewLifecycleOwner) { binding.chipUsePdfBox.isChecked = it }
|
||||
galleryViewModel.renderAutoCrop.observe(viewLifecycleOwner) { binding.chipAutoCrop.isChecked = it }
|
||||
galleryViewModel.pagesPerLandscape.observe(viewLifecycleOwner) {
|
||||
pageZoomLevelChips[it]?.isChecked = true
|
||||
}
|
||||
|
||||
binding.chipAutoCrop.setOnCheckedChangeListener { _, checked -> galleryViewModel.renderAutoCrop.value = checked }
|
||||
binding.chipUsePdfBox.setOnCheckedChangeListener { _, checked -> galleryViewModel.usePdfBox.value = checked }
|
||||
|
||||
galleryViewModel.pageThumbnails.observe(viewLifecycleOwner, ::populateThumbnails)
|
||||
|
||||
val container = binding.thumbnailsLayout
|
||||
val containerScroll = binding.thumbnailsScroll
|
||||
containerScroll.scrollTo(((galleryViewModel.thumbnailScrollProgress.value ?: 0F) * (container.width - containerScroll.width)).toInt(), 0)
|
||||
containerScroll.viewTreeObserver.addOnScrollChangedListener {
|
||||
galleryViewModel.thumbnailScrollProgress.value = containerScroll.scrollX.toFloat() / (container.width - containerScroll.width)
|
||||
}
|
||||
return root
|
||||
}
|
||||
|
@ -39,4 +73,31 @@ class GalleryFragment : Fragment() {
|
|||
super.onDestroyView()
|
||||
_binding = null
|
||||
}
|
||||
|
||||
private fun reLayoutThumbnails() {
|
||||
val container = binding.thumbnailsLayout
|
||||
val disabledContainer = binding.thumbnailsDisabledLayout
|
||||
container.removeAllViewsInLayout()
|
||||
disabledContainer.removeAllViewsInLayout()
|
||||
galleryViewModel.showPages.value
|
||||
?.map { if (it) container else disabledContainer }
|
||||
?.zip(thumbnailImageViews)?.forEach { (cont, img) ->
|
||||
cont.addView(img)
|
||||
}
|
||||
}
|
||||
|
||||
private fun populateThumbnails(bitmaps: List<Bitmap>) {
|
||||
bitmaps.forEachIndexed() { index, bitmap ->
|
||||
val img = ImageView(context)
|
||||
img.setImageBitmap(bitmap)
|
||||
img.setOnClickListener {
|
||||
val showPages = galleryViewModel.showPages.value!!.toMutableList()
|
||||
showPages[index] = !showPages[index]
|
||||
galleryViewModel.showPages.value = showPages.toList()
|
||||
reLayoutThumbnails()
|
||||
}
|
||||
thumbnailImageViews.add(img)
|
||||
}
|
||||
reLayoutThumbnails()
|
||||
}
|
||||
}
|
|
@ -1,13 +1,16 @@
|
|||
package com.lhw.pdf.ui.gallery
|
||||
|
||||
import android.graphics.Bitmap
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.ViewModel
|
||||
|
||||
class GalleryViewModel : ViewModel() {
|
||||
|
||||
private val _text = MutableLiveData<String>().apply {
|
||||
value = "This is gallery Fragment"
|
||||
}
|
||||
val text: LiveData<String> = _text
|
||||
val pageThumbnails = MutableLiveData<List<Bitmap>>().apply { value = listOf() }
|
||||
val showPages = MutableLiveData<List<Boolean>>().apply { value = listOf() }
|
||||
val thumbnailScrollProgress = MutableLiveData<Float>().apply { value = 0F }
|
||||
val textDisplays = MutableLiveData<String>().apply { value = "" }
|
||||
val pagesPerLandscape = MutableLiveData<Float>().apply { value = 3F }
|
||||
val renderAutoCrop = MutableLiveData<Boolean>().apply { value = true }
|
||||
val usePdfBox = MutableLiveData<Boolean>().apply { value = false }
|
||||
}
|
|
@ -18,79 +18,4 @@
|
|||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:navGraph="@navigation/mobile_navigation" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_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.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>
|
|
@ -6,17 +6,78 @@
|
|||
android:layout_height="match_parent"
|
||||
tools:context=".ui.gallery.GalleryFragment">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_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_gallery"
|
||||
android:id="@+id/text_displays"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginTop="8dp"
|
||||
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: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.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>
|
Loading…
Reference in New Issue