diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index d865cae..fc41a69 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -50,7 +50,7 @@
-
+
diff --git a/app/src/main/java/sushi/hardcore/droidfs/adapters/ExplorerElementAdapter.kt b/app/src/main/java/sushi/hardcore/droidfs/adapters/ExplorerElementAdapter.kt
index aa07fcc..fd75151 100644
--- a/app/src/main/java/sushi/hardcore/droidfs/adapters/ExplorerElementAdapter.kt
+++ b/app/src/main/java/sushi/hardcore/droidfs/adapters/ExplorerElementAdapter.kt
@@ -125,7 +125,7 @@ class ExplorerElementAdapter(
volume.loadWholeFile(fullPath, maxSize = adapter.thumbnailMaxSize).first?.let {
if (isActive) {
withContext(Dispatchers.Main) {
- if (isActive && !adapter.activity.isFinishing) {
+ if (isActive && !adapter.activity.isFinishing && !adapter.activity.isDestroyed) {
target = Glide.with(adapter.activity).load(it).skipMemoryCache(true).into(object : DrawableImageViewTarget(icon) {
override fun onResourceReady(
resource: Drawable,
diff --git a/app/src/main/java/sushi/hardcore/droidfs/file_viewers/FileViewerActivity.kt b/app/src/main/java/sushi/hardcore/droidfs/file_viewers/FileViewerActivity.kt
index 1265264..3663fc5 100644
--- a/app/src/main/java/sushi/hardcore/droidfs/file_viewers/FileViewerActivity.kt
+++ b/app/src/main/java/sushi/hardcore/droidfs/file_viewers/FileViewerActivity.kt
@@ -1,10 +1,15 @@
package sushi.hardcore.droidfs.file_viewers
+import android.os.Build
import android.os.Bundle
import android.view.View
-import androidx.core.content.ContextCompat
+import android.view.WindowInsets
+import android.widget.FrameLayout
+import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import androidx.core.view.WindowInsetsControllerCompat
+import androidx.core.view.updateLayoutParams
+import androidx.core.view.updateMargins
import androidx.lifecycle.lifecycleScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.isActive
@@ -29,10 +34,7 @@ abstract class FileViewerActivity: BaseActivity() {
private var wasMapped = false
protected val mappedPlaylist = mutableListOf()
protected var currentPlaylistIndex = -1
- protected open var fullscreenMode = true
- private val legacyMod by lazy {
- sharedPrefs.getBoolean("legacyMod", false)
- }
+ private val isLegacyFullscreen = Build.VERSION.SDK_INT <= Build.VERSION_CODES.R
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@@ -44,38 +46,61 @@ abstract class FileViewerActivity: BaseActivity() {
windowInsetsController.addOnControllableInsetsChangedListener { _, typeMask ->
windowTypeMask = typeMask
}
- if (fullscreenMode) {
- fixNavBarColor()
- hideSystemUi()
- }
+ windowInsetsController.systemBarsBehavior = WindowInsetsControllerCompat.BEHAVIOR_SHOW_BARS_BY_SWIPE
viewFile()
}
- private fun fixNavBarColor() {
- window.navigationBarColor = ContextCompat.getColor(this, R.color.fullScreenBackgroundColor)
+ open fun showPartialSystemUi() {
+ if (isLegacyFullscreen) {
+ @Suppress("Deprecation")
+ window.decorView.systemUiVisibility =
+ View.SYSTEM_UI_FLAG_FULLSCREEN or
+ View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
+ } else {
+ windowInsetsController.hide(WindowInsetsCompat.Type.statusBars())
+ windowInsetsController.show(WindowInsetsCompat.Type.navigationBars())
+ }
}
- private fun hideSystemUi() {
- if (legacyMod) {
+ open fun hideSystemUi() {
+ if (isLegacyFullscreen) {
@Suppress("Deprecation")
window.decorView.systemUiVisibility =
View.SYSTEM_UI_FLAG_LOW_PROFILE or
- View.SYSTEM_UI_FLAG_FULLSCREEN
+ View.SYSTEM_UI_FLAG_FULLSCREEN or
+ View.SYSTEM_UI_FLAG_HIDE_NAVIGATION or
+ View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
} else {
- windowInsetsController.hide(WindowInsetsCompat.Type.statusBars())
+ windowInsetsController.hide(WindowInsetsCompat.Type.systemBars())
+
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
+ window.setDecorFitsSystemWindows(false)
+ }
+ }
+ }
+
+ protected fun applyNavigationBarMargin(root: View) {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
+ ViewCompat.setOnApplyWindowInsetsListener(root) { _, insets ->
+ root.updateLayoutParams {
+ val newInsets = insets.getInsetsIgnoringVisibility(WindowInsets.Type.navigationBars())
+ this.updateMargins(
+ left = newInsets.left,
+ top = newInsets.top,
+ right = newInsets.right,
+ bottom = newInsets.bottom
+ )
+ }
+ insets
+ }
+ } else {
+ root.fitsSystemWindows = true
}
}
abstract fun getFileType(): String
abstract fun viewFile()
- override fun onUserInteraction() {
- super.onUserInteraction()
- if (fullscreenMode && windowTypeMask and WindowInsetsCompat.Type.statusBars() == 0) {
- hideSystemUi()
- }
- }
-
protected fun loadWholeFile(path: String, fileSize: Long? = null, callback: (ByteArray) -> Unit) {
lifecycleScope.launch(Dispatchers.IO) {
val result = encryptedVolume.loadWholeFile(path, size = fileSize)
diff --git a/app/src/main/java/sushi/hardcore/droidfs/file_viewers/ImageViewer.kt b/app/src/main/java/sushi/hardcore/droidfs/file_viewers/ImageViewer.kt
index 8e29916..c0ba353 100644
--- a/app/src/main/java/sushi/hardcore/droidfs/file_viewers/ImageViewer.kt
+++ b/app/src/main/java/sushi/hardcore/droidfs/file_viewers/ImageViewer.kt
@@ -10,6 +10,8 @@ import android.view.View
import android.view.WindowManager
import android.widget.Toast
import androidx.activity.addCallback
+import androidx.activity.viewModels
+import androidx.lifecycle.ViewModel
import com.bumptech.glide.Glide
import com.bumptech.glide.RequestBuilder
import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool
@@ -31,18 +33,23 @@ class ImageViewer: FileViewerActivity() {
private const val MIN_SWIPE_DISTANCE = 150
}
+ class ImageViewModel : ViewModel() {
+ var imageBytes: ByteArray? = null
+ var rotationAngle: Float = 0f
+ }
+
private lateinit var fileName: String
private lateinit var handler: Handler
+ private val imageViewModel: ImageViewModel by viewModels()
private var requestBuilder: RequestBuilder? = null
private var x1 = 0F
private var x2 = 0F
private var slideshowActive = false
- private var originalOrientation: Float = 0f
- private var rotationAngle: Float = 0F
private var orientationTransformation: OrientationTransformation? = null
private val hideUI = Runnable {
binding.actionButtons.visibility = View.GONE
binding.topBar.visibility = View.GONE
+ hideSystemUi()
}
private val slideshowNext = Runnable {
if (slideshowActive){
@@ -60,6 +67,8 @@ class ImageViewer: FileViewerActivity() {
binding = ActivityImageViewerBinding.inflate(layoutInflater)
setContentView(binding.root)
supportActionBar?.hide()
+ showPartialSystemUi()
+ applyNavigationBarMargin(binding.root)
handler = Handler(mainLooper)
binding.imageViewer.setOnInteractionListener(object : ZoomableImageView.OnInteractionListener {
override fun onSingleTap(event: MotionEvent?) {
@@ -67,6 +76,7 @@ class ImageViewer: FileViewerActivity() {
if (binding.actionButtons.visibility == View.GONE) {
binding.actionButtons.visibility = View.VISIBLE
binding.topBar.visibility = View.VISIBLE
+ showPartialSystemUi()
handler.postDelayed(hideUI, hideDelay)
} else {
hideUI.run()
@@ -102,7 +112,7 @@ class ImageViewer: FileViewerActivity() {
if (mappedPlaylist.size == 0) { //deleted all images of the playlist
goBackToExplorer()
} else {
- loadImage()
+ loadImage(true)
}
} else {
CustomAlertDialogBuilder(this, theme)
@@ -140,14 +150,8 @@ class ImageViewer: FileViewerActivity() {
swipeImage(-1F)
}
}
- binding.imageRotateRight.setOnClickListener {
- rotationAngle += 90
- rotateImage()
- }
- binding.imageRotateLeft.setOnClickListener {
- rotationAngle -= 90
- rotateImage()
- }
+ binding.imageRotateRight.setOnClickListener { onClickRotate(90f) }
+ binding.imageRotateLeft.setOnClickListener { onClickRotate(-90f) }
onBackPressedDispatcher.addCallback(this) {
if (slideshowActive) {
stopSlideshow()
@@ -158,19 +162,27 @@ class ImageViewer: FileViewerActivity() {
}
}
}
- loadImage()
+ loadImage(false)
handler.postDelayed(hideUI, hideDelay)
}
- private fun loadImage(){
+ private fun loadImage(newImage: Boolean) {
fileName = File(filePath).name
binding.textFilename.text = fileName
- requestBuilder = null
- loadWholeFile(filePath) {
- originalOrientation = 0f
- requestBuilder = Glide.with(this).load(it)
- requestBuilder?.into(binding.imageViewer)
- rotationAngle = originalOrientation
+ if (newImage || imageViewModel.imageBytes == null) {
+ loadWholeFile(filePath) {
+ imageViewModel.imageBytes = it
+ requestBuilder = Glide.with(this).load(it)
+ requestBuilder?.into(binding.imageViewer)
+ imageViewModel.rotationAngle = 0f
+ }
+ } else {
+ requestBuilder = Glide.with(this).load(imageViewModel.imageBytes)
+ if (imageViewModel.rotationAngle.mod(360f) != 0f) {
+ rotateImage()
+ } else {
+ requestBuilder?.into(binding.imageViewer)
+ }
}
}
@@ -180,10 +192,16 @@ class ImageViewer: FileViewerActivity() {
handler.postDelayed(hideUI, hideDelay)
}
+ private fun onClickRotate(angle: Float) {
+ imageViewModel.rotationAngle += angle
+ binding.imageViewer.restoreZoomNormal()
+ rotateImage()
+ }
+
private fun swipeImage(deltaX: Float, slideshowSwipe: Boolean = false){
playlistNext(deltaX < 0)
- loadImage()
- if (slideshowActive){
+ loadImage(true)
+ if (slideshowActive) {
if (!slideshowSwipe) { //reset slideshow delay if user swipes
handler.removeCallbacks(slideshowNext)
}
@@ -214,14 +232,13 @@ class ImageViewer: FileViewerActivity() {
}
}
- private fun rotateImage(){
- binding.imageViewer.restoreZoomNormal()
- orientationTransformation = OrientationTransformation(rotationAngle)
+ private fun rotateImage() {
+ orientationTransformation = OrientationTransformation(imageViewModel.rotationAngle)
requestBuilder?.transform(orientationTransformation)?.into(binding.imageViewer)
}
private fun askSaveRotation(callback: () -> Unit){
- if (rotationAngle.mod(360f) != originalOrientation && !slideshowActive) {
+ if (imageViewModel.rotationAngle.mod(360f) != 0f && !slideshowActive) {
CustomAlertDialogBuilder(this, theme)
.keepFullScreen()
.setTitle(R.string.warning)
@@ -235,7 +252,7 @@ class ImageViewer: FileViewerActivity() {
Bitmap.CompressFormat.PNG
} else {
Bitmap.CompressFormat.JPEG
- }, 100, outputStream) == true
+ }, 90, outputStream) == true
){
if (encryptedVolume.importFile(ByteArrayInputStream(outputStream.toByteArray()), filePath)) {
Toast.makeText(this, R.string.image_saved_successfully, Toast.LENGTH_SHORT).show()
diff --git a/app/src/main/java/sushi/hardcore/droidfs/file_viewers/PdfViewer.kt b/app/src/main/java/sushi/hardcore/droidfs/file_viewers/PdfViewer.kt
index c10e859..097a74f 100644
--- a/app/src/main/java/sushi/hardcore/droidfs/file_viewers/PdfViewer.kt
+++ b/app/src/main/java/sushi/hardcore/droidfs/file_viewers/PdfViewer.kt
@@ -10,7 +10,6 @@ class PdfViewer: FileViewerActivity() {
init {
applyCustomTheme = false
}
- override var fullscreenMode = false
private lateinit var pdfViewer: PdfViewer
override fun getFileType(): String {
diff --git a/app/src/main/java/sushi/hardcore/droidfs/file_viewers/TextEditor.kt b/app/src/main/java/sushi/hardcore/droidfs/file_viewers/TextEditor.kt
index 324aa0b..7e56dd7 100644
--- a/app/src/main/java/sushi/hardcore/droidfs/file_viewers/TextEditor.kt
+++ b/app/src/main/java/sushi/hardcore/droidfs/file_viewers/TextEditor.kt
@@ -13,7 +13,6 @@ import sushi.hardcore.droidfs.widgets.CustomAlertDialogBuilder
import java.io.File
class TextEditor: FileViewerActivity() {
- override var fullscreenMode = false
private lateinit var fileName: String
private lateinit var editor: EditText
private var changedSinceLastSave = false
diff --git a/app/src/main/java/sushi/hardcore/droidfs/file_viewers/VideoPlayer.kt b/app/src/main/java/sushi/hardcore/droidfs/file_viewers/VideoPlayer.kt
index caaf306..a785aef 100644
--- a/app/src/main/java/sushi/hardcore/droidfs/file_viewers/VideoPlayer.kt
+++ b/app/src/main/java/sushi/hardcore/droidfs/file_viewers/VideoPlayer.kt
@@ -2,6 +2,7 @@ package sushi.hardcore.droidfs.file_viewers
import android.content.pm.ActivityInfo
import android.content.res.Configuration
+import android.view.View
import com.google.android.exoplayer2.ExoPlayer
import com.google.android.exoplayer2.ui.StyledPlayerView
import sushi.hardcore.droidfs.databinding.ActivityVideoPlayerBinding
@@ -16,9 +17,15 @@ class VideoPlayer: MediaPlayer() {
override fun viewFile() {
binding = ActivityVideoPlayerBinding.inflate(layoutInflater)
setContentView(binding.root)
+ applyNavigationBarMargin(binding.root)
binding.videoPlayer.doubleTapOverlay = binding.doubleTapOverlay
binding.videoPlayer.setControllerVisibilityListener(StyledPlayerView.ControllerVisibilityListener { visibility ->
binding.topBar.visibility = visibility
+ if (visibility == View.VISIBLE) {
+ showPartialSystemUi()
+ } else {
+ hideSystemUi()
+ }
})
binding.rotateButton.setOnClickListener {
requestedOrientation =
diff --git a/app/src/main/res/drawable/icon_mod.xml b/app/src/main/res/drawable/icon_mod.xml
deleted file mode 100644
index d0267e7..0000000
--- a/app/src/main/res/drawable/icon_mod.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml
index fb70504..d6c9195 100644
--- a/app/src/main/res/values-ar/strings.xml
+++ b/app/src/main/res/values-ar/strings.xml
@@ -159,8 +159,6 @@
إظهار المجلدات في بداية القائمة
التدوير التلقائي لشاشة مشغل الفيديو
تدوير الشاشة تلقائيًا لتناسب أبعاد الفيديو
- وضع ملء الشاشة القديم
- فعل هذا الخيار كان windowInsetsController لا يعمل بشكل صحيح على جهازك (عادة لا تكون هناك حاجة)
لم يتم العثور على مستكشف للملفات. رجاء ثبت واحد ثم أعد المحاولة.
إغلاق المجلد المشفر
تصنيف حسب
diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml
index 040e5c6..dce1435 100644
--- a/app/src/main/res/values-es/strings.xml
+++ b/app/src/main/res/values-es/strings.xml
@@ -159,8 +159,6 @@
Mostrar las carpetas al principio de la lista
Rotación automática de pantalla en el reproductor de vídeo
Rotación automática de la pantalla para adaptarla a las dimensiones del vídeo
- Modo de pantalla completa heredado
- Prueba esto si windowInsetsController no funciona correctamente en tu dispositivo (normalmente no es necesario)
No se ha encontrado ningún explorador de archivos. Por favor, instala uno y vuelve a intentarlo.
Cerrar volumen
Ordenar por
diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml
index cca68de..ebfe983 100644
--- a/app/src/main/res/values-pt-rBR/strings.xml
+++ b/app/src/main/res/values-pt-rBR/strings.xml
@@ -155,8 +155,6 @@
Mostrar pastas no início da lista
Girar automaticamente a tela ao reproduzir vídeo
Girar automaticamente a tela para encaixar em dimensões de vídeo
- Modo legado de tela completa
- Tente isto se windowInsetsController não funciona corretamente no seu dispositivo (geralmente não é necessário)
Não foi possível encontrar gerenciador de arquivos. Instale o app e tente novamente.
Fechar o volume
Ordenar por
diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml
index 09bc126..20409bb 100644
--- a/app/src/main/res/values-ru/strings.xml
+++ b/app/src/main/res/values-ru/strings.xml
@@ -153,8 +153,6 @@
Показывать папки в начале списка
Автоповорот видео
Автоматический поворот экрана в соответствии с размерами видео
- Устаревший полноэкранный режим
- Использовать данный режим, если windowInsetsController не работает должным образом на вашем устройстве (обычно не требуется)
Проводник файлов не найден. Установите его и повторите попытку.
Закрыть том
Сортировка
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index c5b04a7..c08c1ff 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -160,8 +160,6 @@
Show folders at the beginning of the list
Video player screen auto-rotation
Auto-rotate the screen to fit video dimensions
- Legacy fullscreen mode
- Try this if windowInsetsController doesn\'t work properly on your device (usually not needed)
No file explorer found. Please install one and retry.
Close volume
Sort By
diff --git a/app/src/main/res/xml/root_preferences.xml b/app/src/main/res/xml/root_preferences.xml
index cbf8b1f..a28bee5 100644
--- a/app/src/main/res/xml/root_preferences.xml
+++ b/app/src/main/res/xml/root_preferences.xml
@@ -67,13 +67,6 @@
android:defaultValue="false"
android:icon="@drawable/icon_screen_rotation"/>
-
-