Compare commits
2 Commits
master
...
feature/pd
| Author | SHA1 | Date |
|---|---|---|
|
|
31249a5f6d | |
|
|
0dafe1ff11 |
|
|
@ -0,0 +1 @@
|
||||||
|
/build
|
||||||
|
|
@ -0,0 +1,40 @@
|
||||||
|
plugins {
|
||||||
|
id 'com.android.library'
|
||||||
|
id 'org.jetbrains.kotlin.android'
|
||||||
|
}
|
||||||
|
|
||||||
|
android {
|
||||||
|
compileSdk 31
|
||||||
|
|
||||||
|
defaultConfig {
|
||||||
|
minSdk 23
|
||||||
|
targetSdk 31
|
||||||
|
|
||||||
|
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||||
|
consumerProguardFiles "consumer-rules.pro"
|
||||||
|
}
|
||||||
|
|
||||||
|
buildTypes {
|
||||||
|
release {
|
||||||
|
minifyEnabled false
|
||||||
|
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
compileOptions {
|
||||||
|
sourceCompatibility JavaVersion.VERSION_1_8
|
||||||
|
targetCompatibility JavaVersion.VERSION_1_8
|
||||||
|
}
|
||||||
|
kotlinOptions {
|
||||||
|
jvmTarget = '1.8'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
|
||||||
|
implementation 'androidx.core:core-ktx:1.7.0'
|
||||||
|
implementation 'androidx.appcompat:appcompat:1.4.1'
|
||||||
|
implementation 'com.google.android.material:material:1.5.0'
|
||||||
|
testImplementation 'junit:junit:4.13.2'
|
||||||
|
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
|
||||||
|
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<manifest package="ru.touchin.roboswag.pdf_viewer"> </manifest>
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
package ru.touchin.roboswag.pdf_reader.extensions
|
||||||
|
|
||||||
|
import android.graphics.Bitmap
|
||||||
|
import android.graphics.Canvas
|
||||||
|
import android.graphics.Color
|
||||||
|
import android.graphics.pdf.PdfRenderer
|
||||||
|
|
||||||
|
fun PdfRenderer.Page.renderBitmap(width: Int) = use {
|
||||||
|
val bitmap = createBitmap(width)
|
||||||
|
render(bitmap, null, null, PdfRenderer.Page.RENDER_MODE_FOR_DISPLAY)
|
||||||
|
bitmap
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun PdfRenderer.Page.createBitmap(bitmapWidth: Int): Bitmap {
|
||||||
|
val bitmap = Bitmap.createBitmap(
|
||||||
|
bitmapWidth, (bitmapWidth.toFloat() / width * height).toInt(), Bitmap.Config.ARGB_8888
|
||||||
|
)
|
||||||
|
|
||||||
|
val canvas = Canvas(bitmap)
|
||||||
|
canvas.drawColor(Color.WHITE)
|
||||||
|
canvas.drawBitmap(bitmap, 0f, 0f, null)
|
||||||
|
|
||||||
|
return bitmap
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
package ru.touchin.roboswag.pdf_reader.repository
|
||||||
|
|
||||||
|
import android.graphics.Bitmap
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
|
interface PdfViewRepository {
|
||||||
|
|
||||||
|
suspend fun renderSinglePage(filePath: String, width: Int) : Bitmap
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,58 @@
|
||||||
|
package ru.touchin.roboswag.pdf_reader.ui.base
|
||||||
|
|
||||||
|
import android.graphics.Bitmap
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.view.View
|
||||||
|
import android.widget.Toast
|
||||||
|
import androidx.fragment.app.Fragment
|
||||||
|
import ru.touchin.roboswag.pdf_reader.viewstate.PdfReaderViewState
|
||||||
|
import ru.touchin.roboswag.pdf_reader.BaseViewModel
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
|
abstract class BaseFragment<VM : BaseViewModel> : Fragment() {
|
||||||
|
|
||||||
|
abstract val viewModel: VM
|
||||||
|
|
||||||
|
protected open fun renderData(state: PdfReaderViewState) {
|
||||||
|
when (state) {
|
||||||
|
is PdfReaderViewState.RenderingSuccess -> renderSuccess(state.data)
|
||||||
|
is PdfReaderViewState.Error -> renderError(state.error)
|
||||||
|
is PdfReaderViewState.Loading -> setLoading(true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
|
||||||
|
viewModel.stateLiveData.observe(viewLifecycleOwner) { state ->
|
||||||
|
renderData(state)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
protected open fun renderSuccess(bitmap: Bitmap) {
|
||||||
|
setLoading(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
protected open fun renderError(error: Throwable) {
|
||||||
|
setLoading(false)
|
||||||
|
error.message?.let { showMessage(it) }
|
||||||
|
}
|
||||||
|
|
||||||
|
protected open fun renderMessage(message: String) {
|
||||||
|
setLoading(false)
|
||||||
|
showMessage(message)
|
||||||
|
}
|
||||||
|
|
||||||
|
protected open fun setLoading(isLoading: Boolean) {
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun showMessage(message: String) {
|
||||||
|
Toast.makeText(
|
||||||
|
requireContext(),
|
||||||
|
message,
|
||||||
|
Toast.LENGTH_LONG
|
||||||
|
).show()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,46 @@
|
||||||
|
package ru.touchin.roboswag.pdf_reader.viewmodel
|
||||||
|
|
||||||
|
import androidx.lifecycle.LiveData
|
||||||
|
import androidx.lifecycle.MutableLiveData
|
||||||
|
import androidx.lifecycle.ViewModel
|
||||||
|
import ru.touchin.roboswag.pdf_reader.viewstate.PdfReaderViewState
|
||||||
|
import kotlinx.coroutines.CoroutineExceptionHandler
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.SupervisorJob
|
||||||
|
import kotlinx.coroutines.async
|
||||||
|
import kotlinx.coroutines.cancelChildren
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
|
abstract class BaseViewModel(
|
||||||
|
) : ViewModel() {
|
||||||
|
|
||||||
|
protected val mStateLiveData = MutableLiveData<PdfReaderViewState>()
|
||||||
|
val stateLiveData get() = mStateLiveData as LiveData<PdfReaderViewState>
|
||||||
|
|
||||||
|
private val viewModelCoroutineScope = CoroutineScope(
|
||||||
|
Dispatchers.IO
|
||||||
|
+ SupervisorJob()
|
||||||
|
+ CoroutineExceptionHandler { _, throwable ->
|
||||||
|
handleError(throwable)
|
||||||
|
})
|
||||||
|
|
||||||
|
override fun onCleared() {
|
||||||
|
super.onCleared()
|
||||||
|
cancelJob()
|
||||||
|
}
|
||||||
|
|
||||||
|
protected open fun cancelJob() {
|
||||||
|
viewModelCoroutineScope.coroutineContext.cancelChildren()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun handleError(error: Throwable) {
|
||||||
|
mStateLiveData.postValue(PdfReaderViewState.Error(error))
|
||||||
|
}
|
||||||
|
|
||||||
|
protected fun runAsync(block: suspend () -> Unit) =
|
||||||
|
viewModelCoroutineScope.launch {
|
||||||
|
block()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
package ru.touchin.roboswag.pdf_reader.viewmodel
|
||||||
|
|
||||||
|
import ru.touchin.roboswag.pdf_reader.viewstate.PdfReaderViewState
|
||||||
|
import ru.touchin.roboswag.pdf_reader.repository.PdfViewRepository
|
||||||
|
|
||||||
|
class PdfViewModel(private val repository: PdfViewRepository) : BaseViewModel() {
|
||||||
|
|
||||||
|
fun renderPage(filePath: String, width: Int) {
|
||||||
|
mStateLiveData.postValue(PdfReaderViewState.Loading(true))
|
||||||
|
runAsync {
|
||||||
|
val bitmap = repository.renderSinglePage(filePath, width)
|
||||||
|
mStateLiveData.postValue(PdfReaderViewState.RenderingSuccess(bitmap))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
package ru.touchin.roboswag.pdf_reader.viewstate
|
||||||
|
|
||||||
|
import android.graphics.Bitmap
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
|
sealed class PdfReaderViewState {
|
||||||
|
data class RenderingSuccess(val data: Bitmap) : PdfReaderViewState()
|
||||||
|
data class Error(val error: Throwable) : PdfReaderViewState()
|
||||||
|
data class Loading(val isLoading: Boolean) : PdfReaderViewState()
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue