This commit is contained in:
kunfei
2023-03-31 10:02:24 +08:00
parent 56d02943ee
commit 8699148c01
4 changed files with 108 additions and 38 deletions

View File

@@ -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
}

View File

@@ -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>()
}

View File

@@ -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 = ".."
}
}

View File

@@ -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"