Commit 446b0d7d authored by wanglei's avatar wanglei

白包版本

parent 29ea9ca7
......@@ -3,7 +3,20 @@
<component name="deploymentTargetDropDown">
<value>
<entry key="app">
<State />
<State>
<runningDeviceTargetSelectedWithDropDown>
<Target>
<type value="RUNNING_DEVICE_TARGET" />
<deviceKey>
<Key>
<type value="SERIAL_NUMBER" />
<value value="adb-3426369207001D6-FYisxI._adb-tls-connect._tcp" />
</Key>
</deviceKey>
</Target>
</runningDeviceTargetSelectedWithDropDown>
<timeTargetWasSelectedWithDropDown value="2024-03-29T05:30:11.946057700Z" />
</State>
</entry>
</value>
</component>
......
package com.zxhy.simplefilesmanager.internalstorage
import android.Manifest
import android.annotation.SuppressLint
import android.content.Intent
import android.content.Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
import android.content.Intent.FLAG_GRANT_READ_URI_PERMISSION
import android.content.Intent.FLAG_GRANT_WRITE_URI_PERMISSION
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.os.Environment
import android.view.Gravity
import android.view.MotionEvent
import android.view.View
import android.view.ViewGroup
import android.widget.PopupWindow
import androidx.activity.addCallback
import androidx.activity.enableEdgeToEdge
import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.FileProvider
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import androidx.core.view.isVisible
import androidx.lifecycle.lifecycleScope
import com.zxhy.simplefilesmanager.R
import com.zxhy.simplefilesmanager.databinding.ActivityInternalStorageBinding
import com.zxhy.simplefilesmanager.databinding.PopupwindowMoreOpeartionBinding
import com.zxhy.simplefilesmanager.simpledata.JoListFileJo
import com.zxhy.simplefilesmanager.simpledata.JoListFileJo.Companion.joListFileJo
import com.zxhy.simplefilesmanager.simpledialog.SimpleFileDialog.showSimpleFileDialog
import com.zxhy.simplefilesmanager.simplejoke.JoActivityJoLauncher
import com.zxhy.simplefilesmanager.simplejoke.permission.JoPermissionJoCheckEx.jostorejoPermissionCheck
import com.zxhy.simplefilesmanager.simplejoke.permission.JoStoreJoPermissionEx.jorequestjoStoreFollow
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import java.io.File
class InternalStorageActivity : AppCompatActivity() {
private lateinit var binding: ActivityInternalStorageBinding
private val viewModel: InternalStorageViewModel by viewModels()
private lateinit var launch: JoActivityJoLauncher
private var currentMode: Int = BROWSER_MODE
private val adapter by lazy {
JoInternalJoStorageAdapter(
allSelect = {
binding.ivAll.isSelected = it
},
showEmpty = {
showEmpty(isEmpty = it, showWrite = !it)
}
)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
launch = JoActivityJoLauncher(this)
binding = ActivityInternalStorageBinding.inflate(layoutInflater)
setContentView(R.layout.activity_internal_storage)
setContentView(binding.root)
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets ->
val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
insets
}
if (!jostorejoPermissionCheck()) {
showPermissionSet()
} else {
initView()
loadStorage()
}
}
private fun showPermissionSet() {
binding.flPermissionSet.visibility = View.VISIBLE
binding.tvSet.setOnClickListener {
jorequestjoStoreFollow(launch,
agreeAction = {
initView()
loadStorage()
},
disAgreeAction = {
}
)
}
}
private fun initView() {
binding.flPermissionSet.visibility = View.GONE
binding.llContent.visibility = View.VISIBLE
binding.ivAll.setOnClickListener {
it.isSelected = !it.isSelected
adapter.toggleSelect(it.isSelected)
}
binding.ivWrite.setOnClickListener {
operationMode()
}
binding.ivNewFile.setOnClickListener {
showSimpleFileDialog { name ->
val file = File(adapter.getCurrentDir(), name)
if (file.isFile) return@showSimpleFileDialog
if (!file.exists()) {
file.mkdirs()
adapter.notifyCurrentDir()
}
}
}
binding.rv.adapter = adapter
onBackPressedDispatcher.addCallback {
if (currentMode == BROWSER_MODE) {
val isRoot = adapter.beforePage()
if (isRoot)
finish()
}
if (currentMode == OPERATION_MODE) {
browserMode()
}
if (currentMode == CONFIRM_MODE) {
adapter.beforePage()
}
}
}
private fun browserMode() {
currentMode = BROWSER_MODE
binding.ivAll.visibility = View.GONE
binding.ivWrite.visibility = View.VISIBLE
adapter.changeSelect(false, isRemoveCannotNext = true)
binding.llOperation.visibility = View.GONE
binding.flConfirm.visibility = View.GONE
}
private fun operationMode() {
currentMode = OPERATION_MODE
binding.flConfirm.visibility = View.GONE
binding.llOperation.visibility = View.VISIBLE
adapter.changeSelect(true, canNext = false)
binding.ivAll.isSelected = false
showEmpty(showAll = true)
binding.llMove.setOnClickListener {
confirmMode("Move")
}
binding.llCopy.setOnClickListener {
confirmMode("Copy")
}
binding.llShare.setOnClickListener {
shareFiles()
}
binding.llMore.setOnClickListener {
val files = adapter.getSelectData().map { it.toFile() }
val size = files.size
if (size == 0) return@setOnClickListener
if (size == 1) {
showMorePopupWindow(
2,
renameAction = { renameFile(files.first()) },
deleteAction = { deleteFiles(files) }
)
} else {
showMorePopupWindow(1, deleteAction = { deleteFiles(files) })
}
}
}
private fun deleteFiles(files: List<File>) {
viewModel.deleteFiles(files, ::operationFinish)
}
private fun renameFile(file: File) {
val dir = file.parentFile
showSimpleFileDialog(file.name, nameAction = {
runCatching { file.renameTo(File(dir, it)) }
operationFinish()
})
}
@SuppressLint("SetTextI18n")
private fun confirmMode(operation: String) {
val selectFile = adapter.getSelectData()
if (selectFile.isEmpty())
return
currentMode = CONFIRM_MODE
binding.llOperation.visibility = View.GONE
binding.ivAll.isSelected = false
binding.ivAll.visibility = View.GONE
binding.flConfirm.visibility = View.VISIBLE
adapter.changeSelect(false, isAddCannotNext = true)
binding.tvCancel.setOnClickListener {
browserMode()
}
binding.tvConfirm.setOnClickListener {
val files = adapter.getOperationList()
val currentDir = adapter.getCurrentDir()
when (operation) {
"Move" -> {
binding.tvConfirm.text = "Motion"
viewModel.moveFiles(files, currentDir, ::operationFinish)
}
"Copy" -> {
binding.tvConfirm.text = "Paste"
viewModel.copyFiles(files, currentDir, ::operationFinish)
}
}
}
}
private fun shareFiles() = runCatching {
val list = adapter.getSelectData()
val arrayList = ArrayList<Uri>()
list.forEach {
val uri = FileProvider.getUriForFile(this, "$packageName.provider", File(it.path))
grantUriPermission(
packageName, uri, FLAG_GRANT_READ_URI_PERMISSION
)
arrayList.add(uri)
}
val intent = Intent()
intent.action = "android.intent.action.SEND_MULTIPLE"
intent.type = "image/*"
intent.putExtra("android.intent.extra.STREAM", arrayList)
intent.addFlags(FLAG_GRANT_READ_URI_PERMISSION)
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
startActivity(intent)
browserMode()
}
private fun operationFinish() = lifecycleScope.launch(Dispatchers.Main) {
browserMode()
adapter.notifyCurrentDir()
}
private fun loadStorage() {
val root = Environment.getExternalStorageDirectory().listFiles()
val datas = root?.map { joListFileJo(it) } ?: listOf()
showEmpty(isEmpty = datas.isEmpty(), showWrite = true)
adapter.setData(datas)
}
fun showEmpty(isEmpty: Boolean = false, showAll: Boolean = false, showWrite: Boolean = false) {
binding.llEmpty.isVisible = isEmpty
if (isEmpty) {
binding.flAllWrite.visibility = View.GONE
} else {
binding.flAllWrite.visibility = View.VISIBLE
binding.ivAll.isVisible = showAll
binding.ivWrite.isVisible = showWrite
}
}
companion object {
const val BROWSER_MODE = 12
const val OPERATION_MODE = 13
const val CONFIRM_MODE = 18
}
@SuppressLint("ClickableViewAccessibility", "InflateParams")
private fun showMorePopupWindow(
count: Int = 2,
renameAction: (() -> Unit)? = null,
deleteAction: (() -> Unit)? = null
) {
val popupWindowView = layoutInflater.inflate(R.layout.popupwindow_more_opeartion, null)
val popupBinding = PopupwindowMoreOpeartionBinding.bind(popupWindowView)
val itemHeight = resources.getDimensionPixelOffset(R.dimen.dp_40)
if (count == 1) {
popupBinding.llRename.visibility = View.GONE
}
val width =
resources.getDimensionPixelSize(R.dimen.dp_108)
val height = ViewGroup.LayoutParams.WRAP_CONTENT
val popupWindow = PopupWindow(popupWindowView, width, height, true)
popupWindow.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
popupWindow.isOutsideTouchable = true
popupWindow.isTouchable = true
val intArr = intArrayOf(0, 0)
binding.llMore.getLocationOnScreen(intArr)
popupWindow.showAtLocation(
binding.llOperation, Gravity.NO_GRAVITY,
intArr[0], intArr[1] - itemHeight * count - 20,
)
popupBinding.llRename.setOnTouchListener { v, event ->
when (event.action) {
MotionEvent.ACTION_DOWN -> {
popupBinding.ivRename.isSelected = true
popupBinding.tvRename.isSelected = true
}
MotionEvent.ACTION_UP -> {
popupBinding.ivRename.isSelected = false
popupBinding.tvRename.isSelected = false
}
else -> {}
}
false
}
popupBinding.llDelete.setOnTouchListener { v, event ->
when (event.action) {
MotionEvent.ACTION_DOWN -> {
popupBinding.ivDelete.isSelected = true
popupBinding.tvDelete.isSelected = true
}
MotionEvent.ACTION_UP -> {
popupBinding.ivDelete.isSelected = false
popupBinding.tvDelete.isSelected = false
}
else -> {}
}
false
}
popupBinding.llRename.setOnClickListener {
popupWindow.dismiss()
renameAction?.invoke()
}
popupBinding.llDelete.setOnClickListener {
popupWindow.dismiss()
deleteAction?.invoke()
}
}
}
\ No newline at end of file
package com.zxhy.simplefilesmanager.internalstorage
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.zxhy.simplefilesmanager.simpleCommon.SimpleCommonViewModel
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import java.io.File
class InternalStorageViewModel : SimpleCommonViewModel() {
fun copyFiles(
files: List<File>, currentDir: File,
finish: () -> Unit
) = viewModelScope.launch(Dispatchers.IO) {
runCatching {
files.forEach {
it.copyRecursively(File(currentDir, it.name), true)
}
}
finish.invoke()
}
fun moveFiles(
files: List<File>, currentDir: File,
finish: () -> Unit
) = viewModelScope.launch(Dispatchers.IO) {
runCatching {
files.forEach {
it.copyRecursively(File(currentDir, it.name), true)
it.deleteRecursively()
}
}
finish.invoke()
}
}
\ No newline at end of file
package com.zxhy.simplefilesmanager.internalstorage
import android.annotation.SuppressLint
import android.os.Environment
import android.view.View
import android.view.ViewGroup
import androidx.core.content.ContextCompat
import androidx.core.view.isVisible
import androidx.recyclerview.widget.RecyclerView.ViewHolder
import com.zxhy.simplefilesmanager.R
import com.zxhy.simplefilesmanager.databinding.ItemJoListFileJoBinding
import com.zxhy.simplefilesmanager.simpleadpter.JoCommonJoAdapter
import com.zxhy.simplefilesmanager.simpledata.JoListFileJo
import com.zxhy.simplefilesmanager.simpledata.JoListFileJo.Companion.joListFileJo
import com.zxhy.simplefilesmanager.simpledata.JoListFileJo.Companion.sizeF
import com.zxhy.simplefilesmanager.simplejoke.JoXmljoEx.jojoinflate
import java.io.File
@SuppressLint("NotifyDataSetChanged")
class JoInternalJoStorageAdapter(
private val allSelect: (select: Boolean) -> Unit,
private val showEmpty: ((isShow: Boolean) -> Unit)? = null
) : JoCommonJoAdapter<JoInternalJoStorageAdapter.GGGG, JoListFileJo>() {
private var showSelect: Boolean = false
private var currentDir = Environment.getExternalStorageDirectory()
private val cannotNextFiles = arrayListOf<File>()
private var canNext: Boolean = true
class GGGG(view: View) : ViewHolder(view) {
val binding = ItemJoListFileJoBinding.bind(view)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): GGGG {
return GGGG(R.layout.item_jo_list_file_jo.jojoinflate(parent))
}
override fun onBindViewHolder(holder: GGGG, position: Int) {
}
override fun onBindViewHolder(holder: GGGG, position: Int, payloads: MutableList<Any>) {
val data = joFileList[position]
val context = holder.binding.root.context
if (payloads.isEmpty()) {
bindIcon(data, holder.binding.iv)
holder.binding.tvName.text = data.fName
val file = data.toFile()
if (file.isFile) {
holder.binding.tvInfo.text = data.timeE + " ${file.sizeF(context)}"
} else {
val count = file.list()?.size ?: 0
holder.binding.tvInfo.text = data.timeE + " ${count} items"
}
//================================是否显示选中按钮逻辑==================================
if (showSelect) {
val drawable = ContextCompat.getDrawable(context, R.drawable.bg_list_selector)
holder.binding.ivSelector.isSelected = data.isSelected
holder.binding.ivSelector.isVisible = true
holder.binding.ivSelector.setImageDrawable(drawable)
holder.binding.ivSelector.setOnClickListener {
data.isSelected = !data.isSelected
holder.binding.ivSelector.isSelected = data.isSelected
notifyItemChanged(position, "sdada")
allSelect.invoke(joFileList.all { it.isSelected })
}
} else {
val drawable = ContextCompat.getDrawable(context, R.mipmap.dsf_597)
holder.binding.ivSelector.setImageDrawable(drawable)
holder.binding.ivSelector.isVisible = file.isDirectory
holder.binding.ivSelector.setOnClickListener { }
}
//============================选中目录无法再进入子目录逻辑==============================
holder.binding.root.setOnClickListener {
if (!cannotNextFiles.contains(file) && file.isDirectory && canNext) nextPage(file)
}
if (cannotNextFiles.contains(file) && file.isDirectory) {
val color = ContextCompat.getColor(context, R.color.color_6e6e6e)
holder.binding.llItem.setBackgroundColor(color)
} else {
val color = ContextCompat.getColor(context, R.color.white)
holder.binding.llItem.setBackgroundColor(color)
}
} else {
holder.binding.root.setOnClickListener {
holder.binding.ivSelector.isSelected = data.isSelected
}
super.onBindViewHolder(holder, position, payloads)
}
}
private fun nextPage(file: File) {
currentDir = file
val files = currentDir.listFiles()
val data = files?.map { joListFileJo(it) } ?: listOf()
setData(data, isEmpty = { showEmpty?.invoke(it) })
}
fun getCurrentDir(): File {
return currentDir
}
fun notifyCurrentDir() {
val files = currentDir.listFiles()
// files?.sortByDescending { it.lastModified() }
val data = files?.map { joListFileJo(it) } ?: listOf()
setData(data, isEmpty = { showEmpty?.invoke(it) })
}
fun changeSelect(
isSelect: Boolean,
isAddCannotNext: Boolean = false,
isRemoveCannotNext: Boolean = false,
canNext: Boolean = true,
) {
showSelect = isSelect
if (isAddCannotNext) {
cannotNextFiles.addAll(getSelectData().map { it.toFile() })
}
if (isRemoveCannotNext) {
cannotNextFiles.clear()
}
this.canNext = canNext
notifyDataSetChanged()
}
/**
*@param 是否是根目录
*/
fun beforePage(): Boolean {
return if (currentDir.absoluteFile == Environment.getExternalStorageDirectory().absoluteFile) {
true
} else {
currentDir = currentDir.parentFile
val files = currentDir.listFiles()
val data = files?.map { joListFileJo(it) } ?: listOf()
setData(data, isEmpty = { showEmpty?.invoke(it) })
false
}
}
fun getOperationList(): ArrayList<File> {
return cannotNextFiles
}
}
\ No newline at end of file
......@@ -20,6 +20,8 @@ abstract class JoCommonJoAdapter<T : ViewHolder, E : JoFileJo>() : RecyclerView.
fun bindIcon(data: JoFileJo, iv: ImageView) {
val file = data.toFile()
when {
JoFileJo.isDir(file) -> iv.setImageResource(R.mipmap.koas_87985)
JoFileJo.isEmptyFile(file) -> iv.setImageResource(R.mipmap.koas_87985)
JoFileJo.isImage(file) or JoFileJo.isVideo(file) -> {
val radius = DipPxEx.dp2px(iv.context, R.dimen.dp_5)
val options =
......@@ -32,6 +34,7 @@ abstract class JoCommonJoAdapter<T : ViewHolder, E : JoFileJo>() : RecyclerView.
.apply(options)
.into(iv)
}
JoFileJo.isAudio(file) -> iv.setImageResource(R.mipmap.sfaad_598)
JoFileJo.isZip(file) -> iv.setImageResource(R.mipmap.sfz_6985)
JoFileJo.isApk(file) -> iv.setImageResource(R.mipmap.vzxv_59875)
......@@ -45,15 +48,17 @@ abstract class JoCommonJoAdapter<T : ViewHolder, E : JoFileJo>() : RecyclerView.
return joFileList.size
}
fun setData(data: List<E>) {
fun setData(data: List<E>, isEmpty: ((flag: Boolean) -> Unit)? = null) {
joFileList.clear()
joFileList.addAll(data)
notifyDataSetChanged()
isEmpty?.invoke(joFileList.isEmpty())
}
fun addData(data: List<E>) {
fun addData(data: List<E>, isEmpty: ((flag: Boolean) -> Unit)? = null) {
joFileList.addAll(data)
notifyDataSetChanged()
isEmpty?.invoke(joFileList.isEmpty())
}
fun clearData() {
......@@ -62,7 +67,7 @@ abstract class JoCommonJoAdapter<T : ViewHolder, E : JoFileJo>() : RecyclerView.
notifyDataSetChanged()
}
fun removeData(data: List<E>) {
fun removeData(data: List<E>, isEmpty: ((flag: Boolean) -> Unit)? = null) {
data.forEach {
val index = joFileList.indexOf(it)
if (index != -1) {
......@@ -70,6 +75,7 @@ abstract class JoCommonJoAdapter<T : ViewHolder, E : JoFileJo>() : RecyclerView.
notifyItemRemoved(index)
}
}
isEmpty?.invoke(joFileList.isEmpty())
}
fun getSelectData(): List<E> {
......
......@@ -12,6 +12,14 @@ abstract class JoFileJo(
) {
companion object {
fun isDir(file: File): Boolean {
return file.isDirectory
}
fun isEmptyFile(file: File): Boolean {
return file.isFile && file.length() == 0L
}
fun isImage(file: File): Boolean {
return file.name.contains(".jpg") or
file.name.contains(".png") or
......@@ -37,10 +45,6 @@ abstract class JoFileJo(
return file.length() >= 10 * 1024 * 1024
}
fun isEmptyFile(file: File): Boolean {
return file.length() >= 0
}
fun isZip(file: File): Boolean {
return file.name.contains(".zip")
......
package com.zxhy.simplefilesmanager.simpledialog
import android.content.Context
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.appcompat.app.AlertDialog
import com.zxhy.simplefilesmanager.R
import com.zxhy.simplefilesmanager.databinding.DialogFileNewRenameBinding
object SimpleFileDialog {
fun Context.showSimpleFileDialog(
name: String = "",
nameAction: (name: String) -> Unit
): AlertDialog {
val binding = DialogFileNewRenameBinding.inflate(LayoutInflater.from(this))
val dialog = AlertDialog.Builder(this).setView(binding.root).create()
dialog.setCanceledOnTouchOutside(false)
dialog.show()
//修改dialog的尺寸
val lp = dialog.window?.attributes
lp?.width = this.resources.getDimensionPixelOffset(R.dimen.dp_280)
lp?.height = ViewGroup.LayoutParams.WRAP_CONTENT
dialog.window?.attributes = lp
dialog.window?.setBackgroundDrawableResource(android.R.color.transparent)
if (name.isNotEmpty()) {
binding.edit.setText(name)
}
binding.tvSure.setOnClickListener {
val text = binding.edit.text.toString()
if (text.isEmpty() or text.isBlank()) {
return@setOnClickListener
}
nameAction.invoke(text)
dialog.dismiss()
}
binding.ivCancel.setOnClickListener {
dialog.dismiss()
}
return dialog
}
}
\ No newline at end of file
......@@ -41,6 +41,9 @@ class SimpleDupActivity : AppCompatActivity() {
} else {
loadData()
}
binding.flBack.setOnClickListener {
finish()
}
}
private fun initAdapter() {
......@@ -55,6 +58,7 @@ class SimpleDupActivity : AppCompatActivity() {
viewModel.deleteFiles(data.map { it.toFile() }) {
lifecycleScope.launch(Dispatchers.Main) {
adapter.removeData(data)
binding.tvDelete.visibility = View.GONE
}
}
}
......
......@@ -21,7 +21,7 @@ import com.zxhy.simplefilesmanager.databinding.ItemJoIJoSelectBinding
class SimpleDupAdapter(
private val allSelect: (allSelect: Boolean, count: Int) -> Unit
private val selectAction: (allSelect: Boolean, count: Int) -> Unit
) : RecyclerView.Adapter<SimpleDupAdapter.DDD>() {
private var dupList = arrayListOf<JoDupFileJo>()
......@@ -37,6 +37,7 @@ class SimpleDupAdapter(
override fun getItemCount(): Int = dupList.size
override fun onBindViewHolder(holder: DDD, position: Int) = Unit
@SuppressLint("SetTextI18n")
override fun onBindViewHolder(holder: DDD, position: Int, payloads: MutableList<Any>) {
super.onBindViewHolder(holder, position, payloads)
......@@ -45,14 +46,16 @@ class SimpleDupAdapter(
if (payloads.isEmpty()) {
holder.binding.ivSelector.isSelected = data.isSelected
holder.binding.tvItems.text = context.getString(R.string.d_items, data.dups.size)
val adapter = SSS(context) { flag ->
data.isSelected = flag
holder.binding.ivSelector.isSelected = data.isSelected
notifyItemChanged(position, "sadsf")
val allFlag = dupList.all { it.isSelected }
val count = getSubList().size
allSelect.invoke(allFlag, count)
selectAction.invoke(allFlag, count)
}
holder.binding.rv.adapter = adapter
adapter.setData(data.dups)
......@@ -62,6 +65,9 @@ class SimpleDupAdapter(
data.isSelected = it.isSelected
notifyItemChanged(position, "sfsaf")
adapter.toggleSelect(it.isSelected)
val count = getSubList().size
selectAction.invoke(count != 0, count)
}
} else {
holder.binding.ivSelector.isSelected = data.isSelected
......
package com.zxhy.simplefilesmanager.simplegrid
import android.content.Context
import android.content.Intent
import android.content.Intent.FLAG_ACTIVITY_SINGLE_TOP
import android.os.Bundle
......@@ -28,9 +29,11 @@ class SimpleGridActivity : AppCompatActivity() {
private lateinit var adapter: SimpleGridAdapter
private var tittle: String = ""
private val TAG = "SimpleGridActivity"
private lateinit var context: Context
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
context = this
binding = ActivitySimpleGridBinding.inflate(layoutInflater)
setContentView(binding.root)
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets ->
......@@ -68,6 +71,7 @@ class SimpleGridActivity : AppCompatActivity() {
viewModel.deleteFiles(files) {
lifecycleScope.launch(Dispatchers.Main) {
adapter.removeData(datas)
binding.tvItems.text = context.getString(R.string.select_d_items, 0)
}
}
}
......
package com.zxhy.simplefilesmanager.simplejoke
import android.content.Context
import android.text.format.Formatter
data class Disk(
val path: String = "", //路径
val name: String = "", //名称
val type: Int = 0,//类型 0U盘 1 data区域 2内置存储区域
val total: Long = 0, //总计数量
val used: Long = 0, //已用空间
val free: Long = 0, //空闲空间
) {
fun getTotalContent(context: Context): String {
return Formatter.formatFileSize(context, total)
}
fun getUsedContent(context: Context): String {
return Formatter.formatFileSize(context, used)
}
fun getFreeContent(context: Context): String {
return Formatter.formatFileSize(context, free)
}
companion object {
const val TYPE_U = 0 //u盘
const val TYPE_DATA = 1 //data区域
const val TYPE_EXTERNAL = 2 //外置存储
}
}
\ No newline at end of file
package com.zxhy.simplefilesmanager.simplejoke
import android.annotation.SuppressLint
import android.app.usage.StorageStatsManager
import android.content.Context
import android.os.Build
import android.os.storage.StorageManager
import android.os.storage.StorageVolume
import androidx.annotation.RequiresApi
import java.io.File
import java.lang.reflect.Field
import java.lang.reflect.Method
import java.util.UUID
/**
* 计算储存介质
*/
object DiskHelper {
@SuppressLint("ObsoleteSdkInt", "DiscouragedPrivateApi")
fun getMountInfoList(context: Context): List<Disk> {
val diskList = arrayListOf<Disk>()
val storageManager = context.getSystemService(Context.STORAGE_SERVICE) as StorageManager
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {//小于6.0
val getVolumeListMethod = StorageManager::class.java.getDeclaredMethod("getVolumeList")
val volumes = getVolumeListMethod.invoke(storageManager) as Array<StorageVolume>
for (volume in volumes) {
try {
val fileMethod = volume.javaClass.getDeclaredMethod("getPathFile")
val file = fileMethod.invoke(volume) as File
val path = file.path
val name = file.name
val total = file.totalSpace //总计
val used = total - file.freeSpace //空闲
val usable = file.usableSpace //可用
diskList.add(Disk(path, name, -1, total, used, usable))
} catch (e: Exception) {
e.printStackTrace()
}
}
} else {
val getVolumeMethod = StorageManager::class.java.getDeclaredMethod("getVolumes")
val volumes = getVolumeMethod.invoke(storageManager) as List<Any>
for (volume in volumes) {
try {
val getTypeField: Field = volume.javaClass.getField("type")
val type: Int = getTypeField.getInt(volume)
val fileMethod = volume.javaClass.getDeclaredMethod("getPath")
val f: File = fileMethod.invoke(volume) as File
val path = f.path
val name = f.name
val total =
if (type != Disk.TYPE_U && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val getFsUuid: Method = volume.javaClass.getDeclaredMethod("getFsUuid")
val fsUuid = getFsUuid.invoke(volume) as? String
getTotalSize(context, fsUuid)
} else {
f.totalSpace //总计
}
val used = total - f.usableSpace //空闲
val usable = f.usableSpace //空闲
val disk = Disk(path, name, type, total, used, usable)
diskList.add(disk)
} catch (e: Exception) {
e.printStackTrace()
}
}
}
return diskList
}
@RequiresApi(Build.VERSION_CODES.O)
fun getTotalSize(context: Context, fsUuid: String?): Long {
return try {
val id = if (fsUuid == null) StorageManager.UUID_DEFAULT else UUID.fromString(fsUuid)
val stats = context.getSystemService(StorageStatsManager::class.java)
stats.getTotalBytes(id)
} catch (e: Exception) {
e.printStackTrace()
-1
}
}
}
......@@ -40,9 +40,15 @@ class SimpleListActivity : AppCompatActivity() {
private var tittle: String = ""
private var listData = arrayListOf<JoListFileJo>()
private var canFilter = false
private var showFileRv = true
private var showImageRv = true
private var showVideoRv = true
private var imageEnable = true
private var fileEnable = true
private var videoEnable = true
private var fileSelectCount = 0
private var imageSelectCount = 0
private var videoSelectCount = 0
......@@ -69,6 +75,9 @@ class SimpleListActivity : AppCompatActivity() {
} else {
loadData()
}
binding.flBack.setOnClickListener {
finish()
}
}
private fun showPermissionSet() {
......@@ -164,6 +173,11 @@ class SimpleListActivity : AppCompatActivity() {
}
private fun showItemsCount() {
fileSelectCount = fileAdapter.getSelectData().size
imageSelectCount = imagerAdapter.getSelectData().size
videoSelectCount = videoAdapter.getSelectData().size
val count = fileSelectCount + imageSelectCount + videoSelectCount
binding.tvItems.text = this.getString(R.string.select_d_items, count)
if (count == 0) {
......@@ -184,11 +198,27 @@ class SimpleListActivity : AppCompatActivity() {
viewModel.deleteFiles(selectData.map { it.toFile() }) {
lifecycleScope.launch(Dispatchers.Main) {
listData.removeAll(selectData.toSet())
showItemsCount()
switchUi()
onDeleteRefresh()
}
}
}
}
}
private fun onDeleteRefresh() {
if (listData.isNotEmpty()) {
binding.tvItems.visibility = View.VISIBLE
if (canFilter) {
binding.flFilter.visibility = View.VISIBLE
}
binding.scrollContent.visibility = View.VISIBLE
switchUi(true)
showItemsCount()
} else {
binding.flEmpty.visibility = View.VISIBLE
binding.tvItems.visibility = View.INVISIBLE
binding.scrollContent.visibility = View.GONE
binding.tvDelete.visibility = View.GONE
}
}
......@@ -202,19 +232,31 @@ class SimpleListActivity : AppCompatActivity() {
binding.flFilter.visibility = View.VISIBLE
}
binding.scrollContent.visibility = View.VISIBLE
switchUi()
switchUi(true)
} else {
binding.tvItems.visibility = View.INVISIBLE
binding.flEmpty.visibility = View.VISIBLE
}
}
private fun switchUi() {
private fun switchUi(isFirst: Boolean = false) {
val imageFile = listData.filter { it.isImage() }
val videoFile = listData.filter { it.isVideo() }
val file = listData.filter { !it.isVideo() && !it.isImage() }
val fileList = arrayListOf<JoListFileJo>()
if (isFirst) {
showFileRv = file.isNotEmpty()
fileEnable = file.isNotEmpty()
showImageRv = imageFile.isNotEmpty()
imageEnable = imageFile.isNotEmpty()
showVideoRv = videoFile.isNotEmpty()
videoEnable = videoFile.isNotEmpty()
}
if (showImageRv) {
binding.tvImage.visibility = View.VISIBLE
binding.rvImage.visibility = View.VISIBLE
......@@ -260,8 +302,21 @@ class SimpleListActivity : AppCompatActivity() {
val width =
resources.getDimensionPixelSize(R.dimen.dp_94)
val height =
resources.getDimensionPixelSize(R.dimen.dp_124)
val popupWindow = PopupWindow(popupWindowView, width, height, true)
resources.getDimensionPixelSize(R.dimen.dp_40)
val margin =
resources.getDimensionPixelSize(R.dimen.dp_10)
var i = 0
if (fileEnable) {
i++
}
if (imageEnable) {
i++
}
if (videoEnable) {
i++
}
val popupWindow = PopupWindow(popupWindowView, width, height * i + margin, true)
popupWindow.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
popupWindow.isOutsideTouchable = true
popupWindow.isTouchable = true
......@@ -277,26 +332,64 @@ class SimpleListActivity : AppCompatActivity() {
popupBinding.tvVideo.isSelected = showVideoRv
popupBinding.ivVideo.isSelected = showVideoRv
if (fileEnable) {
popupBinding.llFile.visibility = View.VISIBLE
popupBinding.llFile.setOnClickListener {
if (!showImageRv && !showVideoRv && showFileRv) return@setOnClickListener
showFileRv = !showFileRv
popupBinding.tvFile.isSelected = showFileRv
popupBinding.ivFile.isSelected = showFileRv
if (!showFileRv) {
fileAdapter.toggleSelect(false)
}
popupWindow.dismiss()
switchUi()
showItemsCount()
}
} else {
popupBinding.llFile.visibility = View.GONE
}
if (imageEnable) {
popupBinding.llImage.visibility = View.VISIBLE
popupBinding.llImage.setOnClickListener {
if (!showFileRv && !showVideoRv && showImageRv) return@setOnClickListener
showImageRv = !showImageRv
popupBinding.tvImage.isSelected = showImageRv
popupBinding.ivImage.isSelected = showImageRv
if (!showImageRv) {
imagerAdapter.toggleSelect(false)
}
popupWindow.dismiss()
switchUi()
showItemsCount()
}
} else {
popupBinding.llImage.visibility = View.GONE
}
if (videoEnable) {
popupBinding.llVideo.visibility = View.VISIBLE
popupBinding.llVideo.setOnClickListener {
if (!showFileRv && !showImageRv && showVideoRv) return@setOnClickListener
showVideoRv = !showVideoRv
popupBinding.tvVideo.isSelected = showVideoRv
popupBinding.ivVideo.isSelected = showVideoRv
if (!showVideoRv) {
videoAdapter.toggleSelect(false)
}
popupWindow.dismiss()
switchUi()
showItemsCount()
}
} else {
popupBinding.llVideo.visibility = View.GONE
}
}
......
......@@ -8,7 +8,9 @@ import android.view.View
import android.view.ViewGroup
import com.zxhy.simplefilesmanager.R
import com.zxhy.simplefilesmanager.databinding.FragmentSimpleManagerBinding
import com.zxhy.simplefilesmanager.internalstorage.InternalStorageActivity
import com.zxhy.simplefilesmanager.simpledup.SimpleDupActivity
import com.zxhy.simplefilesmanager.simplejoke.DiskHelper
import com.zxhy.simplefilesmanager.simplelist.SimpleListActivity
class SimpleManagerFragment() : Fragment() {
......@@ -37,7 +39,16 @@ class SimpleManagerFragment() : Fragment() {
putExtra("Tittle", "LARGE FILE")
})
}
binding.tvManager.setOnClickListener {
startActivity(Intent(requireContext(), InternalStorageActivity::class.java))
}
val disk = DiskHelper.getMountInfoList(requireContext())[0]
binding.tvFree.text = disk.getFreeContent(requireContext())
binding.tvUsed.text = disk.getUsedContent(requireContext())
val percentF = (disk.used.toFloat() / disk.total.toFloat()) * 100f
val percent = String.format("%.0f", percentF)
binding.tvStore.text = "$percent%"
}
companion object {
......
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#FF333333" />
<corners android:radius="8dp" />
</shape>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#FFF5F5F5" />
<corners android:radius="8dp" />
</shape>
\ No newline at end of file
......@@ -32,18 +32,17 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="DUPLICATE PICTURE"
android:text="INTERNAL STORAGE"
android:textColor="#FF333333"
android:textSize="16sp"
android:textStyle="bold"
tools:ignore="HardcodedText" />
<FrameLayout
android:id="@+id/fl_all"
android:id="@+id/fl_all_write"
android:layout_width="65dp"
android:layout_height="match_parent"
android:layout_gravity="end"
android:visibility="gone">
android:layout_gravity="end">
<ImageView
android:id="@+id/iv_all"
......@@ -51,7 +50,18 @@
android:layout_height="24dp"
android:layout_gravity="center_vertical|end"
android:layout_marginEnd="20dp"
android:src="@drawable/bg_list_selector"
android:visibility="gone"
tools:ignore="ContentDescription" />
<ImageView
android:id="@+id/iv_write"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_gravity="center_vertical|end"
android:layout_marginEnd="20dp"
android:src="@mipmap/sldo_089"
android:visibility="gone"
tools:ignore="ContentDescription" />
</FrameLayout>
......@@ -59,16 +69,65 @@
</FrameLayout>
<LinearLayout
android:id="@+id/ll_content"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:orientation="vertical">
android:orientation="vertical"
android:visibility="gone">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
tools:ignore="NestedWeights">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
android:layout_height="match_parent"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
tools:ignore="NestedWeights" />
<ImageView
android:id="@+id/iv_new_file"
android:layout_width="36dp"
android:layout_height="36dp"
android:layout_gravity="end|bottom"
android:layout_marginEnd="28dp"
android:layout_marginBottom="50dp"
android:src="@mipmap/dkis_58959"
tools:ignore="ContentDescription" />
<LinearLayout
android:id="@+id/ll_empty"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="150dp"
android:orientation="vertical"
android:visibility="gone"
tools:ignore="UseCompoundDrawables">
<ImageView
android:layout_width="200dp"
android:layout_height="192dp"
android:layout_gravity="center_horizontal"
android:src="@mipmap/sda_887965"
tools:ignore="ContentDescription" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="12dp"
android:text="The folder is empty"
android:textColor="#FF333333"
android:textSize="14sp"
tools:ignore="HardcodedText" />
</LinearLayout>
</FrameLayout>
<LinearLayout
android:id="@+id/ll_operation"
......@@ -77,6 +136,7 @@
android:layout_marginHorizontal="20dp"
android:layout_marginVertical="10dp"
android:orientation="horizontal"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
......@@ -168,7 +228,7 @@
</LinearLayout>
<LinearLayout
android:id="@+id/ll_move"
android:id="@+id/ll_more"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
......@@ -176,7 +236,7 @@
tools:ignore="UseCompoundDrawables,UselessParent">
<ImageView
android:id="@+id/iv_copy"
android:id="@+id/iv_more"
android:layout_width="36dp"
android:layout_height="36dp"
android:layout_gravity="center_horizontal"
......@@ -188,7 +248,7 @@
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_margin="4dp"
android:text="Move"
android:text="More"
android:textColor="#FF333333"
android:textSize="12sp"
tools:ignore="HardcodedText,SmallSp" />
......@@ -198,6 +258,89 @@
</LinearLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/fl_confirm"
android:layout_width="match_parent"
android:layout_height="75dp"
android:visibility="gone">
<TextView
android:id="@+id/tv_cancel"
android:layout_width="140dp"
android:layout_height="40dp"
android:background="@drawable/bg_fff5f5f5_corners"
android:gravity="center"
android:text="Cancel"
android:textColor="#FF999999"
android:textSize="17sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/tv_confirm"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="HardcodedText" />
<TextView
android:id="@+id/tv_confirm"
android:layout_width="140dp"
android:layout_height="40dp"
android:background="@drawable/bg_ff333333_corners"
android:gravity="center"
android:text="Motion"
android:textColor="@color/white"
android:textSize="17sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/tv_cancel"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="HardcodedText" />
</androidx.constraintlayout.widget.ConstraintLayout>
</LinearLayout>
<LinearLayout
android:id="@+id/fl_permission_set"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="96dp"
android:orientation="vertical"
android:visibility="gone">
<ImageView
android:layout_width="140dp"
android:layout_height="172dp"
android:layout_gravity="center_horizontal"
android:src="@mipmap/jaos_7986"
tools:ignore="ContentDescription" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginHorizontal="66dp"
android:layout_marginTop="20dp"
android:gravity="center"
android:text="@string/permission_tip"
android:textColor="#FF666666"
android:textSize="16sp" />
<TextView
android:id="@+id/tv_set"
android:layout_width="290dp"
android:layout_height="40dp"
android:layout_gravity="center_horizontal|bottom"
android:layout_marginTop="28dp"
android:layout_marginBottom="5dp"
android:background="@drawable/bg_333333_corners"
android:gravity="center"
android:text="Set"
android:textColor="#FFFFFFFF"
android:textSize="17sp"
android:textStyle="bold"
tools:ignore="HardcodedText" />
</LinearLayout>
......
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="270dp"
android:layout_height="wrap_content"
android:layout_margin="5dp"
app:cardCornerRadius="12dp">
<ImageView
android:id="@+id/iv_cancel"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_gravity="end"
android:layout_margin="5dp"
android:src="@mipmap/sok_298"
tools:ignore="ContentDescription" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/tv_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="16dp"
android:text="New Folder"
android:textColor="#FF333333"
android:textSize="17sp"
android:textStyle="bold"
tools:ignore="HardcodedText" />
<EditText
android:id="@+id/edit"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="25dp"
android:layout_marginTop="40dp"
android:backgroundTint="#FFF5F5F5"
android:gravity="center_horizontal"
android:hint="Please enter a new name"
android:importantForAutofill="no"
android:singleLine="true"
android:textColor="#FF333333"
android:textSize="14sp"
tools:ignore="HardcodedText,TextFields" />
<TextView
android:id="@+id/tv_sure"
android:layout_width="230dp"
android:layout_height="40dp"
android:layout_gravity="center_horizontal"
android:layout_marginVertical="20dp"
android:background="@drawable/bg_ff333333_corners_8"
android:gravity="center"
android:text="Sure"
android:textColor="#FFFFFFFF"
android:textSize="17sp"
tools:ignore="HardcodedText" />
</LinearLayout>
</androidx.cardview.widget.CardView>
\ No newline at end of file
......@@ -37,7 +37,6 @@
android:layout_marginTop="32dp"
android:background="@mipmap/sdf_7985"
android:gravity="center"
android:text="20%"
android:textColor="#FFFFFF"
android:textSize="60sp"
android:textStyle="bold"
......@@ -109,7 +108,7 @@
tools:ignore="HardcodedText" />
<TextView
android:id="@+id/tv_use"
android:id="@+id/tv_used"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
......@@ -123,15 +122,16 @@
<TextView
android:id="@+id/tv_manager"
android:layout_width="190dp"
android:layout_width="0dp"
android:layout_height="40dp"
android:layout_marginHorizontal="35dp"
android:layout_marginTop="29dp"
android:background="@drawable/bg_333333_corners"
android:gravity="center"
android:text="File Manager"
android:textColor="#FFFFFF"
app:layout_constraintEnd_toEndOf="@id/tv_store"
app:layout_constraintStart_toStartOf="@id/tv_store"
app:layout_constraintEnd_toStartOf="@id/ll_used"
app:layout_constraintStart_toEndOf="@id/ll_free"
app:layout_constraintTop_toBottomOf="@id/tv_store"
tools:ignore="HardcodedText" />
......
......@@ -9,6 +9,7 @@
app:cardCornerRadius="8dp">
<TextView
android:id="@+id/tv_items"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="12dp"
......
......@@ -8,6 +8,7 @@
android:orientation="vertical">
<LinearLayout
android:id="@+id/ll_item"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
......@@ -64,7 +65,6 @@
android:layout_height="1dp"
android:layout_marginStart="40dp"
android:layout_marginTop="13dp"
android:layout_marginEnd="20dp"
android:background="#FFF4F4F4" />
</LinearLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="5dp"
app:cardCornerRadius="4dp">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout
android:id="@+id/ll_rename"
android:layout_width="98dp"
android:layout_height="40dp"
android:clickable="true"
android:focusable="true"
android:orientation="horizontal"
tools:ignore="UseCompoundDrawables">
<TextView
android:id="@+id/tv_rename"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginStart="12dp"
android:layout_weight="1"
android:text="Rename"
android:textColor="@drawable/textcolor_selector"
android:textSize="14sp"
tools:ignore="HardcodedText" />
<ImageView
android:id="@+id/iv_rename"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_gravity="center_vertical"
android:layout_marginEnd="3dp"
android:src="@drawable/bg_list_selector"
tools:ignore="ContentDescription" />
</LinearLayout>
<LinearLayout
android:id="@+id/ll_delete"
android:layout_width="98dp"
android:layout_height="40dp"
android:clickable="true"
android:focusable="true"
android:orientation="horizontal"
tools:ignore="UseCompoundDrawables">
<TextView
android:id="@+id/tv_delete"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginStart="12dp"
android:layout_weight="1"
android:text="Delete"
android:textColor="@drawable/textcolor_selector"
android:textSize="14sp"
tools:ignore="HardcodedText" />
<ImageView
android:id="@+id/iv_delete"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_gravity="center_vertical"
android:layout_marginEnd="3dp"
android:src="@drawable/bg_list_selector"
tools:ignore="ContentDescription" />
</LinearLayout>
</LinearLayout>
</androidx.cardview.widget.CardView>
\ No newline at end of file
app/src/main/res/mipmap-hdpi/dsf_597.png

761 Bytes | W: | H:

app/src/main/res/mipmap-hdpi/dsf_597.png

678 Bytes | W: | H:

app/src/main/res/mipmap-hdpi/dsf_597.png
app/src/main/res/mipmap-hdpi/dsf_597.png
app/src/main/res/mipmap-hdpi/dsf_597.png
app/src/main/res/mipmap-hdpi/dsf_597.png
  • 2-up
  • Swipe
  • Onion skin
app/src/main/res/mipmap-mdpi/dsf_597.png

437 Bytes | W: | H:

app/src/main/res/mipmap-mdpi/dsf_597.png

402 Bytes | W: | H:

app/src/main/res/mipmap-mdpi/dsf_597.png
app/src/main/res/mipmap-mdpi/dsf_597.png
app/src/main/res/mipmap-mdpi/dsf_597.png
app/src/main/res/mipmap-mdpi/dsf_597.png
  • 2-up
  • Swipe
  • Onion skin
......@@ -2,4 +2,5 @@
<resources>
<color name="black">#FF000000</color>
<color name="white">#FFFFFFFF</color>
<color name="color_6e6e6e">#6E6E6E</color>
</resources>
\ No newline at end of file
......@@ -5,4 +5,8 @@
<dimen name="dp_5">5dp</dimen>
<dimen name="dp_94">94dp</dimen>
<dimen name="dp_124">124dp</dimen>
<dimen name="dp_280">280dp</dimen>
<dimen name="dp_108">108dp</dimen>
<dimen name="dp_40">40dp</dimen>
<dimen name="dp_10">10dp</dimen>
</resources>
\ No newline at end of file
......@@ -3,5 +3,6 @@
<!-- TODO: Remove or change this placeholder text -->
<string name="hello_blank_fragment">Hello blank fragment</string>
<string name="select_d_items">Select %d items</string>
<string name="d_items">%d items</string>
<string name="permission_tip">There are no permissions We need to get permission to read all files.</string>
</resources>
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment