Hide navigation bar in full screen mode

This commit is contained in:
Matéo Duparc 2023-03-13 17:02:38 +01:00
parent 22b1522192
commit 821c853a22
Signed by: hardcoresushi
GPG Key ID: AFE384344A45E13A
14 changed files with 99 additions and 75 deletions

View File

@ -50,7 +50,7 @@
<activity android:name=".explorers.ExplorerActivity"/> <activity android:name=".explorers.ExplorerActivity"/>
<activity android:name=".explorers.ExplorerActivityPick"/> <activity android:name=".explorers.ExplorerActivityPick"/>
<activity android:name=".explorers.ExplorerActivityDrop"/> <activity android:name=".explorers.ExplorerActivityDrop"/>
<activity android:name=".file_viewers.ImageViewer" android:configChanges="screenSize|orientation" /> <!-- don't reload content on configuration change --> <activity android:name=".file_viewers.ImageViewer"/>
<activity android:name=".file_viewers.VideoPlayer" android:configChanges="screenSize|orientation" /> <activity android:name=".file_viewers.VideoPlayer" android:configChanges="screenSize|orientation" />
<activity android:name=".file_viewers.PdfViewer" android:configChanges="screenSize|orientation" android:theme="@style/AppTheme" /> <activity android:name=".file_viewers.PdfViewer" android:configChanges="screenSize|orientation" android:theme="@style/AppTheme" />
<activity android:name=".file_viewers.AudioPlayer" android:configChanges="screenSize|orientation" /> <activity android:name=".file_viewers.AudioPlayer" android:configChanges="screenSize|orientation" />

View File

@ -125,7 +125,7 @@ class ExplorerElementAdapter(
volume.loadWholeFile(fullPath, maxSize = adapter.thumbnailMaxSize).first?.let { volume.loadWholeFile(fullPath, maxSize = adapter.thumbnailMaxSize).first?.let {
if (isActive) { if (isActive) {
withContext(Dispatchers.Main) { 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) { target = Glide.with(adapter.activity).load(it).skipMemoryCache(true).into(object : DrawableImageViewTarget(icon) {
override fun onResourceReady( override fun onResourceReady(
resource: Drawable, resource: Drawable,

View File

@ -1,10 +1,15 @@
package sushi.hardcore.droidfs.file_viewers package sushi.hardcore.droidfs.file_viewers
import android.os.Build
import android.os.Bundle import android.os.Bundle
import android.view.View 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.WindowInsetsCompat
import androidx.core.view.WindowInsetsControllerCompat import androidx.core.view.WindowInsetsControllerCompat
import androidx.core.view.updateLayoutParams
import androidx.core.view.updateMargins
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.isActive import kotlinx.coroutines.isActive
@ -29,10 +34,7 @@ abstract class FileViewerActivity: BaseActivity() {
private var wasMapped = false private var wasMapped = false
protected val mappedPlaylist = mutableListOf<ExplorerElement>() protected val mappedPlaylist = mutableListOf<ExplorerElement>()
protected var currentPlaylistIndex = -1 protected var currentPlaylistIndex = -1
protected open var fullscreenMode = true private val isLegacyFullscreen = Build.VERSION.SDK_INT <= Build.VERSION_CODES.R
private val legacyMod by lazy {
sharedPrefs.getBoolean("legacyMod", false)
}
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
@ -44,38 +46,61 @@ abstract class FileViewerActivity: BaseActivity() {
windowInsetsController.addOnControllableInsetsChangedListener { _, typeMask -> windowInsetsController.addOnControllableInsetsChangedListener { _, typeMask ->
windowTypeMask = typeMask windowTypeMask = typeMask
} }
if (fullscreenMode) { windowInsetsController.systemBarsBehavior = WindowInsetsControllerCompat.BEHAVIOR_SHOW_BARS_BY_SWIPE
fixNavBarColor()
hideSystemUi()
}
viewFile() viewFile()
} }
private fun fixNavBarColor() { open fun showPartialSystemUi() {
window.navigationBarColor = ContextCompat.getColor(this, R.color.fullScreenBackgroundColor) 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() { open fun hideSystemUi() {
if (legacyMod) { if (isLegacyFullscreen) {
@Suppress("Deprecation") @Suppress("Deprecation")
window.decorView.systemUiVisibility = window.decorView.systemUiVisibility =
View.SYSTEM_UI_FLAG_LOW_PROFILE or 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 { } 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<FrameLayout.LayoutParams> {
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 getFileType(): String
abstract fun viewFile() 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) { protected fun loadWholeFile(path: String, fileSize: Long? = null, callback: (ByteArray) -> Unit) {
lifecycleScope.launch(Dispatchers.IO) { lifecycleScope.launch(Dispatchers.IO) {
val result = encryptedVolume.loadWholeFile(path, size = fileSize) val result = encryptedVolume.loadWholeFile(path, size = fileSize)

View File

@ -10,6 +10,8 @@ import android.view.View
import android.view.WindowManager import android.view.WindowManager
import android.widget.Toast import android.widget.Toast
import androidx.activity.addCallback import androidx.activity.addCallback
import androidx.activity.viewModels
import androidx.lifecycle.ViewModel
import com.bumptech.glide.Glide import com.bumptech.glide.Glide
import com.bumptech.glide.RequestBuilder import com.bumptech.glide.RequestBuilder
import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool
@ -31,18 +33,23 @@ class ImageViewer: FileViewerActivity() {
private const val MIN_SWIPE_DISTANCE = 150 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 fileName: String
private lateinit var handler: Handler private lateinit var handler: Handler
private val imageViewModel: ImageViewModel by viewModels()
private var requestBuilder: RequestBuilder<Drawable>? = null private var requestBuilder: RequestBuilder<Drawable>? = null
private var x1 = 0F private var x1 = 0F
private var x2 = 0F private var x2 = 0F
private var slideshowActive = false private var slideshowActive = false
private var originalOrientation: Float = 0f
private var rotationAngle: Float = 0F
private var orientationTransformation: OrientationTransformation? = null private var orientationTransformation: OrientationTransformation? = null
private val hideUI = Runnable { private val hideUI = Runnable {
binding.actionButtons.visibility = View.GONE binding.actionButtons.visibility = View.GONE
binding.topBar.visibility = View.GONE binding.topBar.visibility = View.GONE
hideSystemUi()
} }
private val slideshowNext = Runnable { private val slideshowNext = Runnable {
if (slideshowActive){ if (slideshowActive){
@ -60,6 +67,8 @@ class ImageViewer: FileViewerActivity() {
binding = ActivityImageViewerBinding.inflate(layoutInflater) binding = ActivityImageViewerBinding.inflate(layoutInflater)
setContentView(binding.root) setContentView(binding.root)
supportActionBar?.hide() supportActionBar?.hide()
showPartialSystemUi()
applyNavigationBarMargin(binding.root)
handler = Handler(mainLooper) handler = Handler(mainLooper)
binding.imageViewer.setOnInteractionListener(object : ZoomableImageView.OnInteractionListener { binding.imageViewer.setOnInteractionListener(object : ZoomableImageView.OnInteractionListener {
override fun onSingleTap(event: MotionEvent?) { override fun onSingleTap(event: MotionEvent?) {
@ -67,6 +76,7 @@ class ImageViewer: FileViewerActivity() {
if (binding.actionButtons.visibility == View.GONE) { if (binding.actionButtons.visibility == View.GONE) {
binding.actionButtons.visibility = View.VISIBLE binding.actionButtons.visibility = View.VISIBLE
binding.topBar.visibility = View.VISIBLE binding.topBar.visibility = View.VISIBLE
showPartialSystemUi()
handler.postDelayed(hideUI, hideDelay) handler.postDelayed(hideUI, hideDelay)
} else { } else {
hideUI.run() hideUI.run()
@ -102,7 +112,7 @@ class ImageViewer: FileViewerActivity() {
if (mappedPlaylist.size == 0) { //deleted all images of the playlist if (mappedPlaylist.size == 0) { //deleted all images of the playlist
goBackToExplorer() goBackToExplorer()
} else { } else {
loadImage() loadImage(true)
} }
} else { } else {
CustomAlertDialogBuilder(this, theme) CustomAlertDialogBuilder(this, theme)
@ -140,14 +150,8 @@ class ImageViewer: FileViewerActivity() {
swipeImage(-1F) swipeImage(-1F)
} }
} }
binding.imageRotateRight.setOnClickListener { binding.imageRotateRight.setOnClickListener { onClickRotate(90f) }
rotationAngle += 90 binding.imageRotateLeft.setOnClickListener { onClickRotate(-90f) }
rotateImage()
}
binding.imageRotateLeft.setOnClickListener {
rotationAngle -= 90
rotateImage()
}
onBackPressedDispatcher.addCallback(this) { onBackPressedDispatcher.addCallback(this) {
if (slideshowActive) { if (slideshowActive) {
stopSlideshow() stopSlideshow()
@ -158,19 +162,27 @@ class ImageViewer: FileViewerActivity() {
} }
} }
} }
loadImage() loadImage(false)
handler.postDelayed(hideUI, hideDelay) handler.postDelayed(hideUI, hideDelay)
} }
private fun loadImage(){ private fun loadImage(newImage: Boolean) {
fileName = File(filePath).name fileName = File(filePath).name
binding.textFilename.text = fileName binding.textFilename.text = fileName
requestBuilder = null if (newImage || imageViewModel.imageBytes == null) {
loadWholeFile(filePath) { loadWholeFile(filePath) {
originalOrientation = 0f imageViewModel.imageBytes = it
requestBuilder = Glide.with(this).load(it) requestBuilder = Glide.with(this).load(it)
requestBuilder?.into(binding.imageViewer) requestBuilder?.into(binding.imageViewer)
rotationAngle = originalOrientation imageViewModel.rotationAngle = 0f
}
} else {
requestBuilder = Glide.with(this).load(imageViewModel.imageBytes)
if (imageViewModel.rotationAngle.mod(360f) != 0f) {
rotateImage()
} else {
requestBuilder?.into(binding.imageViewer)
}
} }
} }
@ -180,9 +192,15 @@ class ImageViewer: FileViewerActivity() {
handler.postDelayed(hideUI, hideDelay) handler.postDelayed(hideUI, hideDelay)
} }
private fun onClickRotate(angle: Float) {
imageViewModel.rotationAngle += angle
binding.imageViewer.restoreZoomNormal()
rotateImage()
}
private fun swipeImage(deltaX: Float, slideshowSwipe: Boolean = false){ private fun swipeImage(deltaX: Float, slideshowSwipe: Boolean = false){
playlistNext(deltaX < 0) playlistNext(deltaX < 0)
loadImage() loadImage(true)
if (slideshowActive) { if (slideshowActive) {
if (!slideshowSwipe) { //reset slideshow delay if user swipes if (!slideshowSwipe) { //reset slideshow delay if user swipes
handler.removeCallbacks(slideshowNext) handler.removeCallbacks(slideshowNext)
@ -215,13 +233,12 @@ class ImageViewer: FileViewerActivity() {
} }
private fun rotateImage() { private fun rotateImage() {
binding.imageViewer.restoreZoomNormal() orientationTransformation = OrientationTransformation(imageViewModel.rotationAngle)
orientationTransformation = OrientationTransformation(rotationAngle)
requestBuilder?.transform(orientationTransformation)?.into(binding.imageViewer) requestBuilder?.transform(orientationTransformation)?.into(binding.imageViewer)
} }
private fun askSaveRotation(callback: () -> Unit){ private fun askSaveRotation(callback: () -> Unit){
if (rotationAngle.mod(360f) != originalOrientation && !slideshowActive) { if (imageViewModel.rotationAngle.mod(360f) != 0f && !slideshowActive) {
CustomAlertDialogBuilder(this, theme) CustomAlertDialogBuilder(this, theme)
.keepFullScreen() .keepFullScreen()
.setTitle(R.string.warning) .setTitle(R.string.warning)
@ -235,7 +252,7 @@ class ImageViewer: FileViewerActivity() {
Bitmap.CompressFormat.PNG Bitmap.CompressFormat.PNG
} else { } else {
Bitmap.CompressFormat.JPEG Bitmap.CompressFormat.JPEG
}, 100, outputStream) == true }, 90, outputStream) == true
){ ){
if (encryptedVolume.importFile(ByteArrayInputStream(outputStream.toByteArray()), filePath)) { if (encryptedVolume.importFile(ByteArrayInputStream(outputStream.toByteArray()), filePath)) {
Toast.makeText(this, R.string.image_saved_successfully, Toast.LENGTH_SHORT).show() Toast.makeText(this, R.string.image_saved_successfully, Toast.LENGTH_SHORT).show()

View File

@ -10,7 +10,6 @@ class PdfViewer: FileViewerActivity() {
init { init {
applyCustomTheme = false applyCustomTheme = false
} }
override var fullscreenMode = false
private lateinit var pdfViewer: PdfViewer private lateinit var pdfViewer: PdfViewer
override fun getFileType(): String { override fun getFileType(): String {

View File

@ -13,7 +13,6 @@ import sushi.hardcore.droidfs.widgets.CustomAlertDialogBuilder
import java.io.File import java.io.File
class TextEditor: FileViewerActivity() { class TextEditor: FileViewerActivity() {
override var fullscreenMode = false
private lateinit var fileName: String private lateinit var fileName: String
private lateinit var editor: EditText private lateinit var editor: EditText
private var changedSinceLastSave = false private var changedSinceLastSave = false

View File

@ -2,6 +2,7 @@ package sushi.hardcore.droidfs.file_viewers
import android.content.pm.ActivityInfo import android.content.pm.ActivityInfo
import android.content.res.Configuration import android.content.res.Configuration
import android.view.View
import com.google.android.exoplayer2.ExoPlayer import com.google.android.exoplayer2.ExoPlayer
import com.google.android.exoplayer2.ui.StyledPlayerView import com.google.android.exoplayer2.ui.StyledPlayerView
import sushi.hardcore.droidfs.databinding.ActivityVideoPlayerBinding import sushi.hardcore.droidfs.databinding.ActivityVideoPlayerBinding
@ -16,9 +17,15 @@ class VideoPlayer: MediaPlayer() {
override fun viewFile() { override fun viewFile() {
binding = ActivityVideoPlayerBinding.inflate(layoutInflater) binding = ActivityVideoPlayerBinding.inflate(layoutInflater)
setContentView(binding.root) setContentView(binding.root)
applyNavigationBarMargin(binding.root)
binding.videoPlayer.doubleTapOverlay = binding.doubleTapOverlay binding.videoPlayer.doubleTapOverlay = binding.doubleTapOverlay
binding.videoPlayer.setControllerVisibilityListener(StyledPlayerView.ControllerVisibilityListener { visibility -> binding.videoPlayer.setControllerVisibilityListener(StyledPlayerView.ControllerVisibilityListener { visibility ->
binding.topBar.visibility = visibility binding.topBar.visibility = visibility
if (visibility == View.VISIBLE) {
showPartialSystemUi()
} else {
hideSystemUi()
}
}) })
binding.rotateButton.setOnClickListener { binding.rotateButton.setOnClickListener {
requestedOrientation = requestedOrientation =

View File

@ -1,6 +0,0 @@
<vector android:height="24dp"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="?attr/colorAccent"
android:pathData="M5,16c0,3.87 3.13,7 7,7s7,-3.13 7,-7v-4L5,12v4zM16.12,4.37l2.1,-2.1 -0.82,-0.83 -2.3,2.31C14.16,3.28 13.12,3 12,3s-2.16,0.28 -3.09,0.75L6.6,1.44l-0.82,0.83 2.1,2.1C6.14,5.64 5,7.68 5,10v1h14v-1c0,-2.32 -1.14,-4.36 -2.88,-5.63zM9,9c-0.55,0 -1,-0.45 -1,-1s0.45,-1 1,-1 1,0.45 1,1 -0.45,1 -1,1zM15,9c-0.55,0 -1,-0.45 -1,-1s0.45,-1 1,-1 1,0.45 1,1 -0.45,1 -1,1z"/>
</vector>

View File

@ -159,8 +159,6 @@
<string name="folders_first_summary">إظهار المجلدات في بداية القائمة</string> <string name="folders_first_summary">إظهار المجلدات في بداية القائمة</string>
<string name="auto_fit_title">التدوير التلقائي لشاشة مشغل الفيديو</string> <string name="auto_fit_title">التدوير التلقائي لشاشة مشغل الفيديو</string>
<string name="auto_fit_summary">تدوير الشاشة تلقائيًا لتناسب أبعاد الفيديو</string> <string name="auto_fit_summary">تدوير الشاشة تلقائيًا لتناسب أبعاد الفيديو</string>
<string name="legacy_mod_title">وضع ملء الشاشة القديم</string>
<string name="legacy_mod_summary">فعل هذا الخيار كان windowInsetsController لا يعمل بشكل صحيح على جهازك (عادة لا تكون هناك حاجة)</string>
<string name="open_tree_failed">لم يتم العثور على مستكشف للملفات. رجاء ثبت واحد ثم أعد المحاولة.</string> <string name="open_tree_failed">لم يتم العثور على مستكشف للملفات. رجاء ثبت واحد ثم أعد المحاولة.</string>
<string name="close_volume">إغلاق المجلد المشفر</string> <string name="close_volume">إغلاق المجلد المشفر</string>
<string name="sort_by">تصنيف حسب</string> <string name="sort_by">تصنيف حسب</string>

View File

@ -159,8 +159,6 @@
<string name="folders_first_summary">Mostrar las carpetas al principio de la lista</string> <string name="folders_first_summary">Mostrar las carpetas al principio de la lista</string>
<string name="auto_fit_title">Rotación automática de pantalla en el reproductor de vídeo</string> <string name="auto_fit_title">Rotación automática de pantalla en el reproductor de vídeo</string>
<string name="auto_fit_summary">Rotación automática de la pantalla para adaptarla a las dimensiones del vídeo</string> <string name="auto_fit_summary">Rotación automática de la pantalla para adaptarla a las dimensiones del vídeo</string>
<string name="legacy_mod_title">Modo de pantalla completa heredado</string>
<string name="legacy_mod_summary">Prueba esto si windowInsetsController no funciona correctamente en tu dispositivo (normalmente no es necesario)</string>
<string name="open_tree_failed">No se ha encontrado ningún explorador de archivos. Por favor, instala uno y vuelve a intentarlo.</string> <string name="open_tree_failed">No se ha encontrado ningún explorador de archivos. Por favor, instala uno y vuelve a intentarlo.</string>
<string name="close_volume">Cerrar volumen</string> <string name="close_volume">Cerrar volumen</string>
<string name="sort_by">Ordenar por</string> <string name="sort_by">Ordenar por</string>

View File

@ -155,8 +155,6 @@
<string name="folders_first_summary">Mostrar pastas no início da lista</string> <string name="folders_first_summary">Mostrar pastas no início da lista</string>
<string name="auto_fit_title">Girar automaticamente a tela ao reproduzir vídeo</string> <string name="auto_fit_title">Girar automaticamente a tela ao reproduzir vídeo</string>
<string name="auto_fit_summary">Girar automaticamente a tela para encaixar em dimensões de vídeo</string> <string name="auto_fit_summary">Girar automaticamente a tela para encaixar em dimensões de vídeo</string>
<string name="legacy_mod_title">Modo legado de tela completa</string>
<string name="legacy_mod_summary">Tente isto se windowInsetsController não funciona corretamente no seu dispositivo (geralmente não é necessário)</string>
<string name="open_tree_failed">Não foi possível encontrar gerenciador de arquivos. Instale o app e tente novamente.</string> <string name="open_tree_failed">Não foi possível encontrar gerenciador de arquivos. Instale o app e tente novamente.</string>
<string name="close_volume">Fechar o volume</string> <string name="close_volume">Fechar o volume</string>
<string name="sort_by">Ordenar por</string> <string name="sort_by">Ordenar por</string>

View File

@ -153,8 +153,6 @@
<string name="folders_first_summary">Показывать папки в начале списка</string> <string name="folders_first_summary">Показывать папки в начале списка</string>
<string name="auto_fit_title">Автоповорот видео</string> <string name="auto_fit_title">Автоповорот видео</string>
<string name="auto_fit_summary">Автоматический поворот экрана в соответствии с размерами видео</string> <string name="auto_fit_summary">Автоматический поворот экрана в соответствии с размерами видео</string>
<string name="legacy_mod_title">Устаревший полноэкранный режим</string>
<string name="legacy_mod_summary">Использовать данный режим, если windowInsetsController не работает должным образом на вашем устройстве (обычно не требуется)</string>
<string name="open_tree_failed">Проводник файлов не найден. Установите его и повторите попытку.</string> <string name="open_tree_failed">Проводник файлов не найден. Установите его и повторите попытку.</string>
<string name="close_volume">Закрыть том</string> <string name="close_volume">Закрыть том</string>
<string name="sort_by">Сортировка</string> <string name="sort_by">Сортировка</string>

View File

@ -160,8 +160,6 @@
<string name="folders_first_summary">Show folders at the beginning of the list</string> <string name="folders_first_summary">Show folders at the beginning of the list</string>
<string name="auto_fit_title">Video player screen auto-rotation</string> <string name="auto_fit_title">Video player screen auto-rotation</string>
<string name="auto_fit_summary">Auto-rotate the screen to fit video dimensions</string> <string name="auto_fit_summary">Auto-rotate the screen to fit video dimensions</string>
<string name="legacy_mod_title">Legacy fullscreen mode</string>
<string name="legacy_mod_summary">Try this if windowInsetsController doesn\'t work properly on your device (usually not needed)</string>
<string name="open_tree_failed">No file explorer found. Please install one and retry.</string> <string name="open_tree_failed">No file explorer found. Please install one and retry.</string>
<string name="close_volume">Close volume</string> <string name="close_volume">Close volume</string>
<string name="sort_by">Sort By</string> <string name="sort_by">Sort By</string>

View File

@ -67,13 +67,6 @@
android:defaultValue="false" android:defaultValue="false"
android:icon="@drawable/icon_screen_rotation"/> android:icon="@drawable/icon_screen_rotation"/>
<SwitchPreferenceCompat
android:title="@string/legacy_mod_title"
android:summary="@string/legacy_mod_summary"
android:key="legacyMod"
android:defaultValue="false"
android:icon="@drawable/icon_mod"/>
<SwitchPreferenceCompat <SwitchPreferenceCompat
android:title="@string/password_fallback" android:title="@string/password_fallback"
android:summary="@string/password_fallback_summary" android:summary="@string/password_fallback_summary"