kunfei 3 лет назад
Родитель
Сommit
5a0b977dcf

+ 77 - 20
app/src/main/java/io/legado/app/ui/document/FileManageActivity.kt

@@ -1,28 +1,28 @@
 package io.legado.app.ui.document
 
+import android.annotation.SuppressLint
 import android.os.Bundle
 import android.view.ViewGroup
 import androidx.activity.viewModels
 import androidx.appcompat.widget.SearchView
 import androidx.recyclerview.widget.LinearLayoutManager
+import androidx.recyclerview.widget.RecyclerView
 import io.legado.app.R
 import io.legado.app.base.VMBaseActivity
 import io.legado.app.base.adapter.ItemViewHolder
 import io.legado.app.base.adapter.RecyclerAdapter
 import io.legado.app.databinding.ActivityFileManageBinding
 import io.legado.app.databinding.ItemFileBinding
+import io.legado.app.databinding.ItemPathPickerBinding
 import io.legado.app.lib.theme.primaryTextColor
-import io.legado.app.ui.document.adapter.PathAdapter
 import io.legado.app.ui.document.utils.FilePickerIcon
 import io.legado.app.ui.widget.recycler.VerticalDivider
 import io.legado.app.utils.ConvertUtils
-import io.legado.app.utils.FileDoc
 import io.legado.app.utils.applyTint
-import io.legado.app.utils.list
 import io.legado.app.utils.viewbindingdelegate.viewBinding
+import java.io.File
 
-class FileManageActivity : VMBaseActivity<ActivityFileManageBinding, FileManageViewModel>(),
-    PathAdapter.CallBack {
+class FileManageActivity : VMBaseActivity<ActivityFileManageBinding, FileManageViewModel>() {
 
     override val binding by viewBinding(ActivityFileManageBinding::inflate)
     override val viewModel by viewModels<FileManageViewModel>()
@@ -30,7 +30,7 @@ class FileManageActivity : VMBaseActivity<ActivityFileManageBinding, FileManageV
         binding.titleBar.findViewById(R.id.search_view)
     }
     private val pathAdapter by lazy {
-        PathAdapter(this, this)
+        PathAdapter()
     }
     private val fileAdapter by lazy {
         FileAdapter()
@@ -39,14 +39,14 @@ class FileManageActivity : VMBaseActivity<ActivityFileManageBinding, FileManageV
     override fun onActivityCreated(savedInstanceState: Bundle?) {
         initView()
         initSearchView()
-        initData()
+        viewModel.upFiles(viewModel.rootDoc)
     }
 
     private fun initView() {
-        binding.rvPath.layoutManager = LinearLayoutManager(this)
-        binding.rvPath.addItemDecoration(VerticalDivider(this))
+        binding.rvPath.layoutManager = LinearLayoutManager(this, RecyclerView.HORIZONTAL, false)
         binding.rvPath.adapter = pathAdapter
         binding.recyclerView.layoutManager = LinearLayoutManager(this)
+        binding.recyclerView.addItemDecoration(VerticalDivider(this))
         binding.recyclerView.adapter = fileAdapter
     }
 
@@ -68,43 +68,100 @@ class FileManageActivity : VMBaseActivity<ActivityFileManageBinding, FileManageV
         })
     }
 
-    private fun initData() {
-        viewModel.rootDoc?.list()?.let {
+    override fun observeLiveBus() {
+        viewModel.filesLiveData.observe(this) {
             fileAdapter.setItems(it)
         }
     }
 
-    override fun onPathClick(position: Int) {
+    @SuppressLint("SetTextI18n")
+    inner class PathAdapter :
+        RecyclerAdapter<File, ItemPathPickerBinding>(this@FileManageActivity) {
+
+        private val arrowIcon = ConvertUtils.toDrawable(FilePickerIcon.getArrow())
+
+        init {
+            addHeaderView {
+                ItemPathPickerBinding.inflate(inflater, it, false).apply {
+                    textView.text = "root"
+                    imageView.setImageDrawable(arrowIcon)
+                    root.setOnClickListener {
+                        viewModel.subDocs.clear()
+                        setItems(viewModel.subDocs)
+                        viewModel.upFiles(viewModel.rootDoc)
+                    }
+                }
+            }
+        }
+
+        override fun getViewBinding(parent: ViewGroup): ItemPathPickerBinding {
+            return ItemPathPickerBinding.inflate(inflater, parent, false).apply {
+                imageView.setImageDrawable(arrowIcon)
+            }
+        }
+
+        override fun registerListener(holder: ItemViewHolder, binding: ItemPathPickerBinding) {
+            binding.root.setOnClickListener {
+                viewModel.subDocs = viewModel.subDocs.subList(0, holder.layoutPosition)
+                setItems(viewModel.subDocs)
+                viewModel.upFiles(viewModel.subDocs.lastOrNull())
+            }
+        }
+
+        override fun convert(
+            holder: ItemViewHolder,
+            binding: ItemPathPickerBinding,
+            item: File,
+            payloads: MutableList<Any>
+        ) {
+            binding.textView.text = item.name
+        }
 
     }
 
-    inner class FileAdapter : RecyclerAdapter<FileDoc, ItemFileBinding>(this@FileManageActivity) {
+    inner class FileAdapter : RecyclerAdapter<File, ItemFileBinding>(this@FileManageActivity) {
         private val upIcon = ConvertUtils.toDrawable(FilePickerIcon.getUpDir())!!
         private val folderIcon = ConvertUtils.toDrawable(FilePickerIcon.getFolder())!!
         private val fileIcon = ConvertUtils.toDrawable(FilePickerIcon.getFile())!!
+        private val dirParent = ".."
 
         override fun getViewBinding(parent: ViewGroup): ItemFileBinding {
             return ItemFileBinding.inflate(inflater, parent, false)
         }
 
         override fun registerListener(holder: ItemViewHolder, binding: ItemFileBinding) {
-
+            binding.root.setOnClickListener {
+                val item = getItemByLayoutPosition(holder.layoutPosition)
+                item?.let {
+                    if (item == (viewModel.subDocs.lastOrNull() ?: viewModel.rootDoc)) {
+                        viewModel.subDocs.removeLastOrNull()
+                        pathAdapter.setItems(viewModel.subDocs)
+                        viewModel.upFiles(viewModel.subDocs.lastOrNull() ?: viewModel.rootDoc)
+                    } else if (item.isDirectory) {
+                        viewModel.subDocs.add(item)
+                        pathAdapter.setItems(viewModel.subDocs)
+                        viewModel.upFiles(item)
+                    }
+                }
+            }
         }
 
         override fun convert(
             holder: ItemViewHolder,
             binding: ItemFileBinding,
-            item: FileDoc,
+            item: File,
             payloads: MutableList<Any>
         ) {
-            if (!item.isDir) {
-                binding.imageView.setImageDrawable(fileIcon)
-            } else if (holder.layoutPosition == 0 && viewModel.subDocs.isNotEmpty()) {
+            if (item == (viewModel.subDocs.lastOrNull() ?: viewModel.rootDoc)) {
                 binding.imageView.setImageDrawable(upIcon)
-            } else {
+                binding.textView.text = dirParent
+            } else if (item.isDirectory) {
                 binding.imageView.setImageDrawable(folderIcon)
+                binding.textView.text = item.name
+            } else {
+                binding.imageView.setImageDrawable(fileIcon)
+                binding.textView.text = item.name
             }
-            binding.textView.text = item.name
         }
 
 

+ 26 - 4
app/src/main/java/io/legado/app/ui/document/FileManageViewModel.kt

@@ -1,14 +1,36 @@
 package io.legado.app.ui.document
 
 import android.app.Application
+import androidx.lifecycle.MutableLiveData
 import io.legado.app.base.BaseViewModel
-import io.legado.app.utils.FileDoc
+import io.legado.app.utils.toastOnUi
+import java.io.File
 
 class FileManageViewModel(application: Application) : BaseViewModel(application) {
 
-    val rootDoc = context.getExternalFilesDir(null)?.parentFile?.let {
-        FileDoc.fromFile(it)
+    val rootDoc = context.getExternalFilesDir(null)?.parentFile
+    var subDocs = mutableListOf<File>()
+    val filesLiveData = MutableLiveData<List<File>>()
+
+    fun upFiles(parentFile: File?) {
+        execute {
+            if (parentFile == rootDoc) {
+                parentFile?.listFiles()?.toList()
+            } else {
+                val list = arrayListOf(parentFile)
+                parentFile?.listFiles()?.let {
+                    list.addAll(it)
+                }
+                list
+            }
+        }.onStart {
+            filesLiveData.postValue(emptyList())
+        }.onSuccess {
+            filesLiveData.postValue(it ?: emptyList())
+        }.onError {
+            context.toastOnUi(it.localizedMessage)
+        }
     }
-    val subDocs = arrayListOf<FileDoc>()
+
 
 }

+ 4 - 7
app/src/main/java/io/legado/app/ui/document/adapter/FileAdapter.kt

@@ -27,6 +27,8 @@ class FileAdapter(context: Context, val callBack: CallBack) :
     private val fileIcon = ConvertUtils.toDrawable(FilePickerIcon.getFile())!!
     private val primaryTextColor = context.getPrimaryTextColor(!AppConfig.isNightTheme)
     private val disabledTextColor = context.getPrimaryDisabledTextColor(!AppConfig.isNightTheme)
+    private val dirRoot = "."
+    private val dirParent = ".."
 
     fun loadData(path: String?) {
         if (path == null) {
@@ -42,7 +44,7 @@ class FileAdapter(context: Context, val callBack: CallBack) :
             val fileRoot = FileItem(
                 isDirectory = true,
                 icon = homeIcon,
-                name = DIR_ROOT,
+                name = dirRoot,
                 path = rootPath ?: path
             )
             data.add(fileRoot)
@@ -52,7 +54,7 @@ class FileAdapter(context: Context, val callBack: CallBack) :
             val fileParent = FileItem(
                 isDirectory = true,
                 icon = upIcon,
-                name = DIR_PARENT,
+                name = dirParent,
                 path = File(path).parent ?: ""
             )
             data.add(fileParent)
@@ -152,10 +154,5 @@ class FileAdapter(context: Context, val callBack: CallBack) :
         var isShowHideDir: Boolean
     }
 
-    companion object {
-        const val DIR_ROOT = "."
-        const val DIR_PARENT = ".."
-    }
-
 }
 

+ 1 - 7
app/src/main/res/layout/activity_file_manage.xml

@@ -24,18 +24,12 @@
         android:elevation="5dp"
         app:layout_constraintTop_toBottomOf="@+id/titleBar" />
 
-    <io.legado.app.ui.widget.anima.RefreshProgressBar
-        android:id="@+id/refresh_progress_bar"
-        android:layout_width="match_parent"
-        android:layout_height="2dp"
-        app:layout_constraintTop_toBottomOf="@id/rv_path" />
-
     <FrameLayout
         android:layout_width="match_parent"
         android:layout_height="0dp"
         android:layout_weight="1"
         app:layout_constraintBottom_toTopOf="@id/select_action_bar"
-        app:layout_constraintTop_toBottomOf="@id/refresh_progress_bar">
+        app:layout_constraintTop_toBottomOf="@id/rv_path">
 
         <io.legado.app.ui.widget.recycler.scroller.FastScrollRecyclerView
             android:id="@+id/recycler_view"