筛选和排序

This commit is contained in:
litingting 2025-09-29 18:30:36 +08:00
parent 2b8bdcb10c
commit a204314d92
83 changed files with 2409 additions and 646 deletions

View File

@ -52,4 +52,6 @@ dependencies {
androidTestImplementation(libs.androidx.espresso.core)
implementation (libs.glide)
kapt (libs.compiler)
implementation ("androidx.lifecycle:lifecycle-runtime-ktx:2.6.2")
implementation ("com.google.android.material:material:1.13.0")
}

View File

@ -13,6 +13,7 @@
tools:ignore="ScopedStorage" />
<application
android:name=".App"
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"

View File

@ -0,0 +1,14 @@
package com.ux.video.file.filerecovery
import android.app.Application
class App: Application() {
companion object{
lateinit var mAppContext: App
}
override fun onCreate() {
super.onCreate()
mAppContext = this
}
}

View File

@ -13,7 +13,6 @@ abstract class BaseAdapter<K, T : ViewBinding>(
protected val data: MutableList<K> = mutableListOf()
fun addData(items: List<K>?) {
items?.let {
val start = data.size

View File

@ -0,0 +1,50 @@
package com.ux.video.file.filerecovery.base
import android.content.Context
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
abstract class NewBaseAdapter<K>(
protected val mContext: Context
) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
protected val data: MutableList<K> = mutableListOf()
fun addData(items: List<K>?) {
items?.let {
val start = data.size
data.addAll(it)
notifyItemRangeInserted(start, it.size)
}
}
fun setData(items: List<K>?) {
data.clear()
items?.let { data.addAll(it) }
notifyDataSetChanged()
}
override fun getItemCount(): Int = data.size
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return onCreateBinding(parent, viewType)
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
onBind(holder, data[position], getItemViewType(position))
}
/**
* 子类实现根据 viewType 创建对应的 ViewHolder
*/
protected abstract fun onCreateBinding(
parent: ViewGroup,
viewType: Int
): RecyclerView.ViewHolder
/**
* 子类实现绑定数据
*/
protected abstract fun onBind(holder: RecyclerView.ViewHolder, item: K, viewType: Int)
}

View File

@ -24,9 +24,9 @@ class DocumentsScanResultActivity : BaseActivity<ActivityDocumentsScanResultBind
override fun initData() {
super.initData()
ScanRepository.instance.photoResults.observe(this@DocumentsScanResultActivity) {
resultAdapter?.setData(it)
}
// ScanRepository.instance.photoResults.observe(this@DocumentsScanResultActivity) {
// resultAdapter?.setData(it)
// }
}

View File

@ -6,6 +6,15 @@ import com.ux.video.file.filerecovery.R
import com.ux.video.file.filerecovery.base.BaseActivity
import com.ux.video.file.filerecovery.databinding.ActivityScanSelectTypeBinding
import com.ux.video.file.filerecovery.result.ScanningActivity
import com.ux.video.file.filerecovery.utils.Common.KEY_SCAN_TYPE
import com.ux.video.file.filerecovery.utils.Common.VALUE_SCAN_TYPE_audio
import com.ux.video.file.filerecovery.utils.Common.VALUE_SCAN_TYPE_deleted_audio
import com.ux.video.file.filerecovery.utils.Common.VALUE_SCAN_TYPE_deleted_documents
import com.ux.video.file.filerecovery.utils.Common.VALUE_SCAN_TYPE_deleted_photo
import com.ux.video.file.filerecovery.utils.Common.VALUE_SCAN_TYPE_deleted_video
import com.ux.video.file.filerecovery.utils.Common.VALUE_SCAN_TYPE_documents
import com.ux.video.file.filerecovery.utils.Common.VALUE_SCAN_TYPE_photo
import com.ux.video.file.filerecovery.utils.Common.VALUE_SCAN_TYPE_video
import kotlin.properties.Delegates
class ScanSelectTypeActivity : BaseActivity<ActivityScanSelectTypeBinding>() {
@ -30,19 +39,20 @@ class ScanSelectTypeActivity : BaseActivity<ActivityScanSelectTypeBinding>() {
setSelectType(type)
}
override fun initData() {
super.initData()
binding.imageBack.setOnClickListener { finish() }
binding.scanAllFile.setOnClickListener {
startActivity(Intent(this@ScanSelectTypeActivity, ScanningActivity::class.java).apply {
putExtra(ScanningActivity.Companion.KEY_SCAN_TYPE, allType)
putExtra(KEY_SCAN_TYPE, allType)
})
}
binding.scanDeletedFile.setOnClickListener {
startActivity(Intent(this@ScanSelectTypeActivity, ScanningActivity::class.java).apply {
putExtra(ScanningActivity.Companion.KEY_SCAN_TYPE, deletedType)
putExtra(KEY_SCAN_TYPE, deletedType)
})
}
}
@ -50,26 +60,26 @@ class ScanSelectTypeActivity : BaseActivity<ActivityScanSelectTypeBinding>() {
private fun setSelectType(fileType: Int) {
when (fileType) {
VALUE_PHOTO -> {
allType = ScanningActivity.Companion.VALUE_SCAN_TYPE_photo
deletedType = ScanningActivity.Companion.VALUE_SCAN_TYPE_deleted_photo
allType = VALUE_SCAN_TYPE_photo
deletedType = VALUE_SCAN_TYPE_deleted_photo
binding.title.text = getString(R.string.photo_title)
}
VALUE_VIDEO -> {
allType = ScanningActivity.Companion.VALUE_SCAN_TYPE_video
deletedType = ScanningActivity.Companion.VALUE_SCAN_TYPE_deleted_video
allType = VALUE_SCAN_TYPE_video
deletedType = VALUE_SCAN_TYPE_deleted_video
binding.title.text = getString(R.string.video_title)
}
VALUE_AUDIO -> {
allType = ScanningActivity.Companion.VALUE_SCAN_TYPE_audio
deletedType = ScanningActivity.Companion.VALUE_SCAN_TYPE_deleted_audio
allType = VALUE_SCAN_TYPE_audio
deletedType = VALUE_SCAN_TYPE_deleted_audio
binding.title.text = getString(R.string.audio_title)
}
VALUE_DOCUMENT -> {
allType = ScanningActivity.Companion.VALUE_SCAN_TYPE_documents
deletedType = ScanningActivity.Companion.VALUE_SCAN_TYPE_deleted_documents
allType = VALUE_SCAN_TYPE_documents
deletedType = VALUE_SCAN_TYPE_deleted_documents
binding.title.text = getString(R.string.document_title)
}
}

View File

@ -0,0 +1,68 @@
package com.ux.video.file.filerecovery.photo
import android.graphics.Color
import android.os.Bundle
import android.view.Gravity
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.core.graphics.drawable.toDrawable
import androidx.fragment.app.DialogFragment
import com.ux.video.file.filerecovery.R
import com.ux.video.file.filerecovery.databinding.CommonLayoutSortItemBinding
import com.ux.video.file.filerecovery.databinding.DialogSortBinding
import com.google.android.material.datepicker.MaterialDatePicker
import com.google.android.material.datepicker.CalendarConstraints
import com.google.android.material.datepicker.DateValidatorPointForward
import java.text.SimpleDateFormat
import java.util.*
class DatePickerDialogFragment(val onClickSort: (type: Int) -> Unit) : DialogFragment() {
private lateinit var binding: DialogSortBinding
override fun onStart() {
super.onStart()
dialog?.window?.apply {
setLayout(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT
)
setGravity(Gravity.BOTTOM)
setBackgroundDrawable(Color.TRANSPARENT.toDrawable())
}
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding = DialogSortBinding.inflate(inflater)
return binding.root
}
fun showDatePicker() {
// 创建日期选择器构建器
val builder = MaterialDatePicker.Builder.datePicker()
builder.setTitleText("选择日期")
// 可选:限制可选日期,比如只能选择今天之后的日期
val constraintsBuilder = CalendarConstraints.Builder()
constraintsBuilder.setValidator(DateValidatorPointForward.now()) // 今天之后
builder.setCalendarConstraints(constraintsBuilder.build())
val datePicker = builder.build()
// 显示日期选择器
datePicker.show(supportFragmentManager, "MATERIAL_DATE_PICKER")
// 监听用户选择
datePicker.addOnPositiveButtonClickListener { selection ->
// selection 是 Long 类型的时间戳UTC 毫秒)
val sdf = SimpleDateFormat("yyyy-MM-dd", Locale.getDefault())
val dateString = sdf.format(Date(selection))
println("用户选择的日期:$dateString")
}
}
}

View File

@ -0,0 +1,128 @@
package com.ux.video.file.filerecovery.photo
import android.content.Context
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.PopupWindow
import android.widget.RelativeLayout
import androidx.core.view.forEach
import com.ux.video.file.filerecovery.databinding.CommonLayoutFilterItemBinding
import com.ux.video.file.filerecovery.databinding.PopwindowsFilterBinding
import com.ux.video.file.filerecovery.utils.Common.setItemSelect
import com.ux.video.file.filerecovery.utils.CustomTextView
class FilterPopupWindows(
context: Context, list: Array<String>,
selectedPos: Int,
onClickConfirm: (value: String) -> Unit,
var onClickDismiss: () -> Unit
) :
PopupWindow(context) {
private val viewBinding: PopwindowsFilterBinding =
PopwindowsFilterBinding.inflate(LayoutInflater.from(context))
init {
setContentView(viewBinding.root)
width = ViewGroup.LayoutParams.MATCH_PARENT
height = ViewGroup.LayoutParams.WRAP_CONTENT
isFocusable = true
isOutsideTouchable = true
setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
// 动画(可选)
// animationStyle = R.style.PopupAnimation
viewBinding.viewMask.setOnClickListener {
dismiss()
}
setData(list, selectedPos, onClickConfirm)
}
private fun setData(
list: Array<String>,
selectedPos: Int,
onClickConfirm: (value: String) -> Unit
) {
viewBinding.parentLayout.removeAllViews()
list.forEachIndexed { index, item ->
viewBinding.parentLayout.run {
addView(
CommonLayoutFilterItemBinding.inflate(
LayoutInflater.from(context),
this,
false
).apply {
textItem.text = item
if (index == selectedPos) {
textItem.isSelected = true
checkImage.isSelected = true
}
}.root
)
}
}
setMutualExclusion(onClickConfirm)
}
private fun setMutualExclusion(onClickConfirm: (value: String) -> Unit) {
viewBinding.run {
for (i in 0 until parentLayout.childCount) {
val child = parentLayout.getChildAt(i)
if (child is RelativeLayout) {
child.setOnClickListener {
for (j in 0 until parentLayout.childCount) {
val other = parentLayout.getChildAt(j)
if (other is RelativeLayout) {
setItemSelect(other, false)
}
}
setItemSelect(child, true)
for (j in 0 until child.childCount) {
val other = child.getChildAt(j)
if (other is CustomTextView) {
onClickConfirm.invoke(other.text.toString())
}
}
dismiss()
}
}
}
}
}
fun show(anchor: View, xOff: Int = 0, yOff: Int = 0) {
showAsDropDown(anchor, xOff, yOff)
viewBinding.viewMask.apply {
alpha = 0f
animate().alpha(1f).setDuration(200).start()
visibility = View.VISIBLE
}
}
override fun dismiss() {
Log.d("------------", "--------------dismiss")
viewBinding.viewMask.animate().alpha(0f).setDuration(200)
.withEndAction {
super.dismiss()
onClickDismiss.invoke()
}.start()
}
}

View File

@ -1,61 +1,107 @@
package com.ux.video.file.filerecovery.photo
import android.annotation.SuppressLint
import android.content.Context
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.GridLayoutManager
import com.ux.video.file.filerecovery.base.BaseAdapter
import com.ux.video.file.filerecovery.databinding.PhotoDisplayDateAdapterBinding
import com.ux.video.file.filerecovery.utils.ExtendFunctions.addItemDecorationOnce
import com.ux.video.file.filerecovery.utils.ExtendFunctions.dpToPx
import com.ux.video.file.filerecovery.utils.Common
import com.ux.video.file.filerecovery.utils.ExtendFunctions.resetItemDecorationOnce
import com.ux.video.file.filerecovery.utils.GridSpacingItemDecoration
import com.ux.video.file.filerecovery.utils.ScanRepository
class PhotoDisplayDateAdapter(mContext: Context) :
class PhotoDisplayDateAdapter(
mContext: Context,
var mColumns: Int,
var viewModel: ScanRepository,
var onSelectedUpdate: (updatePath: String, isAdd: Boolean) -> Unit
) :
BaseAdapter<Pair<String, List<ResultPhotosFiles>>, PhotoDisplayDateAdapterBinding>(mContext) {
private var allSelected: Boolean? = null
private var columns = 3
override fun getViewBinding(parent: ViewGroup): PhotoDisplayDateAdapterBinding =
PhotoDisplayDateAdapterBinding.inflate(
LayoutInflater.from(parent.context),
parent,
false
)
/**
* 返回所有嵌套的数据量总数
*/
fun getTotalChildCount(): Int {
return data.sumOf { it.second.size }
}
/**
* activity页面上点击全选按钮执行
*/
fun setAllSelected(allSelect: Boolean) {
allSelected = allSelect
data.forEach {
it.second.forEach { item ->
onSelectedUpdate(item.path.toString(),allSelect)
}
}
notifyDataSetChanged()
}
fun setColumns(int: Int){
columns = int
fun resetAllValue(b: Boolean?){
allSelected = b
}
fun setColumns(int: Int) {
mColumns = int
notifyDataSetChanged()
}
@SuppressLint("SetTextI18n")
override fun bindItem(
holder: VHolder<PhotoDisplayDateAdapterBinding>,
item: Pair<String, List<ResultPhotosFiles>>
) {
holder.vb.run {
val photoDisplayDateChildAdapter = PhotoDisplayDateChildAdapter(mContext)
item.run {
allSelected?.let {
imSelectStatus.isSelected = it
photoDisplayDateChildAdapter.setAllSelected(it)
}
imSelectStatus.setOnClickListener {
it.isSelected = !it.isSelected
photoDisplayDateChildAdapter.setAllSelected(it.isSelected)
}
val (date, files) = item
val childAdapter = PhotoDisplayDateChildAdapter(
mContext,
mColumns,
viewModel
) { path, addOrRemove, isDateAllSelected ->
//点击当前Adapter某一天的全选或者子Item上的选中都会回调到这里
tvDayAllSelect.isSelected = isDateAllSelected
onSelectedUpdate(path.toString(),addOrRemove)
}.apply { setData(files) }
allSelected?.let {
childAdapter.setAllSelected(it)
}
tvDayAllSelect.setOnClickListener {
it.isSelected = !it.isSelected
childAdapter.setAllSelected(it.isSelected)
}
textDate.text = date
textChildCounts.text = "(${files.size})"
recyclerChild.apply {
layoutManager = GridLayoutManager(context, columns)
layoutManager = GridLayoutManager(context, mColumns)
val gridSpacingItemDecoration =
GridSpacingItemDecoration(4, 8.dpToPx(mContext), true)
addItemDecorationOnce(gridSpacingItemDecoration)
adapter = photoDisplayDateChildAdapter.apply { setData(files) }
GridSpacingItemDecoration(mColumns, Common.itemSpacing, Common.horizontalSpacing)
Common.showLog("---------mColumns=${mColumns}")
// resetItemDecorationOnce(gridSpacingItemDecoration)
adapter = childAdapter
isNestedScrollingEnabled = false
}
}
}
}
}

View File

@ -3,7 +3,11 @@ package com.ux.video.file.filerecovery.photo
import android.content.Context
import android.graphics.drawable.Drawable
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.RelativeLayout
import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide
import com.bumptech.glide.load.DataSource
import com.bumptech.glide.load.engine.GlideException
@ -12,55 +16,151 @@ import com.bumptech.glide.load.resource.bitmap.RoundedCorners
import com.bumptech.glide.request.RequestListener
import com.bumptech.glide.request.RequestOptions
import com.bumptech.glide.request.target.Target
import com.ux.video.file.filerecovery.base.BaseAdapter
import com.ux.video.file.filerecovery.databinding.PhotoDisplayDateChildAdapterBinding
import com.ux.video.file.filerecovery.App
import com.ux.video.file.filerecovery.base.NewBaseAdapter
import com.ux.video.file.filerecovery.databinding.FileSpanCountThreeAdapterBinding
import com.ux.video.file.filerecovery.databinding.FileSpanCountTwoAdapterBinding
import com.ux.video.file.filerecovery.utils.Common
import com.ux.video.file.filerecovery.utils.CustomTextView
import com.ux.video.file.filerecovery.utils.ExtendFunctions.dpToPx
import com.ux.video.file.filerecovery.utils.ScanManager
import com.ux.video.file.filerecovery.utils.ScanRepository
import kotlin.collections.remove
class PhotoDisplayDateChildAdapter(mContext: Context) :
BaseAdapter<ResultPhotosFiles, PhotoDisplayDateChildAdapterBinding>(mContext) {
private var allSelected: Boolean? = null
override fun getViewBinding(parent: ViewGroup): PhotoDisplayDateChildAdapterBinding =
PhotoDisplayDateChildAdapterBinding.inflate(
LayoutInflater.from(parent.context),
parent,
false
)
class PhotoDisplayDateChildAdapter(
mContext: Context,
var mColumns: Int,
var viewModel: ScanRepository,
/**
* 通知外层某天全选的按钮更新状态
* @param updatePath 当前点击的item
* @param addOrRemove 选中还是取消选中
* @param dateAllSelected 这组数据是否全部选中某一天
*/
var onSelectedUpdate: (updatePath: String, addOrRemove: Boolean, dateAllSelected: Boolean) -> Unit
) :
NewBaseAdapter<ResultPhotosFiles>(mContext) {
fun setAllSelected(allselect: Boolean) {
allSelected = allselect
//日期组某一天的数据选择状态维护
val dateSelectedMap = mutableSetOf<String>()
companion object {
private const val TYPE_TWO = 2
private const val TYPE_THREE = 3
private const val TYPE_FOUR = 4
}
fun setAllSelected(isAdd: Boolean) {
data.forEach {
addOrRemove(it.path.toString(), isAdd)
}
notifyDataSetChanged()
}
override fun bindItem(
holder: VHolder<PhotoDisplayDateChildAdapterBinding>,
item: ResultPhotosFiles
override fun getItemViewType(position: Int): Int {
return when (mColumns) {
2 -> TYPE_TWO
3 -> TYPE_THREE
4 -> TYPE_FOUR
else -> TYPE_THREE
}
}
fun setColumns(int: Int) {
mColumns = int
notifyDataSetChanged()
}
/**
* 设置View为正方形
*/
private fun setHeight(view: View) {
val layoutParams = view.layoutParams
val screenWidth = view.context.resources.displayMetrics.widthPixels
val i = (Common.itemSpacing).dpToPx(App.mAppContext) * (mColumns - 1)
val itemSize =
(screenWidth - i - 2 * Common.horizontalSpacing.dpToPx(App.mAppContext) )/ mColumns
view.layoutParams = layoutParams.apply {
height = itemSize
}
}
override fun onCreateBinding(
parent: ViewGroup,
viewType: Int
): RecyclerView.ViewHolder {
val inflater = LayoutInflater.from(parent.context)
return when (viewType) {
TYPE_TWO -> TwoHolder(
FileSpanCountTwoAdapterBinding.inflate(
inflater,
parent,
false
)
)
else -> ThreeHolder(
FileSpanCountThreeAdapterBinding.inflate(
inflater,
parent,
false
)
)
}
}
override fun onBind(
holder: RecyclerView.ViewHolder,
item: ResultPhotosFiles,
viewType: Int
) {
holder.vb.run {
item.run {
imSelectStatus.isSelected = ScanRepository.instance.checkIsSelect(path.toString())
allSelected?.let {
imSelectStatus.isSelected = it
//全选按钮手动触发,需要更新
updateSetList(it, path.toString())
when (holder) {
is TwoHolder -> holder.vb.run {
initDateView(rootLayout, imageSelect, textSize, imageThumbnail, item)
}
is ThreeHolder -> holder.vb.run {
initDateView(rootLayout, imageSelect, textSize, imageThumbnail, item)
}
}
imSelectStatus.setOnClickListener {
it.isSelected = !it.isSelected
updateSetList(it.isSelected, path.toString())
}
class ThreeHolder(val vb: FileSpanCountThreeAdapterBinding) :
RecyclerView.ViewHolder(vb.root)
class TwoHolder(val vb: FileSpanCountTwoAdapterBinding) :
RecyclerView.ViewHolder(vb.root)
private fun initDateView(
rootLayout: RelativeLayout,
imageSelectStatus: ImageView,
textSize: CustomTextView,
imageThumbnail: ImageView,
item: ResultPhotosFiles
) {
item.run {
viewModel.checkIsSelect(path.toString()).let {
imageSelectStatus.isSelected = it
addOrRemove(path.toString(), it)
}
imageSelectStatus.setOnClickListener {
it.isSelected = !it.isSelected
it.isSelected.let { newStatus ->
addOrRemove(path.toString(), newStatus)
}
}
textSize.text = Common.formatFileSize(mContext, size)
Glide.with(mContext)
.load(targetFile)
.apply(
RequestOptions()
.transform(CenterCrop(), RoundedCorners(15.dpToPx(mContext)))
.transform(CenterCrop(), RoundedCorners(8.dpToPx(mContext)))
)
.listener(object : RequestListener<Drawable> {
override fun onLoadFailed(
@ -89,12 +189,20 @@ class PhotoDisplayDateChildAdapter(mContext: Context) :
})
.into(imageThumbnail)
setHeight(rootLayout)
}
}
}
private fun updateSetList(boolean: Boolean, path: String) {
ScanRepository.instance.toggleSelection(boolean,path)
private fun addOrRemove(path: String, boolean: Boolean) {
if (boolean) {
dateSelectedMap.add(path)
} else {
dateSelectedMap.remove(path)
}
onSelectedUpdate.invoke(path, boolean, dateSelectedMap.size == itemCount)
}
}

View File

@ -1,14 +1,19 @@
package com.ux.video.file.filerecovery.photo
import android.view.LayoutInflater
import android.widget.LinearLayout
import androidx.activity.viewModels
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
import com.ux.video.file.filerecovery.R
import com.ux.video.file.filerecovery.base.BaseActivity
import com.ux.video.file.filerecovery.databinding.ActivityPhotoSortingBinding
import com.ux.video.file.filerecovery.utils.Common
import com.ux.video.file.filerecovery.utils.ExtendFunctions.addItemDecorationOnce
import com.ux.video.file.filerecovery.utils.Common.setItemSelect
import com.ux.video.file.filerecovery.utils.ExtendFunctions.dpToPx
import com.ux.video.file.filerecovery.utils.ExtendFunctions.filterBySize
import com.ux.video.file.filerecovery.utils.ExtendFunctions.filterBySizeList
@ -16,6 +21,7 @@ import com.ux.video.file.filerecovery.utils.ExtendFunctions.filterWithinMonths
import com.ux.video.file.filerecovery.utils.ExtendFunctions.filterWithinMonthsList
import com.ux.video.file.filerecovery.utils.ExtendFunctions.getParcelableArrayListExtraCompat
import com.ux.video.file.filerecovery.utils.ExtendFunctions.mbToBytes
import com.ux.video.file.filerecovery.utils.ExtendFunctions.resetItemDecorationOnce
import com.ux.video.file.filerecovery.utils.GridSpacingItemDecoration
import com.ux.video.file.filerecovery.utils.ScanManager
import com.ux.video.file.filerecovery.utils.ScanManager.copySelectedFilesAsync
@ -38,12 +44,19 @@ class PhotoSortingActivity : BaseActivity<ActivityPhotoSortingBinding>() {
val FILTER_SIZE_1 = 1
val FILTER_SIZE_5 = 2
val FILTER_SIZE_OVER_5 = 3
val SORT_ASC_SIZE = 0
val SORT_DESC_SIZE = 1
val SORT_ASC_DATE = 2
val SORT_DESC_DATE = 3
}
private var sortDialogFragment: SortDialogFragment? = null
private var columns = 3
private var dateAdapter: PhotoDisplayDateAdapter? = null
private var sizeAdapter: PhotoDisplayDateChildAdapter? = null
val selectedSet = mutableSetOf<String>() // 保存选中状态
//文件大小排序使用的适配器
private var sizeSortAdapter: PhotoDisplayDateChildAdapter? = null
//默认倒序排序
@ -55,12 +68,26 @@ class PhotoSortingActivity : BaseActivity<ActivityPhotoSortingBinding>() {
//筛选大小,默认全部-1
private var filterSize = FILTER_SIZE_ALL
private var filterDatePopupWindows: FilterPopupWindows? = null
private var filterSizePopupWindows: FilterPopupWindows? = null
private var filterLayoutPopupWindows: FilterPopupWindows? = null
private lateinit var sortBySizeBigToSmall: List<ResultPhotosFiles>
private lateinit var sortBySizeSmallToBig: List<ResultPhotosFiles>
private lateinit var sortByDayReverse: List<Pair<String, List<ResultPhotosFiles>>>
private lateinit var sortedByPositive: List<Pair<String, List<ResultPhotosFiles>>>
private lateinit var sortByDateReverse: List<Pair<String, List<ResultPhotosFiles>>>
private lateinit var sortedByDatePositive: List<Pair<String, List<ResultPhotosFiles>>>
//选中的所有数据集合(实际选中)
private lateinit var allSelectedSetList: Set<String>
//选中的所有数据集合(筛选后的数据实际显示的所有选中)
private lateinit var filterSelectedSetList: Set<String>
private lateinit var mItemDecoration: GridSpacingItemDecoration
private lateinit var viewModel: ScanRepository
override fun inflateBinding(inflater: LayoutInflater): ActivityPhotoSortingBinding =
ActivityPhotoSortingBinding.inflate(inflater)
@ -69,32 +96,57 @@ class PhotoSortingActivity : BaseActivity<ActivityPhotoSortingBinding>() {
val list: ArrayList<ResultPhotosFiles>? =
intent.getParcelableArrayListExtraCompat(KEY_PHOTO_FOLDER_FILE)
mItemDecoration =
GridSpacingItemDecoration(columns, Common.itemSpacing, Common.horizontalSpacing)
updateButtonCounts(0)
viewModel = ViewModelProvider(this).get(ScanRepository::class.java)
viewModel.selectedLiveData.observe(this) { selectedSet ->
allSelectedSetList = selectedSet
Common.showLog("所有数据 选中状态更新: ${selectedSet.size}")
}
viewModel.selectedDisplayLiveData.observe(this) { displaySet ->
filterSelectedSetList = displaySet
Common.showLog("当前显示筛选数据 选中状态更新: ${displaySet.size}")
updateCurrentIsAllSelectStatus()
}
list?.let {
//倒序(最近的在前面)
sortByDayReverse = Common.getSortByDayNewToOld(it)
//正序(最远的在前面)
sortedByPositive = Common.getSortByDayOldToNew(sortByDayReverse)
//降序(最近的在前面)
sortByDateReverse = Common.getSortByDayNewToOld(it)
//升序(时间最远的在前面)
sortedByDatePositive = Common.getSortByDayOldToNew(sortByDateReverse)
sortBySizeBigToSmall = Common.getSortBySizeBigToSmall(it)
sortBySizeSmallToBig = Common.getSortBySizeSmallToBig(it)
sizeAdapter = PhotoDisplayDateChildAdapter(this@PhotoSortingActivity)
dateAdapter = PhotoDisplayDateAdapter(this@PhotoSortingActivity).apply {
setData(sortByDayReverse)
sizeSortAdapter = PhotoDisplayDateChildAdapter(
this@PhotoSortingActivity,
columns, viewModel
) { path, isAdd, allSelected ->
// updateSelectedList(isAdd, path)
// updateCurrentIsAllSelectStatus()
viewModel.toggleSelection(isAdd, path)
}
dateAdapter =
PhotoDisplayDateAdapter(
this@PhotoSortingActivity,
columns,
viewModel
) { actionPath, isAdd ->
// updateSelectedList(isAdd, actionPath)
// updateCurrentIsAllSelectStatus()
viewModel.toggleSelection(isAdd, actionPath)
}.apply {
setData(sortByDateReverse)
}
setDateAdapter()
setFilter()
binding.run {
lifecycleScope.launch {
ScanRepository.instance.selectedFlow.collect { newSet ->
println("选中集合变化:$newSet")
tvSelectCounts.text = newSet.size.toString()
}
}
tvSelectCounts.setOnClickListener {
tvRecover.setOnClickListener {
lifecycleScope.copySelectedFilesAsync(
selectedSet = ScanRepository.instance.selectedFlow.value,
selectedSet = filterSelectedSetList,
folder = Common.recoveryPhotoDir,
onProgress = { currentCounts: Int, fileName: String, success: Boolean ->
@ -109,10 +161,10 @@ class PhotoSortingActivity : BaseActivity<ActivityPhotoSortingBinding>() {
}
}
btnDelete.setOnClickListener {
tvDelete.setOnClickListener {
lifecycleScope.deleteFilesAsync(
selectedSet = ScanRepository.instance.selectedFlow.value,
onProgress = { currentCounts: Int, path:String, success: Boolean ->
selectedSet = filterSelectedSetList,
onProgress = { currentCounts: Int, path: String, success: Boolean ->
ScanManager.showLog(
"--------删除图片 ",
"----------${currentCounts} ${path}"
@ -124,124 +176,163 @@ class PhotoSortingActivity : BaseActivity<ActivityPhotoSortingBinding>() {
}
}
linear.setOnCheckedChangeListener { group, checkedId ->
when (checkedId) {
R.id.btn_date_old_to_new -> {
imSort.setOnClickListener {
sortDialogFragment = sortDialogFragment ?: SortDialogFragment {
when (it) {
SORT_ASC_DATE -> {
setDateAdapter()
dateAdapter?.setData(sortedByPositive)
dateAdapter?.setData(sortedByDatePositive)
sortReverse = false
}
R.id.btn_date_new_to_old -> {
SORT_DESC_DATE -> {
setDateAdapter()
dateAdapter?.setData(sortByDayReverse)
dateAdapter?.setData(sortByDateReverse)
sortReverse = true
}
R.id.btn_size_big_to_small -> {
SORT_DESC_SIZE -> {
setSizeAdapter()
sizeAdapter?.setData(sortBySizeBigToSmall)
sizeSortAdapter?.setData(sortBySizeBigToSmall)
sortReverse = true
}
R.id.btn_size_small_to_big -> {
SORT_ASC_SIZE -> {
setSizeAdapter()
sizeAdapter?.setData(sortBySizeSmallToBig)
sizeSortAdapter?.setData(sortBySizeSmallToBig)
sortReverse = false
}
}
}
sortDialogFragment?.show(supportFragmentManager, "")
}
imSelectAll.setOnClickListener {
imSelectAll.isSelected = !imSelectAll.isSelected
sizeAdapter?.setAllSelected(imSelectAll.isSelected)
dateAdapter?.setAllSelected(imSelectAll.isSelected)
//全选按钮 只对当前显示的数据有效
tvSelectAll.setOnClickListener {
it.isSelected = !it.isSelected
dateAdapter?.setAllSelected(it.isSelected)
sizeSortAdapter?.setAllSelected(it.isSelected)
}
}
}
}
private fun updateCurrentIsAllSelectStatus() {
filterSelectedSetList.size.let {
binding.tvSelectCounts.text = it.toString()
updateButtonCounts(it)
when (binding.recyclerView.adapter) {
is PhotoDisplayDateAdapter -> {
val adapter = binding.recyclerView.adapter as PhotoDisplayDateAdapter
binding.tvSelectAll.isSelected = it == adapter.getTotalChildCount()
}
is PhotoDisplayDateChildAdapter -> {
binding.tvSelectAll.isSelected = it == binding.recyclerView.adapter?.itemCount
}
}
}
}
private fun setDateAdapter() {
binding.recyclerView.run {
adapter = dateAdapter?.apply { setColumns(columns) }
layoutManager = LinearLayoutManager(this@PhotoSortingActivity)
val bPx = 16.dpToPx(context)
setPadding(0, 0, 0, 0)
clipToPadding = false
}
}
private fun setSizeAdapter() {
binding.recyclerView.run {
adapter = sizeAdapter
val aPx = 16.dpToPx(context)
val bPx = 6.dpToPx(context)
setPadding(aPx, 0, bPx, 0)
clipToPadding = false
layoutManager = GridLayoutManager(context, columns)
val gridSpacingItemDecoration =
GridSpacingItemDecoration(4, 8.dpToPx(this@PhotoSortingActivity), true)
addItemDecorationOnce(gridSpacingItemDecoration)
// resetItemDecorationOnce(mItemDecoration)
adapter = sizeSortAdapter
}
}
/**
* 筛选
* 筛选和布局设置
*/
private fun setFilter() {
binding.linearDate.setOnCheckedChangeListener { group, checkedId ->
when (checkedId) {
R.id.btn_date_all -> {
filterDate = FILTER_DATE_ALL
}
R.id.btn_date_within_1 -> {
filterDate = FILTER_DATE_1
}
R.id.btn_date_customize -> {
}
//日期筛选
binding.run {
filterDateLayout.setOnClickListener {
setItemSelect(it as LinearLayout, true)
resources.getStringArray(R.array.filter_date).let { data ->
filterDatePopupWindows = filterDatePopupWindows ?: FilterPopupWindows(
this@PhotoSortingActivity,
data,
0,
{ clickValue ->
when (clickValue) {
data[0] -> filterDate = FILTER_DATE_ALL
data[1] -> filterDate = FILTER_DATE_1
data[2] -> filterDate = FILTER_DATE_6
data[3] -> filterDate = FILTER_DATE_24
data[4] -> {}
}
startFilter()
}
binding.linearSize.setOnCheckedChangeListener { group, checkedId ->
when (checkedId) {
R.id.btn_size_all -> {
filterSize = FILTER_SIZE_ALL
}) {
setItemSelect(it, false)
}
R.id.btn_size_1m -> {
filterSize = FILTER_SIZE_1
filterDatePopupWindows?.show(it)
}
R.id.btn_size_5m -> {
filterSize = FILTER_SIZE_5
}
R.id.btn_size_over_5m -> {
filterSize = FILTER_SIZE_OVER_5
}
//大小筛选
filterSizeLayout.setOnClickListener {
setItemSelect(it as LinearLayout, true)
resources.getStringArray(R.array.filter_size).let { data ->
filterSizePopupWindows = filterSizePopupWindows ?: FilterPopupWindows(
this@PhotoSortingActivity,
data,
0,
{ clickValue ->
when (clickValue) {
data[0] -> filterSize = FILTER_SIZE_ALL
data[1] -> filterSize = FILTER_SIZE_1
data[2] -> filterSize = FILTER_SIZE_5
data[3] -> filterSize = FILTER_SIZE_OVER_5
}
startFilter()
}) {
setItemSelect(it, false)
}
binding.rgLayout.setOnCheckedChangeListener { group, checkedId ->
when (checkedId) {
R.id.rb_columns_2 -> {
columns = 2
}
R.id.rb_columns_3 -> {
columns = 3
}
R.id.rb_columns_4 -> {
columns = 4
}
filterSizePopupWindows?.show(it)
}
}
//布局设置
filterLayoutLinearlayout.setOnClickListener {
setItemSelect(it as LinearLayout, true)
resources.getStringArray(R.array.filter_layout).let { data ->
filterLayoutPopupWindows = filterLayoutPopupWindows ?: FilterPopupWindows(
this@PhotoSortingActivity,
data,
1,
{ clickValue ->
when (clickValue) {
data[0] -> columns = 2
data[1] -> columns = 3
data[2] -> columns = 4
}
when (binding.recyclerView.adapter) {
is PhotoDisplayDateAdapter -> {
dateAdapter?.setColumns(columns)
@ -250,10 +341,38 @@ class PhotoSortingActivity : BaseActivity<ActivityPhotoSortingBinding>() {
is PhotoDisplayDateChildAdapter -> {
binding.recyclerView.layoutManager =
GridLayoutManager(this@PhotoSortingActivity, columns)
sizeSortAdapter?.setColumns(columns)
}
}
}) {
setItemSelect(it, false)
}
}
filterLayoutPopupWindows?.show(it)
}
}
}
/**
* 根据当前显示的实际数据选中的数量来更新按钮文字和状态
*/
private fun updateButtonCounts(selectedCounts: Int) {
binding.run {
if (selectedCounts <= 0) {
tvDelete.isEnabled = false
tvRecover.isEnabled = false
} else {
tvDelete.isEnabled = true
tvRecover.isEnabled = true
}
tvDelete.text = getString(R.string.delete_placeholder, selectedCounts)
tvRecover.text = getString(R.string.recover_placeholder, selectedCounts)
}
}
@ -262,33 +381,41 @@ class PhotoSortingActivity : BaseActivity<ActivityPhotoSortingBinding>() {
*/
private fun startFilter() {
when (binding.recyclerView.adapter) {
//当前是时间排序
is PhotoDisplayDateAdapter -> {
val list = if (sortReverse) sortByDayReverse else sortedByPositive
//确定当前排序
val list = if (sortReverse) sortByDateReverse else sortedByDatePositive
val filterSizeCovert = filterSizeCovert(filterSize)
list.filterWithinMonths(filterDate)
.filterBySize(filterSizeCovert.first, filterSizeCovert.second).let {
dateAdapter?.setData(it)
ScanManager.showLog(
"---",
"---date-----${it.size} filterDate=${filterDate} first=${filterSizeCovert.first} second=${filterSizeCovert.second} dateAdapter=${dateAdapter}"
)
}
.filterBySize(filterSizeCovert.first, filterSizeCovert.second)
.let { currentList ->
//对筛选后的数据与实际选中集合对比 ,得出筛选后显示的数据中的选中数据
val checkSelectListContain =
Common.checkSelectListContainDate(currentList, allSelectedSetList)
updateButtonCounts(checkSelectListContain.first)
viewModel.filterResetDisplayFlow(checkSelectListContain.second)
Common.showLog( "筛选后重置 allSelectedSetList=${allSelectedSetList.size} filterSelectedSetList=${filterSelectedSetList.size} Thread=${Thread.currentThread().name}")
dateAdapter?.resetAllValue(null)
dateAdapter?.setData(currentList)
}
}
//当前是大小排序
is PhotoDisplayDateChildAdapter -> {
val list = if (sortReverse) sortBySizeBigToSmall else sortBySizeSmallToBig
val filterSizeCovert = filterSizeCovert(filterSize)
list.filterWithinMonthsList(filterDate)
.filterBySizeList(filterSizeCovert.first, filterSizeCovert.second).let {
sizeAdapter?.setData(it)
ScanManager.showLog(
"---",
"----size----${it.size} filterDate=${filterDate} first=${filterSizeCovert.first} second=${filterSizeCovert.second} sizeAdapter=${sizeAdapter}"
)
.filterBySizeList(filterSizeCovert.first, filterSizeCovert.second)
.let { currentList ->
//对筛选后的数据与实际选中集合对比 ,得出筛选后显示的数据中的选中数据
val checkSelectListContain =
Common.checkSelectListContainSize(currentList, allSelectedSetList)
updateButtonCounts(checkSelectListContain.first)
viewModel.filterResetDisplayFlow(checkSelectListContain.second)
sizeSortAdapter?.setData(currentList)
}
}
}
}
@ -306,4 +433,5 @@ class PhotoSortingActivity : BaseActivity<ActivityPhotoSortingBinding>() {
}
}

View File

@ -11,7 +11,7 @@ data class ResultPhotosFiles(
val path: String?= null,
val size: Long, // 字节
val lastModified: Long, // 时间戳
var isSelected: Boolean = false // 选中状态
// var isSelected: Boolean = false // 选中状态
): Parcelable{
val targetFile: File?
get() = path?.let { File(it) }

View File

@ -0,0 +1,116 @@
package com.ux.video.file.filerecovery.photo
import android.graphics.Color
import android.os.Bundle
import android.view.Gravity
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.core.graphics.drawable.toDrawable
import androidx.fragment.app.DialogFragment
import com.ux.video.file.filerecovery.R
import com.ux.video.file.filerecovery.databinding.CommonLayoutSortItemBinding
import com.ux.video.file.filerecovery.databinding.DialogSortBinding
class SortDialogFragment(val onClickSort: (type: Int) -> Unit) : DialogFragment() {
private lateinit var binding: DialogSortBinding
private var clickType = PhotoSortingActivity.SORT_DESC_DATE
private lateinit var LayoutList: List<CommonLayoutSortItemBinding>
override fun onStart() {
super.onStart()
dialog?.window?.apply {
setLayout(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT
)
setGravity(Gravity.BOTTOM)
setBackgroundDrawable(Color.TRANSPARENT.toDrawable())
}
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding = DialogSortBinding.inflate(inflater)
binding.run {
LayoutList = listOf(
ascendingSizeLayout,
descendingSizeLayout,
ascendingDateLayout,
descendingDateLayout
)
setMutualExclusion(LayoutList)
resetSelectedSortType(clickType)
setIconText(
LayoutList[0],
R.drawable.icon_ascending_size,
getString(R.string.size),
getString(R.string.asc_size_describe)
)
setIconText(
LayoutList[1],
R.drawable.icon_descending_size,
getString(R.string.size),
getString(R.string.desc_size_describe)
)
setIconText(
LayoutList[2],
R.drawable.icon_ascending_date,
getString(R.string.date),
getString(R.string.asc_date_describe)
)
setIconText(
LayoutList[3],
R.drawable.icon_descending_date,
getString(R.string.date),
getString(R.string.desc_date_describe)
)
tvCancel.setOnClickListener { dismiss() }
tvOk.setOnClickListener {
onClickSort(clickType)
dismiss()
}
}
return binding.root
}
fun resetSelectedSortType(type: Int) {
LayoutList.forEachIndexed { index, item ->
item.checkImage.isSelected = index == type
}
}
private fun setIconText(
itemBinding: CommonLayoutSortItemBinding,
iconId: Int,
text: String,
subText: String
) {
itemBinding.run {
sortType.text = text
sortSubType.text = subText
icon.setImageResource(iconId)
}
}
private fun setMutualExclusion(listOf: List<CommonLayoutSortItemBinding>) {
for (i in 0 until listOf.size) {
val binding = listOf[i]
binding.root.setOnClickListener {
for (j in 0 until listOf.size) {
listOf[j].checkImage.isSelected = false
}
clickType = i
binding.checkImage.isSelected = true
}
}
}
}

View File

@ -0,0 +1,42 @@
package com.ux.video.file.filerecovery.result
import android.graphics.Color
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.core.graphics.drawable.toDrawable
import androidx.fragment.app.DialogFragment
import com.ux.video.file.filerecovery.databinding.DialogExitBinding
import com.ux.video.file.filerecovery.databinding.DialogPermissionBinding
class ExitDialogFragment(val onClickExit: () -> Unit) : DialogFragment() {
private lateinit var binding: DialogExitBinding
override fun onStart() {
super.onStart()
dialog?.window?.apply {
setLayout(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT
)
setBackgroundDrawable(Color.TRANSPARENT.toDrawable())
}
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding = DialogExitBinding.inflate(inflater)
binding.run {
cancel.setOnClickListener { dismiss() }
exit.setOnClickListener {
onClickExit()
dismiss()
}
}
return binding.root
}
}

View File

@ -1,5 +1,6 @@
package com.ux.video.file.filerecovery.result
import android.annotation.SuppressLint
import android.content.Context
import android.view.LayoutInflater
import android.view.ViewGroup
@ -27,15 +28,19 @@ class ScanResultAdapter(
false
)
@SuppressLint("SetTextI18n")
override fun bindItem(
holder: VHolder<ScanResultAdapterBinding>,
item: ResultPhotos
) {
holder.vb.run {
val imageViews = listOf(im1, im2, im3)
item.run {
textDirNameCount.text = "$dirName(${allFiles.size})"
imageViewEnter.setOnClickListener { onClickItem(allFiles) }
textDirNameCount.text = dirName
textFileCounts.text = "(${allFiles.size})"
val takeFiles = allFiles.take(3)
imageViews.forEachIndexed { index, imageView ->
if (index < takeFiles.size) {
@ -59,7 +64,7 @@ class ScanResultAdapter(
.load(file)
.apply(
RequestOptions()
.transform(CenterCrop(), RoundedCorners(15.dpToPx(context)))
.transform(CenterCrop(), RoundedCorners(8.dpToPx(context)))
)
.into(imageView)
}

View File

@ -2,13 +2,27 @@ package com.ux.video.file.filerecovery.result
import android.content.Intent
import android.view.LayoutInflater
import android.view.View
import androidx.activity.OnBackPressedCallback
import androidx.core.view.isVisible
import androidx.recyclerview.widget.LinearLayoutManager
import com.ux.video.file.filerecovery.R
import com.ux.video.file.filerecovery.base.BaseActivity
import com.ux.video.file.filerecovery.databinding.ActivityScanResultDisplayBinding
import com.ux.video.file.filerecovery.photo.PhotoSortingActivity
import com.ux.video.file.filerecovery.photo.ResultPhotos
import com.ux.video.file.filerecovery.result.ScanningActivity
import com.ux.video.file.filerecovery.utils.Common.KEY_SCAN_TYPE
import com.ux.video.file.filerecovery.utils.Common.VALUE_SCAN_TYPE_audio
import com.ux.video.file.filerecovery.utils.Common.VALUE_SCAN_TYPE_deleted_audio
import com.ux.video.file.filerecovery.utils.Common.VALUE_SCAN_TYPE_deleted_documents
import com.ux.video.file.filerecovery.utils.Common.VALUE_SCAN_TYPE_deleted_photo
import com.ux.video.file.filerecovery.utils.Common.VALUE_SCAN_TYPE_deleted_video
import com.ux.video.file.filerecovery.utils.Common.VALUE_SCAN_TYPE_documents
import com.ux.video.file.filerecovery.utils.Common.VALUE_SCAN_TYPE_photo
import com.ux.video.file.filerecovery.utils.Common.VALUE_SCAN_TYPE_video
import com.ux.video.file.filerecovery.utils.ExtendFunctions.getParcelableArrayListExtraCompat
import com.ux.video.file.filerecovery.utils.ScanManager
import com.ux.video.file.filerecovery.utils.ScanRepository
/**
@ -16,9 +30,12 @@ import com.ux.video.file.filerecovery.utils.ScanRepository
*/
class ScanResultDisplayActivity : BaseActivity<ActivityScanResultDisplayBinding>() {
private var scanResultAdapter: ScanResultAdapter? = null
private var scanType: Int = VALUE_SCAN_TYPE_photo
private var exitDialog: ExitDialogFragment? = null
companion object {
val KEY_SCAN_RESULT = "scan_result"
}
override fun inflateBinding(inflater: LayoutInflater): ActivityScanResultDisplayBinding =
@ -28,9 +45,16 @@ class ScanResultDisplayActivity : BaseActivity<ActivityScanResultDisplayBinding>
super.initView()
val list: ArrayList<ResultPhotos>? =
intent.getParcelableArrayListExtraCompat(KEY_SCAN_RESULT)
scanResultAdapter = ScanResultAdapter(this@ScanResultDisplayActivity){ folderLists->
startActivity(Intent(this@ScanResultDisplayActivity, PhotoSortingActivity::class.java).apply {
putParcelableArrayListExtra(PhotoSortingActivity.KEY_PHOTO_FOLDER_FILE, folderLists)
scanResultAdapter = ScanResultAdapter(this@ScanResultDisplayActivity) { folderLists ->
startActivity(
Intent(
this@ScanResultDisplayActivity,
PhotoSortingActivity::class.java
).apply {
putParcelableArrayListExtra(
PhotoSortingActivity.KEY_PHOTO_FOLDER_FILE,
folderLists
)
})
}
binding.recyclerResult.run {
@ -56,4 +80,50 @@ class ScanResultDisplayActivity : BaseActivity<ActivityScanResultDisplayBinding>
// scanResultAdapter?.setData(it)
// }
}
override fun initData() {
super.initData()
scanType = intent.getIntExtra(KEY_SCAN_TYPE, VALUE_SCAN_TYPE_photo)
setSelectTypeTitle(scanType)
binding.imageViewBack.setOnClickListener { dealExit() }
onBackPressedDispatcher.addCallback(
this,
object : OnBackPressedCallback(true) {
override fun handleOnBackPressed() {
dealExit()
}
})
}
private fun dealExit(){
exitDialog = exitDialog?:ExitDialogFragment(){
finish()
}
exitDialog?.show(supportFragmentManager,"")
}
private fun setSelectTypeTitle(fileType: Int) {
binding.run {
when (fileType) {
VALUE_SCAN_TYPE_photo, VALUE_SCAN_TYPE_deleted_photo -> {
title.text = getString(R.string.photo_title)
}
VALUE_SCAN_TYPE_video, VALUE_SCAN_TYPE_deleted_video -> {
title.text = getString(R.string.video_title)
}
VALUE_SCAN_TYPE_audio, VALUE_SCAN_TYPE_deleted_audio -> {
title.text = getString(R.string.audio_title)
}
VALUE_SCAN_TYPE_documents, VALUE_SCAN_TYPE_deleted_documents -> {
title.text = getString(R.string.document_title)
}
}
}
}
}

View File

@ -11,6 +11,15 @@ import com.ux.video.file.filerecovery.main.ScanSelectTypeActivity.Companion.VALU
import com.ux.video.file.filerecovery.main.ScanSelectTypeActivity.Companion.VALUE_DOCUMENT
import com.ux.video.file.filerecovery.main.ScanSelectTypeActivity.Companion.VALUE_PHOTO
import com.ux.video.file.filerecovery.main.ScanSelectTypeActivity.Companion.VALUE_VIDEO
import com.ux.video.file.filerecovery.utils.Common.KEY_SCAN_TYPE
import com.ux.video.file.filerecovery.utils.Common.VALUE_SCAN_TYPE_audio
import com.ux.video.file.filerecovery.utils.Common.VALUE_SCAN_TYPE_deleted_audio
import com.ux.video.file.filerecovery.utils.Common.VALUE_SCAN_TYPE_deleted_documents
import com.ux.video.file.filerecovery.utils.Common.VALUE_SCAN_TYPE_deleted_photo
import com.ux.video.file.filerecovery.utils.Common.VALUE_SCAN_TYPE_deleted_video
import com.ux.video.file.filerecovery.utils.Common.VALUE_SCAN_TYPE_documents
import com.ux.video.file.filerecovery.utils.Common.VALUE_SCAN_TYPE_photo
import com.ux.video.file.filerecovery.utils.Common.VALUE_SCAN_TYPE_video
import com.ux.video.file.filerecovery.utils.ScanManager
import com.ux.video.file.filerecovery.utils.ScanRepository
import com.ux.video.file.filerecovery.utils.ScanState
@ -21,15 +30,15 @@ import kotlinx.coroutines.launch
class ScanningActivity : BaseActivity<ActivityScanningBinding>() {
companion object {
val KEY_SCAN_TYPE = "scan_type"
val VALUE_SCAN_TYPE_photo = 0
val VALUE_SCAN_TYPE_deleted_photo = 1
val VALUE_SCAN_TYPE_video = 2
val VALUE_SCAN_TYPE_deleted_video = 3
val VALUE_SCAN_TYPE_audio = 4
val VALUE_SCAN_TYPE_deleted_audio = 5
val VALUE_SCAN_TYPE_documents = 6
val VALUE_SCAN_TYPE_deleted_documents = 7
// val KEY_SCAN_TYPE = "scan_type"
// val VALUE_SCAN_TYPE_photo = 0
// val VALUE_SCAN_TYPE_deleted_photo = 1
// val VALUE_SCAN_TYPE_video = 2
// val VALUE_SCAN_TYPE_deleted_video = 3
// val VALUE_SCAN_TYPE_audio = 4
// val VALUE_SCAN_TYPE_deleted_audio = 5
// val VALUE_SCAN_TYPE_documents = 6
// val VALUE_SCAN_TYPE_deleted_documents = 7
}
private var scanType: Int = VALUE_SCAN_TYPE_photo
@ -44,7 +53,7 @@ class ScanningActivity : BaseActivity<ActivityScanningBinding>() {
VALUE_SCAN_TYPE_photo, VALUE_SCAN_TYPE_video, VALUE_SCAN_TYPE_audio, VALUE_SCAN_TYPE_documents -> scanAll()
VALUE_SCAN_TYPE_deleted_photo, VALUE_SCAN_TYPE_deleted_video, VALUE_SCAN_TYPE_deleted_audio, VALUE_SCAN_TYPE_deleted_documents -> scanDeleted()
}
binding.scanProgress.setCenterImage(R.drawable.ic_scan_file)
binding.scanProgress.setCenterImage(R.drawable.im_photo_center_image)
binding.imageViewBack.setOnClickListener { finish() }
}
@ -176,6 +185,7 @@ class ScanningActivity : BaseActivity<ActivityScanningBinding>() {
)
}
finish()
}

View File

@ -7,6 +7,7 @@ import android.graphics.BitmapFactory
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.graphics.Path
import android.graphics.RectF
import android.util.AttributeSet
import android.view.View
@ -19,7 +20,7 @@ class CircleImageProgressView @JvmOverloads constructor(
private val paintBg = Paint(Paint.ANTI_ALIAS_FLAG).apply {
style = Paint.Style.STROKE
strokeWidth = 20f
color = Color.parseColor("#C9DDEF") // 背景浅蓝
color = Color.parseColor("#9CC0EC") // 背景浅蓝
}
private val paintProgress = Paint(Paint.ANTI_ALIAS_FLAG).apply {
@ -57,44 +58,42 @@ class CircleImageProgressView @JvmOverloads constructor(
override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
val stroke = paintBg.strokeWidth
val rect = RectF(stroke, stroke, width - stroke, height - stroke)
val radius = (width / 2f) - (stroke / 2f)
// 背景圆环
val rect = RectF(
(width / 2f) - radius,
(height / 2f) - radius,
(width / 2f) + radius,
(height / 2f) + radius
)
// 1. 背景圆环
canvas.drawArc(rect, 0f, 360f, false, paintBg)
// 中心图片
// 2. 中心图片(圆形裁剪)
centerBitmap?.let {
// val left = (width - it.width) / 2f
// val top = (height - it.height) / 2f
// canvas.drawBitmap(it, left, top, null)
val innerRadius = radius - stroke / 2f // 图片只占内圆,不盖住圆环
// val desiredSize = width * imageScale
// val rectDst = RectF(
// (width - desiredSize) / 2f,
// (height - desiredSize) / 2f,
// (width + desiredSize) / 2f,
// (height + desiredSize) / 2f
// )
// canvas.drawBitmap(it, null, rectDst, null)
val innerRadius = (width / 2f) - stroke // 圆环内半径
val left = (width / 2f) - innerRadius
val top = (height / 2f) - innerRadius
val right = (width / 2f) + innerRadius
val bottom = (height / 2f) + innerRadius
val rectDst = RectF(left, top, right, bottom)
// 缩放图片填满内圆区域
// canvas.drawBitmap(it, null, rectDst, null)
val saveCount = canvas.save()
val path = Path().apply {
addCircle(width / 2f, height / 2f, innerRadius, Path.Direction.CW)
}
canvas.clipPath(path)
canvas.drawBitmap(it, null, rectDst, null)
canvas.restoreToCount(saveCount)
}
// 进度圆弧
// 3. 进度圆弧
val sweepAngle = progress * 360f / 100f
canvas.drawArc(rect, -90f, sweepAngle, false, paintProgress)
}
}

View File

@ -4,19 +4,38 @@ import android.content.Context
import android.icu.text.SimpleDateFormat
import android.icu.util.Calendar
import android.os.Environment
import android.util.Log
import android.view.ViewGroup
import com.ux.video.file.filerecovery.App
import com.ux.video.file.filerecovery.R
import com.ux.video.file.filerecovery.photo.ResultPhotosFiles
import com.ux.video.file.filerecovery.utils.ExtendFunctions.dpToPx
import java.util.Date
import java.util.Locale
import kotlin.collections.sortedBy
object Common {
val itemSpacing = 10
val horizontalSpacing = 16
val KEY_SCAN_TYPE = "scan_type"
val VALUE_SCAN_TYPE_photo = 0
val VALUE_SCAN_TYPE_deleted_photo = 1
val VALUE_SCAN_TYPE_video = 2
val VALUE_SCAN_TYPE_deleted_video = 3
val VALUE_SCAN_TYPE_audio = 4
val VALUE_SCAN_TYPE_deleted_audio = 5
val VALUE_SCAN_TYPE_documents = 6
val VALUE_SCAN_TYPE_deleted_documents = 7
val rootDir = Environment.getExternalStorageDirectory()
val dateFormat = SimpleDateFormat("MMM dd yyyy", Locale.ENGLISH)
val dateFormat = SimpleDateFormat("MMMM d,yyyy", Locale.ENGLISH)
val recoveryPhotoDir = "MyAllRecovery/Photo"
/**
* 默认按照日期分类将最新的排前面
* 默认按照日期分类将最新的排前面 降序
*/
fun getSortByDayNewToOld(list: ArrayList<ResultPhotosFiles>): List<Pair<String, List<ResultPhotosFiles>>> {
@ -31,21 +50,21 @@ object Common {
}
/**
* 按照日期排序 时间最早的排前面
* 按照日期排序 时间最早的排前面 升序
*
*/
fun getSortByDayOldToNew(list: List<Pair<String, List<ResultPhotosFiles>>>) =
list.sortedBy { dateFormat.parse(it.first)?.time ?: 0L }
/**
* 按照文件大小排序将最大的排前面
* 按照文件大小排序将最大的排前面 降序
*/
fun getSortBySizeBigToSmall(list: ArrayList<ResultPhotosFiles>) = list.sortedByDescending {
it.size
}
/**
* 按照文件大小排序将最大的排前面
* 按照文件大小排序将最小的排前面 升序
*/
fun getSortBySizeSmallToBig(list: ArrayList<ResultPhotosFiles>) = list.sortedBy {
it.size
@ -77,7 +96,7 @@ object Common {
* @param months 筛选months月之内的数据
*/
fun filterWithinOneMonthByDay(
grouped: List<Pair<String, List<ResultPhotosFiles>>>,months: Int
grouped: List<Pair<String, List<ResultPhotosFiles>>>, months: Int
): List<Pair<String, List<ResultPhotosFiles>>> {
val today = Calendar.getInstance()
val oneMonthAgo = Calendar.getInstance().apply {
@ -89,10 +108,11 @@ object Common {
day != null && !day.before(oneMonthAgo.time) && !day.after(today.time)
}
}
/**
* @param months 筛选months月之内的数据
*/
fun filterWithinOneMonth(list: List<ResultPhotosFiles>,months: Int): List<ResultPhotosFiles> {
fun filterWithinOneMonth(list: List<ResultPhotosFiles>, months: Int): List<ResultPhotosFiles> {
val today = Calendar.getInstance()
val oneMonthAgo = Calendar.getInstance().apply {
add(Calendar.MONTH, -months)
@ -104,4 +124,55 @@ object Common {
}
}
/**
* 设置全部子View的选中
*/
fun setItemSelect(view: ViewGroup, boolean: Boolean) {
for (i in 0 until view.childCount) {
val child = view.getChildAt(i)
child.isSelected = boolean
}
}
/**
* @param list 筛选后的显示的数据
* @param selected 实际选中的数据集合
* @return 显示的选中数量和选中集合
*/
fun checkSelectListContainDate(
list: List<Pair<String, List<ResultPhotosFiles>>>,
selected: Set<String>
): Pair<Int, MutableSet<String>> {
val currentSelected = mutableSetOf<String>()
val totalSelectedCount = list.sumOf { pair ->
pair.second.count {
val isSelected = it.path in selected
if (isSelected) currentSelected.add(it.path.toString())
isSelected
}
}
showLog("-------totalSelectedCount = $totalSelectedCount currentSelected=${currentSelected.size}")
return totalSelectedCount to currentSelected
}
fun checkSelectListContainSize(list: List<ResultPhotosFiles>, selected: Set<String>): Pair<Int, MutableSet<String>> {
val currentSelected = mutableSetOf<String>()
val totalSelectedCount = list.count {
val isSelected = it.path in selected
if (isSelected) currentSelected.add(it.path.toString())
isSelected
}
showLog("-------totalSelectedCount 222=${totalSelectedCount}")
return totalSelectedCount to currentSelected
}
fun showLog(msg: String) {
Log.d("============", msg)
}
}

View File

@ -17,10 +17,15 @@ class CustomTextView @JvmOverloads constructor(
private var alimama: Typeface? = null
}
private var selectedText: String? = null
private var normalText: String? = null
init {
attrs?.let {
val typedArray = context.obtainStyledAttributes(it, R.styleable.CustomTextView)
val type = typedArray.getInt(R.styleable.CustomTextView_fontType, 0)
selectedText = typedArray.getString(R.styleable.CustomTextView_selected_text)
normalText = typedArray.getString(R.styleable.CustomTextView_normal_text)
typedArray.recycle()
Typeface.create("sans-serif-light", Typeface.NORMAL) // Roboto Light
@ -31,9 +36,10 @@ class CustomTextView @JvmOverloads constructor(
0 -> {
typeface = Typeface.create(Typeface.DEFAULT, Typeface.NORMAL)
}
1 -> {
typeface = Typeface.create(Typeface.DEFAULT, Typeface.BOLD)
typeface = Typeface.create("sans-serif-medium", Typeface.NORMAL)
}
2 -> {
@ -43,12 +49,19 @@ class CustomTextView @JvmOverloads constructor(
typeface = alimama
}
3 -> {
typeface = Typeface.create("sans-serif-medium", Typeface.NORMAL)
}
else -> typeface = Typeface.DEFAULT
}
}
}
override fun setSelected(selected: Boolean) {
super.setSelected(selected)
updateText()
}
private fun updateText() {
// Common.showLog("--updateText$isSelected selectedText=${selectedText} normalText=${normalText} text=${text}")
text = if (isSelected) selectedText ?: text else normalText ?: text
}
}

View File

@ -29,11 +29,9 @@ object ExtendFunctions {
}
}
fun RecyclerView.addItemDecorationOnce(decoration: RecyclerView.ItemDecoration) {
for (i in 0 until itemDecorationCount) {
if (getItemDecorationAt(i)::class == decoration::class) {
return // 已经有同类型,避免重复
}
fun RecyclerView.resetItemDecorationOnce(decoration: RecyclerView.ItemDecoration) {
while (itemDecorationCount > 0) {
removeItemDecorationAt(0)
}
addItemDecoration(decoration)
}

View File

@ -3,11 +3,19 @@ package com.ux.video.file.filerecovery.utils
import android.graphics.Rect
import android.view.View
import androidx.recyclerview.widget.RecyclerView
import com.ux.video.file.filerecovery.App
import com.ux.video.file.filerecovery.utils.ExtendFunctions.dpToPx
/**
* @param spanCount 列数
* @param spacing 列与列之间的间距dp
* @param edgeSpacing RecyclerView 左右两边的边距dp
*/
class GridSpacingItemDecoration(
private val spanCount: Int,
private val spacing: Int,
private val includeEdge: Boolean
private val itemSpacing: Int,
private val edgeSpacing: Int
) : RecyclerView.ItemDecoration() {
override fun getItemOffsets(
@ -16,20 +24,31 @@ class GridSpacingItemDecoration(
val position = parent.getChildAdapterPosition(view)
val column = position % spanCount
if (includeEdge) {
outRect.left = spacing - column * spacing / spanCount
outRect.right = (column + 1) * spacing / spanCount
val itemSpacingPx = itemSpacing.dpToPx(App.mAppContext)
val edgePx = edgeSpacing.dpToPx(App.mAppContext)
when (column) {
0 -> { // 第一列
outRect.left = edgePx
outRect.right = itemSpacingPx / 2
}
spanCount - 1 -> { // 最后一列
outRect.left = itemSpacingPx / 2
outRect.right = edgePx
}
else -> { // 中间列
outRect.left = itemSpacingPx / 2
outRect.right = itemSpacingPx / 2
}
}
// 顶部间距(第一行也加)
if (position < spanCount) {
outRect.top = spacing
}
outRect.bottom = spacing
} else {
outRect.left = column * spacing / spanCount
outRect.right = spacing - (column + 1) * spacing / spanCount
if (position >= spanCount) {
outRect.top = spacing
}
outRect.top = itemSpacingPx
}
// 底部间距
outRect.bottom = itemSpacingPx
}
}

View File

@ -6,6 +6,14 @@ import android.util.Log
import com.ux.video.file.filerecovery.photo.ResultPhotos
import com.ux.video.file.filerecovery.photo.ResultPhotosFiles
import com.ux.video.file.filerecovery.result.ScanningActivity
import com.ux.video.file.filerecovery.utils.Common.VALUE_SCAN_TYPE_audio
import com.ux.video.file.filerecovery.utils.Common.VALUE_SCAN_TYPE_deleted_audio
import com.ux.video.file.filerecovery.utils.Common.VALUE_SCAN_TYPE_deleted_documents
import com.ux.video.file.filerecovery.utils.Common.VALUE_SCAN_TYPE_deleted_photo
import com.ux.video.file.filerecovery.utils.Common.VALUE_SCAN_TYPE_deleted_video
import com.ux.video.file.filerecovery.utils.Common.VALUE_SCAN_TYPE_documents
import com.ux.video.file.filerecovery.utils.Common.VALUE_SCAN_TYPE_photo
import com.ux.video.file.filerecovery.utils.Common.VALUE_SCAN_TYPE_video
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.Flow
@ -56,19 +64,19 @@ object ScanManager {
} else {
var fileCheckBoolean: Boolean = false
when (type) {
ScanningActivity.VALUE_SCAN_TYPE_photo -> {
VALUE_SCAN_TYPE_photo -> {
fileCheckBoolean = isFormatFile(file, IMAGE_FILE) && isValidImage(file)
}
ScanningActivity.VALUE_SCAN_TYPE_video -> {
VALUE_SCAN_TYPE_video -> {
fileCheckBoolean = isFormatFile(file, VIDEO_FILE)
}
ScanningActivity.VALUE_SCAN_TYPE_audio -> {
VALUE_SCAN_TYPE_audio -> {
fileCheckBoolean = isFormatFile(file, AUDIO_FILE)
}
ScanningActivity.VALUE_SCAN_TYPE_documents -> {
VALUE_SCAN_TYPE_documents -> {
fileCheckBoolean = file.isFile && isFormatFile(file, DOCUMENT_FILE)
}
}
@ -126,20 +134,20 @@ object ScanManager {
if (insideHidden) {
var fileCheckBoolean: Boolean = false
when (type) {
ScanningActivity.VALUE_SCAN_TYPE_deleted_photo -> {
VALUE_SCAN_TYPE_deleted_photo -> {
fileCheckBoolean =
isFormatFile(file, IMAGE_FILE) && isValidImage(file)
}
ScanningActivity.VALUE_SCAN_TYPE_deleted_video -> {
VALUE_SCAN_TYPE_deleted_video -> {
fileCheckBoolean = isFormatFile(file, VIDEO_FILE)
}
ScanningActivity.VALUE_SCAN_TYPE_deleted_audio -> {
VALUE_SCAN_TYPE_deleted_audio -> {
fileCheckBoolean = isFormatFile(file, AUDIO_FILE)
}
ScanningActivity.VALUE_SCAN_TYPE_deleted_documents -> {
VALUE_SCAN_TYPE_deleted_documents -> {
fileCheckBoolean = file.isFile && isFormatFile(file, DOCUMENT_FILE)
}
}

View File

@ -2,49 +2,78 @@ package com.ux.video.file.filerecovery.utils
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import com.ux.video.file.filerecovery.photo.ResultPhotos
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
class ScanRepository private constructor() {
//---------扫描结果
private val _photoResults = MutableLiveData<List<ResultPhotos>>()
val photoResults: LiveData<List<ResultPhotos>> get() = _photoResults
private val _videoResults = MutableLiveData<List<ResultPhotos>>()
val videoResults: LiveData<List<ResultPhotos>> get() = _videoResults
class ScanRepository : ViewModel() {
// private val _selectedFlow = MutableStateFlow<MutableSet<String>>(mutableSetOf())
// val selectedFlow: StateFlow<MutableSet<String>> = _selectedFlow
//
//
// private val _selectedDisplayFlow = MutableStateFlow<MutableSet<String>>(mutableSetOf())
// val selectedDisplayFlow: StateFlow<MutableSet<String>> = _selectedDisplayFlow
//----------查看指定目录里面的文件
fun setPhotoResults(data: List<ResultPhotos>) {
_photoResults.value = data
}
private val _selectedLiveData = MutableLiveData<Set<String>>(emptySet())
val selectedLiveData: LiveData<Set<String>> = _selectedLiveData
fun setVideoResults(data: List<ResultPhotos>) {
_videoResults.value = data
}
// 当前筛选显示的选中项
private val _selectedDisplayLiveData = MutableLiveData<Set<String>>(emptySet())
val selectedDisplayLiveData: LiveData<Set<String>> = _selectedDisplayLiveData
private val _selectedFlow = MutableStateFlow<Set<String>>(emptySet())
val selectedFlow: StateFlow<Set<String>> = _selectedFlow
fun toggleSelection(isAdd: Boolean, path: String) {
val current = _selectedLiveData.value?.toMutableSet() ?: mutableSetOf()
val currentDisplay = _selectedDisplayLiveData.value?.toMutableSet() ?: mutableSetOf()
fun toggleSelection(boolean: Boolean, path: String) {
val current = _selectedFlow.value.toMutableSet()
if (boolean) {
if (isAdd) {
current.add(path)
ScanManager.showLog("_------", "add selected ${path}")
currentDisplay.add(path)
// Common.showLog( "add selected ${path}")
} else {
current.remove(path)
ScanManager.showLog("_------", "remove selected ${path}")
currentDisplay.remove(path)
// Common.showLog( "remove selected ${path}")
}
_selectedFlow.value = current
Common.showLog( "toggleSelection------------ _selectedDisplayFlow=${_selectedDisplayLiveData.value?.size} _selectedFlow=${_selectedLiveData.value?.size} ")
// LiveData 使用新对象赋值,保证 observer 触发
_selectedLiveData.value = current.toSet()
_selectedDisplayLiveData.value = currentDisplay.toSet()
}
fun checkIsSelect(path: String) : Boolean{
val current = _selectedFlow.value.toMutableSet()
return current.contains(path)
// fun toggleSelection(isAdd: Boolean, path: String) {
// val current = _selectedFlow.value.toMutableSet()
// val currentDisplay = _selectedDisplayFlow.value.toMutableSet()
// if (isAdd) {
// current.add(path)
// currentDisplay.add(path)
// Common.showLog( "add selected ${path}")
// } else {
// current.remove(path)
// currentDisplay.remove(path)
// Common.showLog( "remove selected ${path}")
// }
// _selectedFlow.value = current
// _selectedDisplayFlow.value = currentDisplay
// }
/**
* 数据筛选后重置当前显示的选中集合
*/
fun filterResetDisplayFlow(list: MutableSet<String>){
_selectedDisplayLiveData.value = list.toSet()
Common.showLog( "筛选后重置 _selectedDisplayFlow=${_selectedDisplayLiveData.value?.size} _selectedFlow=${_selectedLiveData.value?.size} ")
}
fun checkIsSelect(path: String): Boolean {
val current = _selectedDisplayLiveData.value
return current?.contains(path) == true
}

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="@color/color_title_blue" android:state_selected="true"/>
<item android:color="@color/main_title" android:state_selected="false"/>
</selector>

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="@color/color_title_blue" android:state_selected="true"/>
<item android:color="@color/switch_track_false" android:state_selected="false"/>
</selector>

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="@color/main_text_blue" android:state_enabled="true"/>
<item android:color="@color/switch_track_true" android:state_enabled="false"/>
</selector>

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="@color/main_text_blue" android:state_enabled="true"/>
<item android:color="@color/switch_track_true" android:state_enabled="false"/>
</selector>

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!-- 开启状态 -->
<item android:color="@color/main_text_blue" android:state_checked="true"/>
<!-- 关闭状态 -->
<item android:color="@color/dividing_line_color" android:state_checked="false"/>
</selector>

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!-- 开启状态 -->
<item android:color="@color/switch_track_true" android:state_checked="true"/>
<!-- 关闭状态 -->
<item android:color="@color/switch_track_false" android:state_checked="false"/>
</selector>

View File

@ -2,6 +2,6 @@
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="8dp"/>
<solid android:color="@color/dialog_btn_stoke"/>
<solid android:color="@color/main_text_blue"/>
</shape>

View File

@ -2,6 +2,6 @@
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="8dp"/>
<stroke android:color="@color/dialog_btn_stoke" android:width="1dp"/>
<stroke android:color="@color/main_text_blue" android:width="1dp"/>
</shape>

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:topRightRadius="8dp" android:bottomRightRadius="8dp"/>
<solid android:color="@color/main_text_blue"/>
</shape>

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:topRightRadius="8dp" android:bottomRightRadius="8dp"/>
<solid android:color="@color/switch_track_true"/>
</shape>

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:topLeftRadius="8dp" android:bottomLeftRadius="8dp"/>
<solid android:color="@color/color_bg"/>
</shape>

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:bottomRightRadius="20dp" android:bottomLeftRadius="20dp"/>
<solid android:color="@color/white" />
</shape>

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:topLeftRadius="8dp" android:bottomLeftRadius="8dp"/>
<solid android:color="@color/white"/>
</shape>

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:topRightRadius="20dp" android:topLeftRadius="20dp" />
<solid android:color="@color/white" />
</shape>

Binary file not shown.

After

Width:  |  Height:  |  Size: 436 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 552 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -0,0 +1,16 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="16dp"
android:height="16dp"
android:viewportWidth="28"
android:viewportHeight="28">
<group>
<clip-path
android:pathData="M14,0L14,0A14,14 0,0 1,28 14L28,14A14,14 0,0 1,14 28L14,28A14,14 0,0 1,0 14L0,14A14,14 0,0 1,14 0z"/>
<path
android:pathData="M14,0L14,0A14,14 0,0 1,28 14L28,14A14,14 0,0 1,14 28L14,28A14,14 0,0 1,0 14L0,14A14,14 0,0 1,14 0z"
android:fillColor="#ffffff"/>
<path
android:pathData="M14,0C11.231,0 8.524,0.821 6.222,2.359C3.92,3.898 2.125,6.084 1.066,8.642C0.006,11.201 -0.271,14.016 0.269,16.731C0.809,19.447 2.143,21.942 4.101,23.899C6.058,25.857 8.553,27.191 11.269,27.731C13.984,28.271 16.799,27.994 19.358,26.934C21.916,25.875 24.102,24.08 25.641,21.778C27.179,19.476 28,16.769 28,14C28,10.287 26.525,6.726 23.899,4.1C21.274,1.475 17.713,0 14,0ZM22.925,10.15L12.425,20.65C12.118,20.869 11.752,20.991 11.375,21C11.003,20.964 10.644,20.844 10.325,20.65L4.025,14.35C3.747,14.071 3.59,13.694 3.59,13.3C3.59,12.906 3.747,12.528 4.025,12.25C4.304,11.972 4.681,11.815 5.075,11.815C5.469,11.815 5.847,11.972 6.125,12.25L11.375,17.5L20.825,8.05C21.116,7.796 21.489,7.657 21.875,7.657C22.261,7.657 22.634,7.796 22.925,8.05C23.089,8.172 23.222,8.33 23.314,8.512C23.406,8.695 23.454,8.896 23.454,9.1C23.454,9.304 23.406,9.506 23.314,9.688C23.222,9.87 23.089,10.028 22.925,10.15Z"
android:fillColor="#0014F0"/>
</group>
</vector>

View File

@ -0,0 +1,16 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="28dp"
android:height="28dp"
android:viewportWidth="28"
android:viewportHeight="28">
<group>
<clip-path
android:pathData="M14,0L14,0A14,14 0,0 1,28 14L28,14A14,14 0,0 1,14 28L14,28A14,14 0,0 1,0 14L0,14A14,14 0,0 1,14 0z"/>
<path
android:pathData="M14,0L14,0A14,14 0,0 1,28 14L28,14A14,14 0,0 1,14 28L14,28A14,14 0,0 1,0 14L0,14A14,14 0,0 1,14 0z"
android:fillColor="#ffffff"/>
<path
android:pathData="M14,0C11.231,0 8.524,0.821 6.222,2.359C3.92,3.898 2.125,6.084 1.066,8.642C0.006,11.201 -0.271,14.016 0.269,16.731C0.809,19.447 2.143,21.942 4.101,23.899C6.058,25.857 8.553,27.191 11.269,27.731C13.984,28.271 16.799,27.994 19.358,26.934C21.916,25.875 24.102,24.08 25.641,21.778C27.179,19.476 28,16.769 28,14C28,10.287 26.525,6.726 23.899,4.1C21.274,1.475 17.713,0 14,0ZM22.925,10.15L12.425,20.65C12.118,20.869 11.752,20.991 11.375,21C11.003,20.964 10.644,20.844 10.325,20.65L4.025,14.35C3.747,14.071 3.59,13.694 3.59,13.3C3.59,12.906 3.747,12.528 4.025,12.25C4.304,11.972 4.681,11.815 5.075,11.815C5.469,11.815 5.847,11.972 6.125,12.25L11.375,17.5L20.825,8.05C21.116,7.796 21.489,7.657 21.875,7.657C22.261,7.657 22.634,7.796 22.925,8.05C23.089,8.172 23.222,8.33 23.314,8.512C23.406,8.695 23.454,8.896 23.454,9.1C23.454,9.304 23.406,9.506 23.314,9.688C23.222,9.87 23.089,10.028 22.925,10.15Z"
android:fillColor="#0014F0"/>
</group>
</vector>

Binary file not shown.

After

Width:  |  Height:  |  Size: 458 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 648 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@ -1,9 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="256dp"
android:height="256dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
<path
android:pathData="M512.2,64.2c-247.4,0 -448,200.6 -448,448s200.6,448 448,448 448,-200.6 448,-448 -200.6,-448 -448,-448zM709,445.6L474.4,632.4c-14.7,11.7 -35.9,9.5 -48,-4.7 -0.5,-0.3 -1,-0.6 -1.4,-1L310.4,543c-15.5,-11.3 -18.8,-33 -7.5,-48.5s33,-18.8 48.5,-7.5l101.3,74.1 213.2,-169.7c15,-11.9 36.8,-9.5 48.7,5.5 11.8,14.9 9.4,36.8 -5.6,48.7z"
android:fillColor="#13227a"/>
</vector>

Binary file not shown.

After

Width:  |  Height:  |  Size: 950 B

View File

@ -1,9 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="256dp"
android:height="256dp"
android:width="16dp"
android:height="16dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
<path
android:pathData="M518,87.1c-235.3,0 -426,190.7 -426,426s190.7,426 426,426 426,-190.7 426,-426 -190.7,-426 -426,-426zM518,855.1c-188.9,0 -342.1,-153.2 -342.1,-342.1S329,170.9 518,170.9s342.1,153.2 342.1,342.1 -153.2,342.1 -342.1,342.1z"
android:fillColor="#13227a"/>
android:fillColor="@color/black"/>
</vector>

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="16dp"
android:height="16dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
<path
android:pathData="M518,87.1c-235.3,0 -426,190.7 -426,426s190.7,426 426,426 426,-190.7 426,-426 -190.7,-426 -426,-426zM518,855.1c-188.9,0 -342.1,-153.2 -342.1,-342.1S329,170.9 518,170.9s342.1,153.2 342.1,342.1 -153.2,342.1 -342.1,342.1z"
android:fillColor="@color/white"/>
</vector>

Binary file not shown.

After

Width:  |  Height:  |  Size: 379 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="12dp"/>
<corners android:bottomRightRadius="8dp" android:bottomLeftRadius="8dp"/>
<solid android:color="@color/color_photo_size_bg"/>
</shape>

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/icon_arrow_up_blue" android:state_selected="true" />
<item android:drawable="@drawable/icon_arrow_down_gray" android:state_selected="false" />
</selector>

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/icon_checkmark_filter" android:state_selected="true" />
<item android:drawable="@android:color/transparent" android:state_selected="false" />
</selector>

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/icon_checkmark_28dp" android:state_selected="true" />
<item android:drawable="@drawable/icon_unselected_28dp" />
</selector>

View File

@ -1,5 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/icon_selected" android:state_selected="true" />
<item android:drawable="@drawable/icon_unselected" />
</selector>

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/icon_checkmark_16dp" android:state_selected="true" />
<item android:drawable="@drawable/icon_unselected_16dp" />
</selector>

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/bg_rectangle_blue_right_8" android:state_enabled="true" />
<item android:drawable="@drawable/bg_rectangle_d5ebff_right_8" android:state_enabled="false" />
</selector>

View File

@ -1,12 +1,211 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
<LinearLayout 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:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white"
android:orientation="vertical"
tools:context=".photo.PhotoSortingActivity">
<RelativeLayout
android:id="@+id/layout_top"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/white"
android:gravity="center_vertical"
android:paddingBottom="9dp"
app:layout_constraintTop_toTopOf="parent">
<ImageView
android:id="@+id/image_view_back"
android:layout_width="wrap_content"
android:layout_height="44dp"
android:paddingHorizontal="13dp"
android:paddingVertical="14dp"
android:src="@drawable/black_return" />
<com.ux.video.file.filerecovery.utils.CustomTextView
android:id="@+id/tv_select_all"
android:layout_width="wrap_content"
android:layout_height="44dp"
android:layout_alignParentEnd="true"
android:gravity="center"
android:paddingHorizontal="16dp"
android:text="@string/select_all"
android:textColor="@color/color_title_blue"
android:textSize="16sp"
app:fontType="bold"
app:normal_text="@string/select_all"
app:selected_text="@string/deselect_all"
tools:ignore="RelativeOverlap" />
<LinearLayout
android:id="@+id/filter_date_layout"
android:layout_width="wrap_content"
android:layout_height="42dp"
android:layout_below="@id/tv_select_all"
android:layout_marginStart="16dp"
android:gravity="center"
android:orientation="horizontal">
<com.ux.video.file.filerecovery.utils.CustomTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/date"
android:textColor="@color/selector_black_blue"
android:textSize="16sp"
app:fontType="bold" />
<ImageView
android:layout_width="8dp"
android:layout_height="4dp"
android:layout_marginStart="8dp"
android:src="@drawable/selector_arrow_up_down" />
</LinearLayout>
<LinearLayout
android:id="@+id/filter_size_layout"
android:layout_width="wrap_content"
android:layout_height="42dp"
android:layout_alignTop="@id/filter_date_layout"
android:layout_marginStart="20dp"
android:layout_toEndOf="@id/filter_date_layout"
android:gravity="center"
android:orientation="horizontal">
<com.ux.video.file.filerecovery.utils.CustomTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/size"
android:textColor="@color/selector_black_blue"
android:textSize="16sp"
app:fontType="bold" />
<ImageView
android:layout_width="8dp"
android:layout_height="4dp"
android:layout_marginStart="8dp"
android:src="@drawable/selector_arrow_up_down" />
</LinearLayout>
<LinearLayout
android:id="@+id/filter_layout_linearlayout"
android:layout_width="wrap_content"
android:layout_height="42dp"
android:layout_alignTop="@id/filter_date_layout"
android:layout_marginStart="20dp"
android:layout_toEndOf="@id/filter_size_layout"
android:gravity="center"
android:orientation="horizontal">
<com.ux.video.file.filerecovery.utils.CustomTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/layout"
android:textColor="@color/selector_black_blue"
android:textSize="16sp"
app:fontType="bold" />
<ImageView
android:layout_width="8dp"
android:layout_height="4dp"
android:layout_marginStart="8dp"
android:src="@drawable/selector_arrow_up_down" />
</LinearLayout>
<ImageView
android:layout_width="47dp"
android:layout_height="16dp"
android:layout_alignTop="@id/filter_date_layout"
android:layout_alignBottom="@id/filter_date_layout"
android:layout_alignParentEnd="true"
android:layout_marginEnd="8dp"
android:id="@+id/im_sort"
android:paddingHorizontal="16dp"
android:src="@drawable/icon_sort" />
<com.ux.video.file.filerecovery.utils.CustomTextView
android:id="@+id/tv_thumbnail_counts"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/filter_date_layout"
android:layout_marginStart="16dp"
android:layout_marginTop="10dp"
android:text="@string/hide_thumbnails"
android:textColor="@color/main_title"
android:textSize="16sp"
app:fontType="bold" />
<com.ux.video.file.filerecovery.utils.CustomTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/tv_thumbnail_counts"
android:layout_alignStart="@id/tv_thumbnail_counts"
android:layout_marginTop="8dp"
android:text="@string/hide_thumbnails_describe"
android:textColor="@color/main_sub_title"
android:textSize="12sp" />
<com.google.android.material.switchmaterial.SwitchMaterial
android:id="@+id/switch_hide_thumbnails"
android:layout_width="wrap_content"
android:layout_height="16dp"
android:layout_alignTop="@id/tv_thumbnail_counts"
android:layout_alignParentEnd="true"
android:layout_marginEnd="16dp"
app:thumbTint="@color/selector_switch_thumb_color"
app:trackTint="@color/selector_switch_track_color" />
</RelativeLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/color_bg">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<com.ux.video.file.filerecovery.utils.CustomTextView
android:id="@+id/tv_delete"
android:layout_width="0dp"
android:layout_height="50dp"
android:layout_marginStart="16dp"
android:layout_marginBottom="16dp"
android:background="@drawable/bg_rectangle_white_left_8"
android:gravity="center"
android:text="@string/delete"
android:textColor="@color/selector_delete_button_enable"
android:textSize="16sp"
app:fontType="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintHorizontal_weight="1"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="@id/tv_recover" />
<com.ux.video.file.filerecovery.utils.CustomTextView
android:id="@+id/tv_recover"
android:layout_width="0dp"
android:layout_height="50dp"
android:layout_marginEnd="16dp"
android:layout_marginBottom="16dp"
android:background="@drawable/selector_recover_button_enable"
android:gravity="center"
android:text="@string/recover"
android:textColor="@color/white"
android:textSize="16sp"
app:fontType="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintHorizontal_weight="1"
app:layout_constraintLeft_toRightOf="@id/tv_delete"
app:layout_constraintRight_toRightOf="parent" />
<TextView
android:id="@+id/tv_select_counts"
@ -14,21 +213,21 @@
android:layout_height="wrap_content"
android:layout_marginStart="20dp"
android:layout_marginTop="20dp"
android:text="@string/app_name" />
android:text="@string/app_name"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Delete"
android:id="@+id/btn_delete"
android:layout_toEndOf="@id/tv_select_counts"/>
<RadioGroup
android:id="@+id/rg_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/tv_select_counts"
android:orientation="horizontal">
android:orientation="horizontal"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent">
<RadioButton
android:id="@+id/rb_columns_2"
@ -55,7 +254,10 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/rg_layout"
android:orientation="horizontal">
android:orientation="horizontal"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent">
<RadioButton
android:id="@+id/btn_size_all"
@ -83,57 +285,42 @@
</RadioGroup>
<RadioGroup
android:id="@+id/linear_date"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/linear_size"
android:orientation="horizontal">
<!-- <RadioGroup-->
<!-- android:id="@+id/linear_date"-->
<!-- android:layout_width="wrap_content"-->
<!-- android:layout_height="wrap_content"-->
<!-- android:layout_below="@id/linear_size"-->
<!-- android:orientation="horizontal">-->
<RadioButton
android:id="@+id/btn_date_all"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="all date" />
<!-- <RadioButton-->
<!-- android:id="@+id/btn_date_all"-->
<!-- android:layout_width="wrap_content"-->
<!-- android:layout_height="wrap_content"-->
<!-- android:text="all date" />-->
<RadioButton
android:id="@+id/btn_date_within_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="within 1 month" />
<!-- <RadioButton-->
<!-- android:id="@+id/btn_date_within_1"-->
<!-- android:layout_width="wrap_content"-->
<!-- android:layout_height="wrap_content"-->
<!-- android:text="within 1 month" />-->
<RadioButton
android:id="@+id/btn_date_customize"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="customize" />
<!-- <RadioButton-->
<!-- android:id="@+id/btn_date_customize"-->
<!-- android:layout_width="wrap_content"-->
<!-- android:layout_height="wrap_content"-->
<!-- android:text="customize" />-->
</RadioGroup>
<!-- </RadioGroup>-->
<ImageView
android:id="@+id/im_select_all"
android:layout_width="36dp"
android:layout_height="36dp"
android:layout_below="@id/linear_date"
android:padding="8dp"
android:src="@drawable/selector_icon_select" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="@id/im_select_all"
android:layout_alignBottom="@id/im_select_all"
android:layout_toEndOf="@id/im_select_all"
android:gravity="center_vertical"
android:text="@string/select_all" />
<RadioGroup
android:id="@+id/linear"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/im_select_all"
android:orientation="horizontal">
android:orientation="horizontal"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent">
<RadioButton
android:id="@+id/btn_date_old_to_new"
@ -160,10 +347,7 @@
android:text="big" />
</RadioGroup>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/linear" />
</androidx.constraintlayout.widget.ConstraintLayout>
</RelativeLayout>
</LinearLayout>

View File

@ -1,47 +1,165 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
<LinearLayout 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:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white"
android:orientation="vertical"
tools:context=".result.ScanResultDisplayActivity">
<TextView
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="44dp"
android:gravity="center_vertical">
<ImageView
android:id="@+id/image_view_back"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:paddingHorizontal="13dp"
android:paddingVertical="14dp"
android:src="@drawable/black_return" />
<com.ux.video.file.filerecovery.utils.CustomTextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:textColor="@color/main_title"
android:textSize="16sp"
app:fontType="bold" />
</RelativeLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/color_bg"
android:orientation="vertical">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="20dp"
android:layout_marginEnd="16dp"
android:background="@drawable/bg_rectangle_white_20"
android:paddingVertical="20dp">
<RelativeLayout
android:id="@+id/relativelayout_finish"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="horizontal"
app:layout_constraintTop_toTopOf="parent">
<ImageView
android:id="@+id/im_finish"
android:layout_width="16dp"
android:layout_height="16dp"
android:layout_centerVertical="true"
android:src="@drawable/icon_finish" />
<com.ux.video.file.filerecovery.utils.CustomTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_toEndOf="@id/im_finish"
android:text="@string/finished"
android:textColor="@color/main_title"
android:textSize="16sp"
app:fontType="bold" />
</RelativeLayout>
<LinearLayout
android:id="@+id/layout_file_counts"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:gravity="center"
android:orientation="vertical"
app:layout_constraintHorizontal_weight="1"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="@id/div_line"
app:layout_constraintTop_toBottomOf="@id/relativelayout_finish">
<com.ux.video.file.filerecovery.utils.CustomTextView
android:id="@+id/text_all_counts"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="13" />
android:text="13"
android:textColor="@color/main_title"
android:textSize="16sp"
app:fontType="bold" />
<TextView
<com.ux.video.file.filerecovery.utils.CustomTextView
android:id="@+id/text_file_type"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/text_all_counts"
android:textSize="14sp"
android:layout_marginTop="8dp"
app:fontType="bold"
android:textColor="@color/main_sub_title"
android:text="photos" />
</LinearLayout>
<TextView
<View
android:id="@+id/div_line"
android:layout_width="1dp"
android:layout_height="18dp"
android:background="@color/dividing_line_color"
app:layout_constraintBottom_toBottomOf="@id/layout_file_counts"
app:layout_constraintLeft_toRightOf="@id/layout_file_counts"
app:layout_constraintRight_toLeftOf="@id/layout_folder_counts"
app:layout_constraintTop_toTopOf="@id/layout_file_counts" />
<LinearLayout
android:id="@+id/layout_folder_counts"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="vertical"
app:layout_constraintHorizontal_weight="1"
app:layout_constraintLeft_toRightOf="@id/div_line"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/relativelayout_finish"
app:layout_constraintTop_toTopOf="@id/layout_file_counts">
<com.ux.video.file.filerecovery.utils.CustomTextView
android:id="@+id/text_dir_count"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="75dp"
android:layout_toEndOf="@id/text_all_counts"
android:text="13" />
android:text="13"
android:textColor="@color/main_title"
android:textSize="16sp"
app:fontType="bold" />
<TextView
<com.ux.video.file.filerecovery.utils.CustomTextView
android:id="@+id/text_dir"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/text_dir_count"
android:layout_alignStart="@id/text_dir_count"
android:textSize="14sp"
android:layout_marginTop="8dp"
app:fontType="bold"
android:textColor="@color/main_sub_title"
android:text="Folders" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_result"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/text_dir"
android:layout_marginTop="35dp" />
android:layout_marginTop="30dp" />
</LinearLayout>
</RelativeLayout>
</LinearLayout>

View File

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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="match_parent"
android:layout_height="50dp"
android:id="@+id/relativelayout"
android:paddingHorizontal="16dp">
<com.ux.video.file.filerecovery.utils.CustomTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:textColor="@color/selector_c7c7cc_blue"
android:textSize="16sp"
app:fontType="bold"
android:id="@+id/text_item"
tools:ignore="RelativeOverlap" />
<ImageView
android:layout_width="16dp"
android:layout_height="12dp"
android:id="@+id/check_image"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:src="@drawable/selector_filter_image_view" />
</RelativeLayout>

View File

@ -0,0 +1,45 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingHorizontal="16dp"
android:paddingVertical="5dp">
<ImageView
android:id="@+id/icon"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_centerVertical="true"
android:src="@drawable/icon_ascending_size" />
<com.ux.video.file.filerecovery.utils.CustomTextView
android:id="@+id/sort_type"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_toEndOf="@id/icon"
android:textColor="@color/main_title"
android:textSize="16sp"
app:fontType="bold" />
<com.ux.video.file.filerecovery.utils.CustomTextView
android:id="@+id/sort_sub_type"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/sort_type"
android:layout_alignStart="@id/sort_type"
android:layout_marginTop="2dp"
android:textColor="@color/main_sub_title"
android:textSize="12sp" />
<ImageView
android:id="@+id/check_image"
android:layout_width="16dp"
android:layout_height="12dp"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:src="@drawable/selector_filter_image_view" />
</RelativeLayout>

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<DatePicker
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -0,0 +1,74 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="20dp"
android:layout_marginEnd="20dp"
android:background="@drawable/bg_rectangle_white_20"
android:orientation="vertical"
android:paddingHorizontal="20dp"
android:paddingVertical="30dp">
<com.ux.video.file.filerecovery.utils.CustomTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/exit_title"
android:textSize="20sp"
app:fontType="bold" />
<com.ux.video.file.filerecovery.utils.CustomTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:lineSpacingExtra="2dp"
android:text="@string/exit_content"
android:textColor="@color/dialog_permission_content"
android:textSize="14sp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="36dp"
android:layout_marginTop="26dp"
android:orientation="horizontal">
<com.ux.video.file.filerecovery.utils.CustomTextView
android:id="@+id/exit"
android:layout_width="match_parent"
android:layout_height="36dp"
android:layout_weight="1"
android:background="@drawable/bg_dialog_btn_cancel_stoke_8"
android:gravity="center"
android:text="@string/exit"
android:textColor="@color/main_text_blue"
android:textSize="14sp"
app:fontType="bold" />
<com.ux.video.file.filerecovery.utils.CustomTextView
android:id="@+id/cancel"
android:layout_width="match_parent"
android:layout_height="36dp"
android:layout_marginStart="20dp"
android:layout_weight="1"
android:background="@drawable/bg_dialog_btn_allow_solid_8"
android:gravity="center"
android:text="@string/cancel"
android:textColor="@color/white"
android:textSize="14sp"
app:fontType="bold" />
</LinearLayout>
</LinearLayout>
</FrameLayout>

View File

@ -10,7 +10,7 @@
android:layout_height="wrap_content"
android:layout_marginStart="20dp"
android:layout_marginEnd="20dp"
android:background="@drawable/bg_dialog_permission_white_20"
android:background="@drawable/bg_rectangle_white_20"
android:orientation="vertical"
android:padding="20dp">
@ -20,7 +20,7 @@
android:layout_height="wrap_content"
android:text="@string/permission_request"
android:textSize="20sp"
app:fontType="medium" />
app:fontType="bold" />
<com.ux.video.file.filerecovery.utils.CustomTextView
android:layout_width="wrap_content"
@ -56,9 +56,9 @@
android:background="@drawable/bg_dialog_btn_cancel_stoke_8"
android:gravity="center"
android:text="@string/cancel"
android:textColor="@color/dialog_btn_stoke"
android:textColor="@color/main_text_blue"
android:textSize="14sp"
app:fontType="medium" />
app:fontType="bold" />
<com.ux.video.file.filerecovery.utils.CustomTextView
android:id="@+id/allow"
@ -71,7 +71,7 @@
android:text="@string/allow"
android:textColor="@color/white"
android:textSize="14sp"
app:fontType="medium" />
app:fontType="bold" />
</LinearLayout>

View File

@ -0,0 +1,82 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/bg_rectangle_white_top_20"
android:orientation="vertical">
<com.ux.video.file.filerecovery.utils.CustomTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="20dp"
android:text="@string/sort_by"
android:textColor="@color/main_title"
android:textSize="20sp"
app:fontType="bold" />
<include
android:id="@+id/ascending_size_layout"
layout="@layout/common_layout_sort_item"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<include
android:id="@+id/descending_size_layout"
layout="@layout/common_layout_sort_item" />
<include
android:id="@+id/ascending_date_layout"
layout="@layout/common_layout_sort_item" />
<include
android:id="@+id/descending_date_layout"
layout="@layout/common_layout_sort_item" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:layout_marginBottom="16dp"
android:orientation="horizontal">
<com.ux.video.file.filerecovery.utils.CustomTextView
android:id="@+id/tv_cancel"
android:layout_width="0dp"
android:layout_height="50dp"
android:layout_marginStart="16dp"
android:layout_weight="1"
android:background="@drawable/bg_rectangle_f5f5fa_left_8"
android:gravity="center"
android:text="@string/cancel"
android:textColor="@color/main_text_blue"
android:textSize="16sp"
app:fontType="bold" />
<com.ux.video.file.filerecovery.utils.CustomTextView
android:id="@+id/tv_ok"
android:layout_width="0dp"
android:layout_height="50dp"
android:layout_marginEnd="16dp"
android:layout_weight="1"
android:background="@drawable/bg_rectangle_blue_right_8"
android:gravity="center"
android:text="@string/ok"
android:textColor="@color/white"
android:textSize="16sp"
app:fontType="bold" />
</LinearLayout>
</LinearLayout>
</FrameLayout>

View File

@ -0,0 +1,40 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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:id="@+id/root_layout"
android:layout_marginEnd="10dp"
android:layout_marginTop="9dp"
android:layout_width="match_parent"
android:layout_height="150dp">
<ImageView
android:id="@+id/image_thumbnail"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<com.ux.video.file.filerecovery.utils.CustomTextView
android:id="@+id/text_size"
android:layout_width="match_parent"
android:layout_height="24dp"
android:layout_alignParentBottom="true"
android:layout_centerVertical="true"
android:paddingStart="6dp"
android:background="@drawable/photo_size_bg"
android:text="150kb"
android:textColor="@color/white"
android:textSize="11sp"
app:fontType="bold"
tools:ignore="RtlSymmetry" />
<ImageView
android:id="@+id/image_select"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingHorizontal="6dp"
android:paddingVertical="6dp"
android:src="@drawable/selector_icon_select_16" />
</RelativeLayout>

View File

@ -0,0 +1,38 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/root_layout"
android:layout_width="match_parent"
android:layout_height="150dp"
android:layout_marginTop="9dp"
android:layout_marginEnd="10dp">
<ImageView
android:id="@+id/image_thumbnail"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<com.ux.video.file.filerecovery.utils.CustomTextView
android:id="@+id/text_size"
android:layout_width="match_parent"
android:layout_height="40dp"
android:layout_alignParentBottom="true"
android:background="@drawable/photo_size_bg"
android:gravity="center_vertical"
android:paddingStart="6dp"
android:text="150kb"
android:textColor="@color/white"
android:textSize="14sp"
app:fontType="bold" />
<ImageView
android:id="@+id/image_select"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingHorizontal="6dp"
android:paddingVertical="6dp"
android:src="@drawable/selector_icon_checkmark_28dp" />
</RelativeLayout>

View File

@ -1,30 +1,51 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
<com.ux.video.file.filerecovery.utils.CustomTextView
android:id="@+id/text_date"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
android:textSize="19sp"
android:text="@string/app_name"
android:textStyle="bold"
android:layout_marginStart="8dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:paddingTop="21dp"
android:text="@string/app_name"
android:textColor="@color/main_title"
android:textSize="16sp"
app:fontType="bold" />
<ImageView
android:layout_width="36dp"
android:layout_height="36dp"
android:padding="8dp"
<com.ux.video.file.filerecovery.utils.CustomTextView
android:id="@+id/text_child_counts"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_toEndOf="@id/text_date"
android:paddingTop="21dp"
android:text="@string/app_name"
android:textColor="@color/main_sub_title"
android:textSize="16sp"
app:fontType="bold" />
<com.ux.video.file.filerecovery.utils.CustomTextView
android:id="@+id/tv_day_all_select"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:id="@+id/im_select_status"
android:src="@drawable/selector_icon_select" />
android:layout_marginEnd="16dp"
android:drawableStart="@drawable/selector_icon_select_16"
android:drawablePadding="4dp"
android:paddingTop="21dp"
android:text="@string/select"
android:textColor="@color/main_title"
android:textSize="16sp"
app:fontType="bold" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_child"
android:layout_width="match_parent"
android:paddingStart="16dp"
android:paddingEnd="6dp"
android:layout_height="wrap_content"
android:layout_below="@id/text_date" />

View File

@ -1,38 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="90dp">
<ImageView
android:id="@+id/image_thumbnail"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:background="@drawable/photo_size_bg">
<TextView
android:id="@+id/text_size"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="5dp"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:text="150kb"
android:textColor="@color/white"
android:textSize="15sp" />
</RelativeLayout>
<ImageView
android:layout_width="36dp"
android:layout_height="36dp"
android:padding="8dp"
android:id="@+id/im_select_status"
android:src="@drawable/selector_icon_select" />
</RelativeLayout>

View File

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<View
android:id="@+id/view_mask"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:alpha="0"
android:visibility="gone"
android:background="@color/popup_windows_mask" />
<LinearLayout
android:id="@+id/parent_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/bg_rectangle_white_bottom_20"
android:orientation="vertical">
</LinearLayout>
</FrameLayout>

View File

@ -5,22 +5,51 @@
android:layout_marginTop="13dp"
android:layout_height="wrap_content">
<TextView
<com.ux.video.file.filerecovery.utils.CustomTextView
android:id="@+id/text_dir_name_count"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="26dp"
android:layout_height="44dp"
android:layout_marginStart="16dp"
android:textColor="@color/main_title"
app:fontType="bold"
android:textSize="16sp"
android:gravity="center"
android:text="@string/allow"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<com.ux.video.file.filerecovery.utils.CustomTextView
android:id="@+id/text_file_counts"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:textColor="@color/main_sub_title"
app:fontType="bold"
android:textSize="16sp"
android:text="@string/allow"
app:layout_constraintBottom_toBottomOf="@id/text_dir_name_count"
app:layout_constraintLeft_toRightOf="@id/text_dir_name_count"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="0dp"
android:id="@+id/image_view_enter"
app:layout_constraintEnd_toEndOf="parent"
android:paddingHorizontal="16dp"
android:paddingVertical="14dp"
app:layout_constraintTop_toTopOf="@id/text_dir_name_count"
app:layout_constraintBottom_toBottomOf="@id/text_dir_name_count"
android:src="@drawable/icon_vector"/>
<ImageView
android:id="@+id/im1"
android:layout_width="0dp"
android:layout_height="120dp"
android:layout_height="102dp"
android:layout_below="@id/text_dir_name_count"
android:layout_marginStart="10dp"
android:layout_marginEnd="7dp"
android:layout_marginStart="16dp"
android:layout_marginEnd="10dp"
android:layout_marginTop="10dp"
android:src="@mipmap/ic_launcher"
app:layout_constraintHorizontal_weight="1"
@ -33,7 +62,7 @@
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_below="@id/text_dir_name_count"
android:layout_marginEnd="7dp"
android:layout_marginEnd="10dp"
android:src="@mipmap/ic_launcher"
app:layout_constraintBottom_toBottomOf="@id/im1"
app:layout_constraintHorizontal_weight="1"
@ -46,7 +75,7 @@
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_below="@id/text_dir_name_count"
android:layout_marginEnd="10dp"
android:layout_marginEnd="16dp"
android:src="@mipmap/ic_launcher"
app:layout_constraintBottom_toBottomOf="@id/im1"
app:layout_constraintHorizontal_weight="1"

View File

@ -2,44 +2,34 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical">
<TextView
<com.ux.video.file.filerecovery.utils.CustomTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/app_name"
android:textSize="29sp"
android:fontFamily="sans-serif"/>
<TextView
app:fontType="bold"/>
<com.ux.video.file.filerecovery.utils.CustomTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/app_name"
android:textSize="29sp"
android:textStyle="bold"
android:fontFamily="sans-serif"/>
<TextView
app:fontType="bold"/>
<com.ux.video.file.filerecovery.utils.CustomTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/app_name"
android:textSize="29sp"
android:fontFamily="sans-serif-light"/>
<TextView
app:fontType="alimama"/>
<com.ux.video.file.filerecovery.utils.CustomTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/app_name"
android:textSize="29sp"
android:fontFamily="sans-serif-thin"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/app_name"
android:textSize="29sp"
android:fontFamily="sans-serif-medium"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/app_name"
android:textSize="29sp"
android:fontFamily="sans-serif-condensed"/>
app:fontType="regular"/>

View File

@ -2,11 +2,12 @@
<resources>
<declare-styleable name="CustomTextView">
<attr name="fontType" format="enum">
<enum name="regular" value="0"/>
<enum name="bold" value="1"/>
<enum name="alimama" value="2"/>
<enum name="medium" value="3"/>
<enum name="regular" value="0" />
<enum name="bold" value="1" />
<enum name="alimama" value="2" />
</attr>
<attr name="selected_text" format="string" />
<attr name="normal_text" format="string" />
</declare-styleable>
<declare-styleable name="CircleImageProgressView">

View File

@ -3,7 +3,7 @@
<color name="black">#FF000000</color>
<color name="white">#FFFFFFFF</color>
<color name="color_scan_select_bg">#DDF6C1</color>
<color name="color_photo_size_bg">#B1A6A6A6</color>
<color name="color_photo_size_bg">#66000000</color>
<color name="main_title">#000000</color>
<color name="main_sub_title">#9696A2</color>
@ -12,6 +12,11 @@
<color name="color_title_start_color">#198BF5</color>
<color name="color_title_end_color">#6D00F2</color>
<color name="dialog_permission_content">#9696A2</color>
<color name="dividing_line_color">#E5E5EA</color>
<color name="main_text_blue">#0014F0</color>
<color name="switch_track_false">#C7C7CC</color>
<color name="switch_track_true">#D5EBFF</color>
<color name="popup_windows_mask">#65000000</color>
<color name="dialog_btn_stoke">#0014F0</color>
</resources>

View File

@ -3,6 +3,8 @@
<string name="scan_all_file">Scan all files</string>
<string name="scan_deleted_files">Scan deleted files</string>
<string name="select_all">Select all</string>
<string name="select">Select</string>
<string name="deselect_all">Deselect all</string>
<string name="size_kb">%.2f KB</string>
@ -31,6 +33,7 @@
<string name="permission_request_promote">We will never share, upload, or send your data without your permission.</string>
<string name="cancel">Cancel</string>
<string name="exit">Exit</string>
<string name="allow">Allow</string>
<string name="scan">Scanning…</string>
<string name="describe_photos">photos</string>
@ -41,4 +44,41 @@
<string name="describe_delete_audios">deleted audios</string>
<string name="describe_documents">documents</string>
<string name="describe_delete_documents">deleted documents</string>
<string name="finished">Finished!</string>
<string name="exit_title">Recoverable files are ready</string>
<string name="exit_content">If you exit,the scanning results will be discarded.Are you sure you want to exit now?</string>
<string name="date">Date</string>
<string name="size">Size</string>
<string name="layout">Layout</string>
<string name="hide_thumbnails">Hide thumbnails (%d)</string>
<string name="hide_thumbnails_describe">Thumbnails refer to photos below 256 pixels</string>
<string name="delete">Delete</string>
<string name="recover">Recover</string>
<string name="delete_placeholder">Delete (%d)</string>
<string name="recover_placeholder">Recover (%d)</string>
<string name="sort_by">Sort by</string>
<string name="asc_size_describe">(Small to large)</string>
<string name="desc_size_describe">(Large to Small)</string>
<string name="asc_date_describe">(Old to new)</string>
<string name="desc_date_describe">(New to old)</string>
<string name="ok">OK</string>
<string-array name="filter_date">
<item>All</item>
<item>within 1 month</item>
<item>within 6 month</item>
<item>within 24 month</item>
<item>Customize</item>
</string-array>
<string-array name="filter_size">
<item>All</item>
<item>0-1 M</item>
<item>1-5 M</item>
<item>>5 M</item>
</string-array>
<string-array name="filter_layout">
<item>2 columns</item>
<item>3 columns</item>
<item>4 columns</item>
</string-array>
</resources>