Commit 91b88b99 authored by wanglei's avatar wanglei Committed by wanglei

feat:完善代码

parents 24e4a103 55189506
......@@ -50,4 +50,6 @@ dependencies {
testImplementation(libs.junit)
androidTestImplementation(libs.androidx.junit)
androidTestImplementation(libs.androidx.espresso.core)
implementation(libs.androidx.navigation.fragment.ktx)
implementation(libs.androidx.navigation.ui.ktx)
}
\ No newline at end of file
......@@ -2,22 +2,35 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission
android:name="android.permission.MANAGE_EXTERNAL_STORAGE"
tools:ignore="ScopedStorage" />
<application
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/zzzz_8596325"
android:label="@string/app_name"
android:requestLegacyExternalStorage="true"
android:requestRawExternalStorageAccess="true"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.FastFileManagerPro"
tools:targetApi="31">
<activity
android:name=".kokoInternalstorage.KoInternalkoActivity"
android:exported="false" />
<activity
android:name=".kokodup.KoDupFilekoActivity"
android:exported="false" />
<activity
android:name=".kokolistfile.KoListFilekoActivity"
android:exported="false" />
android:exported="false"
android:screenOrientation="portrait"
tools:ignore="LockedOrientationActivity" />
<activity
android:name=".gridfile.KoGridFilekoActivity"
android:exported="false" />
......
......@@ -29,11 +29,12 @@ class KokoLaunchActivity : AppCompatActivity() {
}
lifecycleScope.launch(Dispatchers.Main) {
while (binding.ProgressBar.progress!=100){
while (binding.ProgressBar.progress != 100) {
binding.ProgressBar.progress += 2
delay(50)
}
startActivity(Intent(this@KokoLaunchActivity, MainActivity::class.java))
finish()
}
}
}
\ No newline at end of file
......@@ -9,6 +9,8 @@ import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import androidx.navigation.findNavController
import androidx.navigation.fragment.NavHostFragment
import com.google.android.material.navigation.NavigationBarView
import com.zxhy.fastfilemanagerpro.databinding.ActivityMainBinding
......@@ -24,9 +26,27 @@ class MainActivity : AppCompatActivity() {
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
insets
}
//关键去除itemIconTint影响
binding.bnv.itemIconTintList = null
binding.bnv.setItemIconSizeRes(R.dimen.dp_24)
val navHostFragment =
supportFragmentManager.findFragmentById(R.id.container) as NavHostFragment
navHostFragment.navController.addOnDestinationChangedListener { controller, destination, arguments ->
when (destination.id) {
R.id.koManagerkoFragment -> {
binding.bnv.selectedItemId = R.id.nav_manager
}
R.id.koHomekoFragment -> {
binding.bnv.selectedItemId = R.id.nav_home
}
}
}
binding.bnv.setOnItemSelectedListener(object : AdapterView.OnItemSelectedListener,
NavigationBarView.OnItemSelectedListener {
NavigationBarView.OnItemSelectedListener {
override fun onItemSelected(
parent: AdapterView<*>?,
view: View?,
......@@ -43,10 +63,15 @@ class MainActivity : AppCompatActivity() {
when (item.itemId) {
R.id.nav_manager -> {
runCatching {
findNavController(R.id.container).navigate(R.id.action_koHomekoFragment_to_koManagerkoFragment)
}
}
R.id.nav_home -> {
runCatching {
findNavController(R.id.container).navigate(R.id.action_koManagerkoFragment_to_koHomekoFragment)
}
}
}
return true
......
......@@ -21,4 +21,9 @@ class KoGridFilekoActivity : AppCompatActivity() {
insets
}
}
companion object {
const val IMAGE_FILE = "Image file"
const val VIDEO_FILE = "Video file"
}
}
\ No newline at end of file
package com.zxhy.fastfilemanagerpro.kokoInternalstorage
import android.os.Bundle
import androidx.activity.enableEdgeToEdge
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import com.zxhy.fastfilemanagerpro.R
class KoInternalkoActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
setContentView(R.layout.activity_ko_internalko)
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
}
}
}
\ No newline at end of file
package com.zxhy.fastfilemanagerpro.kokodata
import android.content.Context
import android.text.format.Formatter
import java.io.File
import java.text.SimpleDateFormat
import java.util.Locale
data class KoFileDatako(
val name: String,
var isSelect: Boolean
)
\ No newline at end of file
var name: String,
var path: String,
val timeE: String = "",
var isSelect: Boolean = false,
val sizeF: String = ""
) {
companion object {
fun KoFileDatako.toFile(): File {
return File(path)
}
fun File.koFileDatako(context: Context): KoFileDatako {
return KoFileDatako(
name = name,
timeE = timeE(),
sizeF = sizeF(context),
path = absolutePath
)
}
fun File.timeE(): String {
return SimpleDateFormat("MMM dd, yyyy", Locale.ENGLISH).format(lastModified())
}
fun File.sizeF(context: Context): String {
return Formatter.formatFileSize(context, length())
}
}
}
\ No newline at end of file
package com.zxhy.fastfilemanagerpro.kokodup
import android.content.ClipData.Item
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
......@@ -9,7 +8,7 @@ import com.zxhy.fastfilemanagerpro.R
import com.zxhy.fastfilemanagerpro.databinding.ItemKokoDupFileBinding
import com.zxhy.fastfilemanagerpro.databinding.ItemKokoDupImageBinding
import com.zxhy.fastfilemanagerpro.kokoadapter.CommonAdapter
import com.zxhy.fastfilemanagerpro.kokotools.inflate
import com.zxhy.fastfilemanagerpro.kokotools.XmlEx.inflate
class KoDupFilekoAdapter : RecyclerView.Adapter<KoDupFilekoAdapter.KoDupFilekoViewHolder>() {
......
package com.zxhy.fastfilemanagerpro.kokohome
import android.content.Context
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.navigation.fragment.findNavController
import com.zxhy.fastfilemanagerpro.R
import com.zxhy.fastfilemanagerpro.databinding.FragmentKoHomekoBinding
import com.zxhy.fastfilemanagerpro.kokolistfile.KoListFilekoActivity.Companion.EMPTY_FILE
import com.zxhy.fastfilemanagerpro.kokolistfile.KoListFilekoActivity.Companion.LARGE_FILE
import com.zxhy.fastfilemanagerpro.kokotools.DiskHelper
class KoHomekoFragment : Fragment() {
private lateinit var binding: FragmentKoHomekoBinding
private lateinit var context: Context
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
}
......@@ -24,4 +30,32 @@ class KoHomekoFragment : Fragment() {
return root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
context = requireContext()
val disk = DiskHelper.getMountInfoList(context)[0]
binding.tvFree.text = disk.getFreeContent(context)
binding.tvUsed.text = disk.getUsedContent(context)
binding.tvScanEmpty.setOnClickListener {
val bundle = Bundle().apply {
putString("Tittle", EMPTY_FILE)
}
findNavController().navigate(R.id.koListFilekoActivity, bundle)
}
binding.tvScanLarge.setOnClickListener {
val bundle = Bundle().apply {
putString("Tittle", LARGE_FILE)
}
findNavController().navigate(R.id.koListFilekoActivity, bundle)
}
binding.tvScanDupImage.setOnClickListener {
}
binding.tvScanDupFiles.setOnClickListener {
}
}
}
\ No newline at end of file
package com.zxhy.fastfilemanagerpro.kokolistfile
import android.annotation.SuppressLint
import android.content.Context
import android.os.Bundle
import android.view.View
import androidx.activity.enableEdgeToEdge
import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import androidx.lifecycle.lifecycleScope
import com.zxhy.fastfilemanagerpro.R
import com.zxhy.fastfilemanagerpro.databinding.ActivityKoListFilekoBinding
import com.zxhy.fastfilemanagerpro.kokodata.KoFileDatako
import com.zxhy.fastfilemanagerpro.kokodata.KoFileDatako.Companion.toFile
import com.zxhy.fastfilemanagerpro.kokotools.ActivityLauncher
import com.zxhy.fastfilemanagerpro.kokotools.permission.PermissionCheck.storePermissionCheck
import com.zxhy.fastfilemanagerpro.kokotools.permission.StorePermissionEx.requestStoreFollow
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
class KoListFilekoActivity : AppCompatActivity() {
private val viewModel: KoListFilekoViewHolder by viewModels()
private val viewModel: KoListFilekoViewModel by viewModels()
private lateinit var binding: ActivityKoListFilekoBinding
private lateinit var activityLauncher: ActivityLauncher
private lateinit var adapter: KoListFilekoAdapter
private var tittle = ""
private lateinit var context: Context
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
setContentView(R.layout.activity_ko_list_fileko)
context = this
activityLauncher = ActivityLauncher(this)
binding = ActivityKoListFilekoBinding.inflate(layoutInflater)
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
}
tittle = intent.extras?.getString("Tittle") ?: ""
binding.tvTittle.text = tittle
adapter = KoListFilekoAdapter {
binding.ivAllSelector.isSelected = it
enableDelete()
}
binding.rv.adapter = adapter
binding.ivAllSelector.setOnClickListener {
it.isSelected = !it.isSelected
adapter.toggleSelect(it.isSelected)
enableDelete()
}
binding.ivBack.setOnClickListener {
finish()
}
if (storePermissionCheck()) {
showPermissionSet(false)
loadListFile()
} else {
showPermissionSet(true)
}
}
//region 通用ui操作
fun showOperationResult() = lifecycleScope.launch(Dispatchers.Main) {
binding.llResult.visibility = View.VISIBLE
delay(500)
binding.llResult.visibility = View.GONE
}
fun showPermissionSet(show: Boolean) {
if (show) {
binding.clContent.visibility = View.GONE
binding.clPermissionSet.visibility = View.VISIBLE
binding.tvSet.setOnClickListener {
requestStoreFollow(activityLauncher, disAgreeAction = {
showPermissionSet(true)
}, agreeAction = {
showPermissionSet(false)
loadListFile()
})
}
} else {
binding.clContent.visibility = View.VISIBLE
binding.clPermissionSet.visibility = View.GONE
}
}
private fun loadListFile() {
when (tittle) {
EMPTY_FILE -> viewModel.loadEmptyFile(context, ::onDoList, ::onFinishList)
LARGE_FILE -> viewModel.loadLargeFile(context, ::onDoList, ::onFinishList)
AUDIO_FILE -> viewModel.loadAudioFile(context, ::onDoList, ::onFinishList)
LOG_FILE -> viewModel.loadLogFile(context, ::onDoList, ::onFinishList)
ZIP_FILE -> viewModel.loadZipFile(context, ::onDoList, ::onFinishList)
APK_FILE -> viewModel.loadApkFile(context, ::onDoList, ::onFinishList)
DOCUMENTS_FILE -> viewModel.loadDocumentsFile(context, ::onDoList, ::onFinishList)
}
}
fun enableDelete() {
val enable = adapter.getSelectData().isNotEmpty()
binding.tvDelete.isEnabled = enable
if (enable) {
binding.tvDelete.background =
ContextCompat.getDrawable(context, R.drawable.bg_ffff6767_corners)
binding.tvDelete.setTextColor(ContextCompat.getColor(context, R.color.white))
binding.tvDelete.setOnClickListener {
deleteFiles()
}
} else {
binding.tvDelete.background =
ContextCompat.getDrawable(context, R.drawable.bg_fff4f4f4_corners)
binding.tvDelete.setTextColor(ContextCompat.getColor(context, R.color.color_999999))
binding.tvDelete.setOnClickListener {}
}
}
private fun showEmptyList() {
if (adapter.itemCount == 0) {
binding.clEmpty.visibility = View.VISIBLE
binding.clShowContent.visibility = View.GONE
binding.llAll.visibility = View.GONE
} else {
binding.clEmpty.visibility = View.GONE
binding.clShowContent.visibility = View.VISIBLE
binding.llAll.visibility = View.VISIBLE
}
}
private fun onDoList(list: List<KoFileDatako>) = lifecycleScope.launch(Dispatchers.Main) {
adapter.setData(list)
}
@SuppressLint("SetTextI18n")
private fun onFinishList(list: List<KoFileDatako>) = lifecycleScope.launch(Dispatchers.Main) {
adapter.setData(list)
showEmptyList()
enableDelete()
binding.tvTittle.text = "total:${adapter.itemCount} items"
}
private fun deleteFiles() {
val selectData = adapter.getSelectData()
val files = selectData.map { it.toFile() }
viewModel.deleteFiles(files) {
lifecycleScope.launch(Dispatchers.Main) {
showOperationResult()
adapter.removeData(selectData)
showEmptyList()
enableDelete()
}
}
}
//endregion
companion object {
const val EMPTY_FILE = "Empty file"
const val LARGE_FILE = "Large file"
const val AUDIO_FILE = "Audio file"
const val LOG_FILE = "Log file"
const val ZIP_FILE = "Zip"
const val APK_FILE = "APK"
const val DOCUMENTS_FILE = "documents file"
}
}
\ No newline at end of file
package com.zxhy.fastfilemanagerpro.kokolistfile
import android.annotation.SuppressLint
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView.ViewHolder
import com.zxhy.fastfilemanagerpro.R
import com.zxhy.fastfilemanagerpro.databinding.ActivityKoListFilekoBinding
import com.zxhy.fastfilemanagerpro.databinding.ItemKokoListFileBinding
import com.zxhy.fastfilemanagerpro.kokoadapter.CommonAdapter
import com.zxhy.fastfilemanagerpro.kokotools.XmlEx.inflate
class KoListFilekoAdapter(
private val allSelect: (flag: Boolean) -> Unit
) : CommonAdapter<KoListFilekoAdapter.ItemKokoListFileViewHolder>() {
inner class ItemKokoListFileViewHolder(view: View) : ViewHolder(view) {
val binding = ItemKokoListFileBinding.bind(view)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemKokoListFileViewHolder {
return ItemKokoListFileViewHolder(R.layout.item_koko_list_file.inflate(parent))
}
override fun onBindViewHolder(holder: ItemKokoListFileViewHolder, position: Int) {
}
@SuppressLint("SetTextI18n")
override fun onBindViewHolder(
holder: ItemKokoListFileViewHolder,
position: Int,
payloads: MutableList<Any>
) {
val context = holder.binding.root.context
val data = fileList[position]
if (payloads.isEmpty()) {
holder.binding.apply {
tvName.text = data.name
tvInfo.text = "${data.timeE} ${data.sizeF}"
ivSelector.isSelected = data.isSelect
ivSelector.setOnClickListener {
data.isSelect = !data.isSelect
notifyItemChanged(position, "局部刷洗")
allSelect.invoke(fileList.all { it.isSelect })
}
}
} else {
holder.binding.apply {
ivSelector.isSelected = data.isSelect
}
super.onBindViewHolder(holder, position, payloads)
}
}
}
\ No newline at end of file
package com.zxhy.fastfilemanagerpro.kokolistfile
import android.content.Context
import android.os.Environment
import androidx.lifecycle.ViewModel
import androidx.recyclerview.widget.RecyclerView.ViewHolder
import androidx.lifecycle.viewModelScope
import com.zxhy.fastfilemanagerpro.kokodata.KoFileDatako
import com.zxhy.fastfilemanagerpro.kokodata.KoFileDatako.Companion.koFileDatako
import com.zxhy.fastfilemanagerpro.kokotools.HelperTraverse.linkedLisTraverseFolder
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.launch
import java.io.File
import kotlin.reflect.KFunction1
class KoListFilekoViewModel : ViewModel() {
fun isEmptyFilter(file: File): Boolean {
return file.length() == 0L
}
fun isLargeFilter(file: File): Boolean {
return file.length() >= 10 * 1024 * 1024L
}
fun isAudioFilter(file: File): Boolean {
return file.length() >= 10 * 1024 * 1024L
}
fun isLogFilter(file: File): Boolean {
return file.length() >= 10 * 1024 * 1024L
}
fun isZipFilter(file: File): Boolean {
return file.length() >= 10 * 1024 * 1024L
}
fun isApkFilter(file: File): Boolean {
return file.length() >= 10 * 1024 * 1024L
}
fun isDocumentsFilter(file: File): Boolean {
return file.length() >= 10 * 1024 * 1024L
}
fun loadEmptyFile(
context: Context,
onDo: (list: List<KoFileDatako>) -> Unit,
onFinish: (list: List<KoFileDatako>) -> Unit
) {
loadFile(context, filter = (::isEmptyFilter),
onDo = { list ->
onDo.invoke(list)
},
onFinish = { list ->
onFinish.invoke(list)
}
)
}
fun loadLargeFile(
context: Context,
onDo: (list: List<KoFileDatako>) -> Unit,
onFinish: (list: List<KoFileDatako>) -> Unit
) {
loadFile(context, filter = (::isLargeFilter),
onDo = { list ->
onDo.invoke(list)
},
onFinish = { list ->
onFinish.invoke(list)
}
)
}
fun loadAudioFile(
context: Context,
onDo: (list: List<KoFileDatako>) -> Unit,
onFinish: (list: List<KoFileDatako>) -> Unit
) {
loadFile(context, filter = (::isAudioFilter),
onDo = { list ->
onDo.invoke(list)
},
onFinish = { list ->
onFinish.invoke(list)
}
)
}
fun loadLogFile(
context: Context,
onDo: (list: List<KoFileDatako>) -> Unit,
onFinish: (list: List<KoFileDatako>) -> Unit
) {
loadFile(context, filter = (::isLogFilter),
onDo = { list ->
onDo.invoke(list)
},
onFinish = { list ->
onFinish.invoke(list)
}
)
}
fun loadZipFile(
context: Context,
onDo: (list: List<KoFileDatako>) -> Unit,
onFinish: (list: List<KoFileDatako>) -> Unit
) {
loadFile(context, filter = (::isZipFilter),
onDo = { list ->
onDo.invoke(list)
},
onFinish = { list ->
onFinish.invoke(list)
}
)
}
fun loadApkFile(
context: Context,
onDo: (list: List<KoFileDatako>) -> Unit,
onFinish: (list: List<KoFileDatako>) -> Unit
) {
loadFile(context, filter = (::isApkFilter),
onDo = { list ->
onDo.invoke(list)
},
onFinish = { list ->
onFinish.invoke(list)
}
)
}
fun loadDocumentsFile(
context: Context,
onDo: (list: List<KoFileDatako>) -> Unit,
onFinish: (list: List<KoFileDatako>) -> Unit
) {
loadFile(context, filter = (::isDocumentsFilter),
onDo = { list ->
onDo.invoke(list)
},
onFinish = { list ->
onFinish.invoke(list)
}
)
}
private fun loadFile(
context: Context,
filter: (file: File) -> Boolean,
onDo: (list: List<KoFileDatako>) -> Unit,
onFinish: (list: List<KoFileDatako>) -> Unit
) {
viewModelScope.launch(Dispatchers.IO) {
val root = Environment.getExternalStorageDirectory()
val resultList = arrayListOf<KoFileDatako>()
var firstSend = false
linkedLisTraverseFolder(root) { file ->
if (filter(file)) {
resultList.add(file.koFileDatako(context))
if (resultList.size == 20 && !firstSend) {
onDo.invoke(resultList)
resultList.clear()
firstSend = true
}
}
}
onFinish.invoke(resultList)
}
}
fun deleteFiles(files: List<File>, finishAction: () -> Unit) =
viewModelScope.launch(Dispatchers.IO) {
runCatching {
files.forEach {
if (it.exists()) {
it.delete()
}
}
}
finishAction.invoke()
}
class KoListFilekoViewHolder : ViewModel() {
}
\ No newline at end of file
......@@ -6,9 +6,12 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.zxhy.fastfilemanagerpro.R
import com.zxhy.fastfilemanagerpro.databinding.FragmentKoManagerkoBinding
class KoManagerkoFragment : Fragment() {
private lateinit var binding: FragmentKoManagerkoBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
}
......@@ -17,7 +20,17 @@ class KoManagerkoFragment : Fragment() {
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment_ko_managerko, container, false)
val root = inflater.inflate(R.layout.fragment_ko_managerko, container, false)
binding = FragmentKoManagerkoBinding.bind(root)
return root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
}
companion object{
}
}
\ No newline at end of file
package com.zxhy.fastfilemanagerpro.kokotools
import android.content.Intent
import androidx.activity.result.ActivityResult
import androidx.activity.result.ActivityResultCallback
import androidx.activity.result.ActivityResultCaller
import androidx.activity.result.contract.ActivityResultContracts
class ActivityLauncher(activityResultCaller: ActivityResultCaller) {
//region 权限
private var permissionCallback: ActivityResultCallback<Map<String, Boolean>>? = null
private val permissionLauncher =
activityResultCaller.registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) { result: Map<String, Boolean> ->
permissionCallback?.onActivityResult(result)
}
fun launch(
permissionArray: Array<String>,
permissionCallback: ActivityResultCallback<Map<String, Boolean>>?
) {
this.permissionCallback = permissionCallback
permissionLauncher.launch(permissionArray)
}
//endregion
//region intent跳转
private var activityResultCallback: ActivityResultCallback<ActivityResult>? = null
private val intentLauncher =
activityResultCaller.registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { activityResult: ActivityResult ->
activityResultCallback?.onActivityResult(activityResult)
}
/**
* it.resultCode == Activity.RESULT_OK
*/
fun launch(
intent: Intent,
activityResultCallback: ActivityResultCallback<ActivityResult>? = null
) {
this.activityResultCallback = activityResultCallback
intentLauncher.launch(intent)
}
//endregion
}
\ No newline at end of file
package com.zxhy.fastfilemanagerpro.kokotools
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.fastfilemanagerpro.kokotools
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 {
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
}
}
}
package com.zxhy.fastfilemanagerpro.kokotools
import java.io.File
import java.util.LinkedList
object HelperTraverse {
//LinkedLis方式遍历
fun linkedLisTraverseFolder(folder: File, onDo: ((file: File) -> Unit)?) {
//添加第一层文件到链表
val linkList = LinkedList<File>()
val fileList = folder.listFiles()
fileList?.forEach {
if (it.isDirectory) {
linkList.add(it)
} else {
onDo?.invoke(it)
}
}
//链表取文件
var tempFile: File
while (!linkList.isEmpty()) {
tempFile = linkList.removeFirst()
val tempFileList = tempFile.listFiles()
tempFileList?.forEach {
if (it.isDirectory) {
linkList.add(it)
} else {
onDo?.invoke(it)
}
}
}
}
}
\ No newline at end of file
package com.zxhy.fastfilemanagerpro.kokotools
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.os.Build
import android.provider.Settings
import androidx.annotation.RequiresApi
/**
* 访问所有文件权限设置界面
* https://blog.csdn.net/qq_17766199/article/details/115351949
*/
object IntentEx{
@RequiresApi(Build.VERSION_CODES.R)
fun settingManageExternalStorage(uri: Uri? = null): Intent {
val intent = Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION, uri)
// intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
return intent
}
//权限设置界面
fun goToPermissionSettings(context: Context, activityLauncher: ActivityLauncher) {
val intent = appSettingsIntent(context.packageName)
activityLauncher.launch(intent)
}
/**
* 应用设置页面意图
*/
fun appSettingsIntent(packageName: String): Intent {
return Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
.setData(Uri.fromParts("package", packageName, null))
}
}
......@@ -4,12 +4,16 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
/**
* 解析xml布局
*
* @param parent 父布局
* @param attachToRoot 是否依附到父布局
*/
fun Int.inflate(parent: ViewGroup, attachToRoot: Boolean = false): View {
return LayoutInflater.from(parent.context).inflate(this, parent, attachToRoot)
object XmlEx {
/**
* 解析xml布局
*
* @param parent 父布局
* @param attachToRoot 是否依附到父布局
*/
fun Int.inflate(parent: ViewGroup, attachToRoot: Boolean = false): View {
return LayoutInflater.from(parent.context).inflate(this, parent, attachToRoot)
}
}
package com.zxhy.fastfilemanagerpro.kokotools.permission
import android.Manifest
import android.content.Context
import android.content.pm.PackageManager
import android.os.Build
import android.os.Environment
import androidx.core.content.ContextCompat
object PermissionCheck {
//Android 13以后,读写权限无法弹出系统弹窗,分化为Manifest.permission.READ_MEDIA_*权限
//Android 11以后,Manifest.permission.READ_EXTERNAL_STORAGE 授予后还需授予 额外储存管理权限 ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION
//Android 11以下使用Manifest.permission.READ_EXTERNAL_STORAGE
fun Context.storePermissionCheck(): Boolean {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {//Android 13以后
return Environment.isExternalStorageManager()
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {//Android 11以后
val flag1 = Environment.isExternalStorageManager()
val flag2 = arrayOf(
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE
).all {
ContextCompat.checkSelfPermission(this, it) == PackageManager.PERMISSION_GRANTED
}
return flag1 or flag2
} else { //Android 11以下,Android 6以上
return arrayOf(
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE
).all {
ContextCompat.checkSelfPermission(this, it) == PackageManager.PERMISSION_GRANTED
}
}
}
}
package com.zxhy.fastfilemanagerpro.kokotools.permission
import android.content.Context
import android.content.pm.PackageManager
import androidx.core.content.ContextCompat
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.zxhy.fastfilemanagerpro.kokotools.ActivityLauncher
import com.zxhy.fastfilemanagerpro.kokotools.IntentEx.goToPermissionSettings
object PermissionEx {
fun requestPermission(
context: Context,
activityLauncher: ActivityLauncher,
permission: Array<String>,
title: String = "title",
message: String = "message",
agreeAction: (() -> Unit)? = null,
disAgreeAction: (() -> Unit)? = null
) {
val permissionFlag =
permission.all {
ContextCompat.checkSelfPermission(context, it) == PackageManager.PERMISSION_GRANTED
}
if (permissionFlag) {
agreeAction?.invoke()
} else {
activityLauncher.launch(permission) { callback ->
val isGrantAll = callback.values.all { it }
if (!isGrantAll) {
context.alert(title = title, message = message,
positiveButton = {
goToPermissionSettings(context, activityLauncher)
},
negativeButton = {
disAgreeAction?.invoke()
})
} else {
agreeAction?.invoke()
}
}
}
}
fun Context.alert(
title: String = "",
message: String,
positiveButtonText: String = "",
positiveButton: (() -> Unit)? = null,
negativeButtonText: String = "",
negativeButton: (() -> Unit)? = null,
) {
val builder = MaterialAlertDialogBuilder(this)
builder.setNegativeButton(negativeButtonText) { dialog, _ ->
dialog.dismiss()
negativeButton?.invoke()
}
builder.setPositiveButton(positiveButtonText) { dialog, _ ->
dialog.dismiss()
positiveButton?.invoke()
}
val dialog = builder.create()
dialog.setCanceledOnTouchOutside(false)
dialog.setTitle(title)
dialog.setMessage(message)
}
}
package com.zxhy.fastfilemanagerpro.kokotools.permission
import com.zxhy.fastfilemanagerpro.kokotools.permission.PermissionEx.requestPermission
import android.Manifest
import android.annotation.SuppressLint
import android.content.Context
import android.net.Uri
import android.os.Build
import android.os.Environment
import com.zxhy.fastfilemanagerpro.kokotools.ActivityLauncher
import com.zxhy.fastfilemanagerpro.kokotools.IntentEx.settingManageExternalStorage
object StorePermissionEx {
//Android 13以后,读写权限无法弹出系统弹窗,分化为Manifest.permission.READ_MEDIA_*权限
//Android 11以后,Manifest.permission.READ_EXTERNAL_STORAGE 授予后还需授予 额外储存管理权限 ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION
//Android 11以下使用Manifest.permission.READ_EXTERNAL_STORAGE
@SuppressLint("LocalSuppress")
fun Context.requestStoreFollow(
activityLauncher: ActivityLauncher,
disAgreeAction: (() -> Unit)? = null,
agreeAction: (() -> Unit)? = null,
) {
//请求读写管理权限
@SuppressLint("NewApi")
val requestExternalStorageManager: () -> Unit = {
if (!Environment.isExternalStorageManager()) {
val uri = Uri.parse("package:$packageName")
val intent = settingManageExternalStorage(uri)
activityLauncher.launch(intent) {
val flag = Environment.isExternalStorageManager()
if (flag) agreeAction?.invoke() else disAgreeAction?.invoke()
}
} else {
agreeAction?.invoke()
}
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {//Android 13以后
requestExternalStorageManager()
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {//Android 11以后
requestPermission(
this, activityLauncher,
arrayOf(
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE
), message = "Set permission to access external storage",
agreeAction = { //读写权限通过,设置储存管理权限
requestExternalStorageManager()
},
disAgreeAction = { disAgreeAction?.invoke() }
)
} else { //Android 11以下,Android 6以上
requestPermission(
this, activityLauncher,
arrayOf(
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE
), message = "Set permission to access external storage",
agreeAction = {
//读写权限通过
agreeAction?.invoke()
}, disAgreeAction = { disAgreeAction?.invoke() }
)
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#494949" />
<corners android:radius="20dp" />
</shape>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@mipmap/d_55633" android:state_selected="false" />
<item android:drawable="@mipmap/d_5563322" android:state_selected="true" />
<item android:drawable="@mipmap/d_55633" android:state_selected="true" />
<item android:drawable="@mipmap/d_5563322" android:state_selected="false" />
</selector>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@mipmap/fgf_87979812" android:state_selected="false" />
<item android:drawable="@mipmap/fgf_879798" android:state_selected="true" />
<item android:drawable="@mipmap/fgf_87979812" android:state_selected="true" />
<item android:drawable="@mipmap/fgf_879798" android:state_selected="false" />
</selector>
\ No newline at end of file
This diff is collapsed.
......@@ -22,6 +22,7 @@
tools:ignore="UseCompoundDrawables">
<ImageView
android:id="@+id/iv_back"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_gravity="center_vertical"
......@@ -35,7 +36,7 @@
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_margin="5dp"
android:text="Internal storage"
android:text="Tittle List Files"
android:textColor="#FF333333"
android:textSize="17sp"
android:textStyle="bold"
......@@ -102,6 +103,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="20dp"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="@id/tv_items"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@id/tv_items"
......@@ -117,6 +119,7 @@
tools:ignore="HardcodedText" />
<ImageView
android:id="@+id/iv_all_selector"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_gravity="center_vertical"
......@@ -126,21 +129,24 @@
</LinearLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginVertical="8dp"
app:layoutManager="androidx.recyclerview.widget.GridLayoutManager"
app:layout_constraintBottom_toBottomOf="parent"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
app:layout_constraintBottom_toTopOf="@id/tv_delete"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_items" />
<LinearLayout
android:id="@+id/ll_result"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/bg_000000_corners"
android:orientation="horizontal"
android:paddingVertical="8dp"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
......@@ -168,45 +174,20 @@
</LinearLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/cl_operation"
android:layout_width="match_parent"
android:layout_height="83dp"
app:layout_constraintBottom_toBottomOf="parent">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="vertical">
<ImageView
android:id="@+id/iv_share"
android:layout_width="28dp"
android:layout_height="28dp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Shre"
android:textColor="#FF333333"
tools:ignore="HardcodedText" />
</LinearLayout>
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
<TextView
android:id="@+id/tv_delete"
android:layout_width="278dp"
android:layout_height="40dp"
android:layout_marginBottom="40dp"
android:background="@drawable/bg_delete_selector"
android:gravity="center"
android:text="Delete"
android:textSize="15sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
tools:ignore="HardcodedText" />
</androidx.constraintlayout.widget.ConstraintLayout>
......@@ -245,6 +226,7 @@
app:layout_constraintTop_toBottomOf="@id/iv_lock" />
<TextView
android:id="@+id/tv_set"
android:layout_width="270dp"
android:layout_height="40dp"
android:layout_marginTop="20dp"
......
......@@ -8,11 +8,22 @@
tools:context=".MainActivity">
<androidx.fragment.app.FragmentContainerView
android:id="@+id/container"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="0dp"
app:defaultNavHost="true"
app:layout_constraintBottom_toTopOf="@id/bnv"
app:layout_constraintTop_toTopOf="parent"
app:navGraph="@navigation/nav" />
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/bnv"
app:menu="@menu/nav_menu"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent" />
app:layout_constraintBottom_toBottomOf="parent"
app:menu="@menu/nav_menu" />
</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
......@@ -74,6 +74,7 @@
android:layout_width="45dp"
android:layout_height="45dp"
android:layout_gravity="center_horizontal"
android:src="@mipmap/zsdas_878987"
tools:ignore="ContentDescription" />
<TextView
......@@ -98,6 +99,7 @@
android:layout_width="45dp"
android:layout_height="45dp"
android:layout_gravity="center_horizontal"
android:src="@mipmap/dzd_8789789"
tools:ignore="ContentDescription" />
<TextView
......@@ -105,7 +107,7 @@
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="8dp"
android:text="Image"
android:text="Video"
android:textColor="#FF333333"
android:textSize="12sp"
tools:ignore="HardcodedText" />
......@@ -122,6 +124,7 @@
android:layout_width="45dp"
android:layout_height="45dp"
android:layout_gravity="center_horizontal"
android:src="@mipmap/zd_8871110"
tools:ignore="ContentDescription" />
<TextView
......@@ -129,7 +132,7 @@
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="8dp"
android:text="Image"
android:text="Audio"
android:textColor="#FF333333"
android:textSize="12sp"
tools:ignore="HardcodedText" />
......@@ -157,6 +160,7 @@
android:layout_width="45dp"
android:layout_height="45dp"
android:layout_gravity="center_horizontal"
android:src="@mipmap/zd_001123"
tools:ignore="ContentDescription" />
<TextView
......@@ -164,7 +168,7 @@
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="8dp"
android:text="Image"
android:text="Log file"
android:textColor="#FF333333"
android:textSize="12sp"
tools:ignore="HardcodedText" />
......@@ -181,6 +185,7 @@
android:layout_width="45dp"
android:layout_height="45dp"
android:layout_gravity="center_horizontal"
android:src="@mipmap/eqwe_878979"
tools:ignore="ContentDescription" />
<TextView
......@@ -188,7 +193,7 @@
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="8dp"
android:text="Image"
android:text="Zip"
android:textColor="#FF333333"
android:textSize="12sp"
tools:ignore="HardcodedText" />
......@@ -205,6 +210,7 @@
android:layout_width="45dp"
android:layout_height="45dp"
android:layout_gravity="center_horizontal"
android:src="@mipmap/eqwe_88599"
tools:ignore="ContentDescription" />
<TextView
......@@ -212,7 +218,7 @@
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="8dp"
android:text="Image"
android:text="APK"
android:textColor="#FF333333"
android:textSize="12sp"
tools:ignore="HardcodedText" />
......@@ -225,12 +231,14 @@
android:layout_height="wrap_content"
android:layout_gravity="start"
android:layout_marginTop="20dp"
android:layout_marginStart="-10dp"
android:orientation="vertical"
app:layout_constraintStart_toStartOf="@id/fl_2"
app:layout_constraintTop_toBottomOf="@id/fl_2"
tools:ignore="UseCompoundDrawables">
<ImageView
android:src="@mipmap/qwe_889989"
android:layout_width="45dp"
android:layout_height="45dp"
android:layout_gravity="center_horizontal"
......@@ -241,23 +249,24 @@
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="8dp"
android:text="Image"
android:text="Documents"
android:textColor="#FF333333"
android:textSize="12sp"
tools:ignore="HardcodedText" />
</LinearLayout>
<FrameLayout
android:layout_marginTop="20dp"
app:layout_constraintTop_toBottomOf="@id/ll_documents"
android:layout_width="350dp"
android:layout_height="140dp"
android:layout_marginTop="20dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" >
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/ll_documents">
<ImageView
android:src="@mipmap/a_87890001"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@mipmap/a_87890001"
tools:ignore="ContentDescription" />
</FrameLayout>
......
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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_marginHorizontal="20dp"
android:layout_marginVertical="12dp"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:src="@mipmap/qwe_889989111"
android:id="@+id/iv_icon"
android:layout_width="45dp"
android:layout_height="45dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="ContentDescription" />
<LinearLayout
android:id="@+id/ll"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginHorizontal="8dp"
android:orientation="vertical"
app:layout_constraintEnd_toStartOf="@id/iv_selector"
app:layout_constraintStart_toEndOf="@id/iv_icon"
app:layout_constraintTop_toTopOf="@id/iv_icon">
<TextView
android:id="@+id/tv_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:singleLine="true"
android:text="Aaa"
android:textColor="#333333"
android:textSize="14sp"
android:textStyle="bold"
tools:ignore="HardcodedText" />
<TextView
android:id="@+id/tv_info"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="January 5, 2024 2.0MB"
android:textColor="#666666"
android:textSize="12sp"
tools:ignore="HardcodedText" />
</LinearLayout>
<ImageView
android:src="@drawable/bg_file_selector"
android:id="@+id/iv_selector"
android:layout_width="24dp"
android:layout_marginEnd="6dp"
android:layout_height="24dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="ContentDescription" />
</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
......@@ -17,7 +17,7 @@
android:id="@+id/nav_manager"
android:enabled="true"
android:icon="@drawable/bg_manager_selector"
android:title="Home"
android:title="Manager"
android:visible="true"
app:showAsAction="ifRoom"
tools:ignore="HardcodedText" />
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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