Commit 9faec8a2 authored by jyx's avatar jyx

视频清理

parent ce010dc7
...@@ -16,7 +16,11 @@ ...@@ -16,7 +16,11 @@
android:supportsRtl="true" android:supportsRtl="true"
android:theme="@style/AppTheme"> android:theme="@style/AppTheme">
<activity android:name=".ui.setting.SettingActivity"></activity> <activity android:name=".ui.setting.SettingActivity"></activity>
<activity android:name=".ui.albumClean.AlbumCleanActivity">
<activity android:name=".ui.albumClean.AlbumCleanActivity" />
<activity
android:name=".ui.multiClean.MultiCleanActivity"
android:launchMode="singleTop">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN" />
...@@ -34,6 +38,22 @@ ...@@ -34,6 +38,22 @@
<activity android:name=".ui.NavigationActivity"> <activity android:name=".ui.NavigationActivity">
</activity> </activity>
<activity
android:name=".ui.PreviewActivity"
android:launchMode="singleTop"
android:theme="@style/CustomerTransparentTheme" />
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths" />
</provider>
</application> </application>
</manifest> </manifest>
\ No newline at end of file
package com.mints.cleaner.adapter package com.mints.cleaner.adapter.albumClean
import android.widget.ImageView import android.widget.ImageView
import com.bumptech.glide.Glide import com.bumptech.glide.Glide
...@@ -11,7 +11,6 @@ import com.mints.cleaner.model.bean.Image ...@@ -11,7 +11,6 @@ import com.mints.cleaner.model.bean.Image
import com.mints.cleaner.util.VersionUtils import com.mints.cleaner.util.VersionUtils
import com.mints.cleaner.widget.RoundCheckBox import com.mints.cleaner.widget.RoundCheckBox
class AlbumCleanAdapter(layoutResId: Int, data: List<Image>) : class AlbumCleanAdapter(layoutResId: Int, data: List<Image>) :
BaseQuickAdapter<Image, BaseViewHolder>(layoutResId, data) { BaseQuickAdapter<Image, BaseViewHolder>(layoutResId, data) {
...@@ -22,7 +21,6 @@ class AlbumCleanAdapter(layoutResId: Int, data: List<Image>) : ...@@ -22,7 +21,6 @@ class AlbumCleanAdapter(layoutResId: Int, data: List<Image>) :
private var mCheckBoxTags = arrayListOf<Int>() private var mCheckBoxTags = arrayListOf<Int>()
private var mSelectListener: OnImageSelectListener? = null private var mSelectListener: OnImageSelectListener? = null
private var mItemClickListener: OnItemClickListener? = null private var mItemClickListener: OnItemClickListener? = null
private val isViewImage = false
private val isAndroidQ: Boolean = VersionUtils.isAndroidQ() private val isAndroidQ: Boolean = VersionUtils.isAndroidQ()
...@@ -30,7 +28,13 @@ class AlbumCleanAdapter(layoutResId: Int, data: List<Image>) : ...@@ -30,7 +28,13 @@ class AlbumCleanAdapter(layoutResId: Int, data: List<Image>) :
helper.getView<ImageView>(R.id.iv_item_album).run { helper.getView<ImageView>(R.id.iv_item_album).run {
Glide.with(mContext).load(if (isAndroidQ) item.uri else item.path) Glide.with(mContext).load(if (isAndroidQ) item.uri else item.path)
.apply(RequestOptions().diskCacheStrategy(DiskCacheStrategy.NONE)) .apply(
RequestOptions()
.centerCrop()
.placeholder(drawable)
.dontAnimate()
.diskCacheStrategy(DiskCacheStrategy.NONE)
)
.into(this) .into(this)
setOnClickListener { setOnClickListener {
...@@ -143,7 +147,7 @@ class AlbumCleanAdapter(layoutResId: Int, data: List<Image>) : ...@@ -143,7 +147,7 @@ class AlbumCleanAdapter(layoutResId: Int, data: List<Image>) :
} }
interface OnItemClickListener { interface OnItemClickListener {
fun onItemClick(image: Image?, position: Int) fun onItemClick(image: Image, position: Int)
} }
} }
\ No newline at end of file
package com.mints.cleaner.adapter.clean package com.mints.cleaner.adapter.home
import android.widget.GridView import android.widget.GridView
import android.widget.SimpleAdapter import android.widget.SimpleAdapter
...@@ -6,21 +6,21 @@ import com.chad.library.adapter.base.BaseMultiItemQuickAdapter ...@@ -6,21 +6,21 @@ import com.chad.library.adapter.base.BaseMultiItemQuickAdapter
import com.chad.library.adapter.base.BaseViewHolder import com.chad.library.adapter.base.BaseViewHolder
import com.mints.cleaner.R import com.mints.cleaner.R
class CleanAdapter : BaseMultiItemQuickAdapter<CleanMultiItem, BaseViewHolder> { class HomeAdapter : BaseMultiItemQuickAdapter<HomeMultiItem, BaseViewHolder> {
constructor(data: List<CleanMultiItem>) : super(data) { constructor(data: List<HomeMultiItem>) : super(data) {
addItemType(CleanMultiItem.ITEM_TOP, R.layout.item_clean_top) addItemType(HomeMultiItem.ITEM_TOP, R.layout.item_clean_top)
addItemType(CleanMultiItem.ITEM_MID, R.layout.item_clean_mid) addItemType(HomeMultiItem.ITEM_MID, R.layout.item_clean_mid)
addItemType(CleanMultiItem.ITEM_BOTTOM, R.layout.item_clean_bottom) addItemType(HomeMultiItem.ITEM_BOTTOM, R.layout.item_clean_bottom)
} }
override fun convert(helper: BaseViewHolder, item: CleanMultiItem?) { override fun convert(helper: BaseViewHolder, item: HomeMultiItem?) {
when (helper.itemViewType) { when (helper.itemViewType) {
CleanMultiItem.ITEM_TOP -> { HomeMultiItem.ITEM_TOP -> {
helper.addOnClickListener(R.id.btn_clean) helper.addOnClickListener(R.id.btn_clean)
} }
CleanMultiItem.ITEM_MID -> { HomeMultiItem.ITEM_MID -> {
val gridView = helper.getView<GridView>(R.id.gv_clean) val gridView = helper.getView<GridView>(R.id.gv_clean)
val simpleAdapter = SimpleAdapter( val simpleAdapter = SimpleAdapter(
gridView.context, gridView.context,
...@@ -36,7 +36,7 @@ class CleanAdapter : BaseMultiItemQuickAdapter<CleanMultiItem, BaseViewHolder> { ...@@ -36,7 +36,7 @@ class CleanAdapter : BaseMultiItemQuickAdapter<CleanMultiItem, BaseViewHolder> {
} }
} }
} }
CleanMultiItem.ITEM_BOTTOM -> { HomeMultiItem.ITEM_BOTTOM -> {
} }
} }
......
package com.mints.cleaner.adapter.clean package com.mints.cleaner.adapter.home
import com.chad.library.adapter.base.entity.MultiItemEntity import com.chad.library.adapter.base.entity.MultiItemEntity
class CleanMultiItem : MultiItemEntity { class HomeMultiItem : MultiItemEntity {
private var itemType: Int = 0 private var itemType: Int = 0
......
package com.mints.cleaner.adapter.impl
// TODO 公用接口回调
\ No newline at end of file
package com.mints.cleaner.adapter.multiClean
import android.widget.ImageView
import android.widget.TextView
import com.bumptech.glide.Glide
import com.bumptech.glide.load.engine.DiskCacheStrategy
import com.bumptech.glide.request.RequestOptions
import com.chad.library.adapter.base.BaseQuickAdapter
import com.chad.library.adapter.base.BaseViewHolder
import com.mints.cleaner.R
import com.mints.cleaner.model.bean.FileBean
import com.mints.cleaner.util.FormatUtils
import com.mints.cleaner.widget.RoundCheckBox
class MultiCleanAdapter(layoutResId: Int, data: List<FileBean>) :
BaseQuickAdapter<FileBean, BaseViewHolder>(layoutResId, data) {
// 选中图片数据
private var mSelectImages = arrayListOf<FileBean>()
// 复选框选中状态
private var mCheckBoxTags = arrayListOf<Int>()
private var mSelectListener: OnImageSelectListener? = null
private var mItemClickListener: OnItemClickListener? = null
override fun convert(helper: BaseViewHolder, item: FileBean) {
helper.getView<ImageView>(R.id.iv_item_multi).run {
Glide.with(mContext).load(item.path)
.apply(
RequestOptions()
.centerCrop()
.placeholder(drawable)
.dontAnimate()
.diskCacheStrategy(DiskCacheStrategy.NONE)
)
.into(this)
setOnClickListener {
mItemClickListener?.let {
it.onItemClick(item, helper.adapterPosition)
}
}
}
helper.getView<TextView>(R.id.tv_item_multi_name).text = item.name
helper.getView<TextView>(R.id.tv_item_multi_size).text = FormatUtils.formatFileSize(item.size)
helper.getView<TextView>(R.id.tv_item_multi_time).text = FormatUtils.formatDuration(item.time)
helper.getView<RoundCheckBox>(R.id.cb_item).run {
setOnCheckedChangeListener(null)
tag = helper.adapterPosition
isChecked = mCheckBoxTags.contains(helper.adapterPosition)
setOnCheckedChangeListener { _, _ ->
if (mSelectImages.contains(item)) {
unSelectImage(item)
} else {
selectImage(item)
}
if (isChecked) {
mCheckBoxTags.add(helper.adapterPosition)
} else {
mCheckBoxTags.remove(helper.adapterPosition)
}
}
}
}
fun setOnImageSelectListener(listener: OnImageSelectListener?) {
mSelectListener = listener
}
fun setOnItemClickListener1(listener: OnItemClickListener?) {
mItemClickListener = listener
}
fun getSelectImageList(): List<FileBean> {
return mSelectImages
}
// 更新数据
fun refreshData(data: List<FileBean>) {
mData = data
notifyDataSetChanged()
}
// 清空复选框标识
fun cleanSelectImage() {
mSelectImages = arrayListOf()
mCheckBoxTags = arrayListOf()
mSelectListener?.let {
it.onImageSelect(mSelectImages.size)
}
notifyDataSetChanged()
}
// 全选
fun fullSelectImage() {
for (index in 0 until mData.size) {
mCheckBoxTags.add(index)
mSelectImages.add(mData[index])
}
mSelectListener?.let {
it.onImageSelect(mSelectImages.size)
}
notifyDataSetChanged()
}
// 取消全选
fun cancelFullSelectImage() {
// 取消全选
mSelectImages = arrayListOf()
mCheckBoxTags = arrayListOf()
mSelectListener?.let {
it.onImageSelect(mSelectImages.size)
}
notifyDataSetChanged()
}
/**
* 选中图片
*/
private fun selectImage(image: FileBean) {
mSelectImages.add(image)
mSelectListener?.let {
it.onImageSelect(mSelectImages.size)
}
}
/**
* 取消选中图片
*/
private fun unSelectImage(file: FileBean) {
mSelectImages.remove(file)
mSelectListener?.let {
it.onImageSelect(mSelectImages.size)
}
}
interface OnImageSelectListener {
fun onImageSelect(
selectCount: Int
)
}
interface OnItemClickListener {
fun onItemClick(file: FileBean, position: Int)
}
}
\ No newline at end of file
package com.mints.cleaner.model.bean package com.mints.cleaner.model.bean
import android.view.View
import androidx.databinding.BaseObservable
import androidx.databinding.Bindable
import com.mints.cleaner.BR
import com.mints.cleaner.R
class CleanHeaderTitle : BaseObservable {
class CleanHeaderTitle(
// 标题内容
var title: Int,
// 左边图标 // 左边图标
var leftIcon: Int, var leftIcon: Int = 0
// 左边图标点击事件 // 左边图标点击事件
var leftAction: () -> Unit, var leftAction: () -> Unit = {}
// 右边文字是否显示 // 右边文字是否显示
val rightInfoVisible: Int, var rightInfoVisible: Int = View.GONE
// 右边文字内容
val rightInfo: String,
// 右边文字点击事件 // 右边文字点击事件
val rightInfoAction: () -> Unit, var rightInfoAction: () -> Unit = {}
// 背景颜色 // 背景颜色
val background: Int var background: Int = R.color.theme
)
\ No newline at end of file @get:Bindable
// 标题内容
var title: String? = null
set(value) {
field = value
notifyPropertyChanged(BR.title)
}
@get:Bindable
// 右边文字内容
var rightInfo: String? = null
set(value) {
field = value
notifyPropertyChanged(BR.rightInfo)
}
constructor(
title: String,
leftIcon: Int,
leftAction: () -> Unit,
rightInfoVisible: Int,
rightInfo: String,
rightInfoAction: () -> Unit,
background: Int
) {
this.title = title
this.leftIcon = leftIcon
this.leftAction = leftAction
this.rightInfo = rightInfo
this.rightInfoVisible = rightInfoVisible
this.rightInfoAction = rightInfoAction
this.background = background
}
}
\ No newline at end of file
package com.mints.cleaner.model.bean
import android.os.Parcel
import android.os.Parcelable
data class FileBean(
val thumbPath: String,
val path: String,
val time: Long,
val modifyTime: Long,
val name: String,
val size: Long
) : Parcelable {
constructor(parcel: Parcel) : this(
parcel.readString()!!,
parcel.readString()!!,
parcel.readLong(),
parcel.readLong(),
parcel.readString()!!,
parcel.readLong()
)
override fun writeToParcel(dest: Parcel?, flags: Int) {
dest?.run {
writeString(thumbPath)
writeString(path)
writeLong(time)
writeLong(modifyTime)
writeString(name)
writeLong(size)
}
}
override fun describeContents(): Int {
return 0
}
companion object CREATOR : Parcelable.Creator<FileBean> {
override fun createFromParcel(parcel: Parcel): FileBean {
return FileBean(parcel)
}
override fun newArray(size: Int): Array<FileBean?> {
return arrayOfNulls(size)
}
}
}
\ No newline at end of file
...@@ -3,7 +3,7 @@ package com.mints.cleaner.model.bean ...@@ -3,7 +3,7 @@ package com.mints.cleaner.model.bean
class HeaderTitle( class HeaderTitle(
// 标题内容 // 标题内容
var title: Int, var title: String,
// 返回箭头是否显示 // 返回箭头是否显示
var leftIconVisible: Int, var leftIconVisible: Int,
// 左边图标 // 左边图标
......
package com.mints.cleaner.model.bean package com.mints.cleaner.model.bean
import android.net.Uri import android.net.Uri
import android.os.Parcel
import android.os.Parcelable
data class Image( data class Image(
val path: String, val path: String,
...@@ -9,4 +11,38 @@ data class Image( ...@@ -9,4 +11,38 @@ data class Image(
val mimeType: String, val mimeType: String,
val uri: Uri, val uri: Uri,
val size: Long val size: Long
) ) : Parcelable {
\ No newline at end of file constructor(parcel: Parcel) : this(
parcel.readString()!!,
parcel.readLong(),
parcel.readString()!!,
parcel.readString()!!,
parcel.readParcelable<Uri>(Uri::class.java.classLoader) as Uri,
parcel.readLong()
)
override fun writeToParcel(dest: Parcel?, flags: Int) {
dest?.run {
writeString(path)
writeLong(time)
writeString(name)
writeString(mimeType)
writeParcelable(uri, 0)
writeLong(size)
}
}
override fun describeContents(): Int {
return 0
}
companion object CREATOR : Parcelable.Creator<Image> {
override fun createFromParcel(parcel: Parcel): Image {
return Image(parcel)
}
override fun newArray(size: Int): Array<Image?> {
return arrayOfNulls(size)
}
}
}
\ No newline at end of file
package com.mints.cleaner.model.repository package com.mints.cleaner.model.repository
import com.mints.cleaner.R import com.mints.cleaner.R
import com.mints.cleaner.adapter.clean.CleanMultiItem import com.mints.cleaner.adapter.home.HomeMultiItem
import com.mints.cleaner.model.api.ApiService import com.mints.cleaner.model.api.ApiService
import com.mints.cleaner.model.api.client.BaseRepository import com.mints.cleaner.model.api.client.BaseRepository
...@@ -18,11 +18,11 @@ class MainRepository(val service: ApiService) : BaseRepository() { ...@@ -18,11 +18,11 @@ class MainRepository(val service: ApiService) : BaseRepository() {
R.mipmap.ic_launcher R.mipmap.ic_launcher
) )
private var multiItemList: ArrayList<CleanMultiItem> = arrayListOf() private var multiItemList: ArrayList<HomeMultiItem> = arrayListOf()
private val gvDataList: MutableList<Map<String, Any>> = ArrayList() private val gvDataList: MutableList<Map<String, Any>> = ArrayList()
fun getHomeData(): ArrayList<CleanMultiItem> { fun getHomeData(): ArrayList<HomeMultiItem> {
for (i in gvNames.indices) { for (i in gvNames.indices) {
val item: MutableMap<String, Any> = HashMap() val item: MutableMap<String, Any> = HashMap()
item["item_gv_icon"] = gvIcons[i] item["item_gv_icon"] = gvIcons[i]
...@@ -31,12 +31,12 @@ class MainRepository(val service: ApiService) : BaseRepository() { ...@@ -31,12 +31,12 @@ class MainRepository(val service: ApiService) : BaseRepository() {
} }
multiItemList = arrayListOf( multiItemList = arrayListOf(
CleanMultiItem(CleanMultiItem.ITEM_TOP), HomeMultiItem(HomeMultiItem.ITEM_TOP),
CleanMultiItem(CleanMultiItem.ITEM_MID, gvDataList), HomeMultiItem(HomeMultiItem.ITEM_MID, gvDataList),
CleanMultiItem(CleanMultiItem.ITEM_BOTTOM), HomeMultiItem(HomeMultiItem.ITEM_BOTTOM),
CleanMultiItem(CleanMultiItem.ITEM_BOTTOM), HomeMultiItem(HomeMultiItem.ITEM_BOTTOM),
CleanMultiItem(CleanMultiItem.ITEM_BOTTOM), HomeMultiItem(HomeMultiItem.ITEM_BOTTOM),
CleanMultiItem(CleanMultiItem.ITEM_BOTTOM) HomeMultiItem(HomeMultiItem.ITEM_BOTTOM)
) )
return multiItemList return multiItemList
......
package com.mints.cleaner.ui
import android.widget.ImageView
import com.bumptech.glide.Glide
import com.bumptech.glide.load.engine.DiskCacheStrategy
import com.bumptech.glide.request.RequestOptions
import com.github.chrisbanes.photoview.PhotoViewAttacher
import com.mints.cleaner.R
import com.mints.cleaner.model.bean.Image
import com.mints.cleaner.util.VersionUtils
import com.mints.core.base.BaseActivity
import kotlinx.android.synthetic.main.activity_preview.*
class PreviewActivity : BaseActivity() {
companion object {
const val IMAGE = "image"
}
private val image: Image by lazy { intent.getParcelableExtra(IMAGE) as Image }
override fun getLayoutResId() = R.layout.activity_preview
override fun initView() {
val photoViewAttacher = PhotoViewAttacher(pv_preview)
pv_preview.scaleType = ImageView.ScaleType.FIT_CENTER
Glide.with(mContext)
.load(if (VersionUtils.isAndroidQ()) image.uri else image.path)
.apply(RequestOptions().diskCacheStrategy(DiskCacheStrategy.NONE)).override(720, 1080)
.into(pv_preview)
photoViewAttacher.update()
photoViewAttacher.setOnPhotoTapListener { _, _, _ ->
onBackPressed()
}
}
override fun initData() {
}
}
\ No newline at end of file
...@@ -6,20 +6,20 @@ import android.view.View ...@@ -6,20 +6,20 @@ import android.view.View
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.GridLayoutManager
import com.mints.cleaner.R import com.mints.cleaner.R
import com.mints.cleaner.adapter.AlbumCleanAdapter import com.mints.cleaner.adapter.albumClean.AlbumCleanAdapter
import com.mints.cleaner.databinding.ActivityAlbumCleanBinding import com.mints.cleaner.databinding.ActivityAlbumCleanBinding
import com.mints.cleaner.model.bean.CleanHeaderTitle import com.mints.cleaner.model.bean.CleanHeaderTitle
import com.mints.cleaner.model.bean.Folder import com.mints.cleaner.model.bean.Folder
import com.mints.cleaner.model.bean.HeaderTitle
import com.mints.cleaner.model.bean.Image import com.mints.cleaner.model.bean.Image
import com.mints.cleaner.ui.PreviewActivity
import com.mints.cleaner.util.FileUtils import com.mints.cleaner.util.FileUtils
import com.mints.cleaner.util.LogUtil import com.mints.cleaner.util.FormatUtils
import com.mints.core.base.BaseVMActivity import com.mints.core.base.BaseVMActivity
import com.mints.ktx.ext.startKtxActivity
import kotlinx.android.synthetic.main.activity_album_clean.* import kotlinx.android.synthetic.main.activity_album_clean.*
import java.io.File import java.io.File
import java.util.* import java.util.*
class AlbumCleanActivity : BaseVMActivity(), AlbumCleanAdapter.OnImageSelectListener, class AlbumCleanActivity : BaseVMActivity(), AlbumCleanAdapter.OnImageSelectListener,
AlbumCleanAdapter.OnItemClickListener { AlbumCleanAdapter.OnItemClickListener {
...@@ -29,7 +29,6 @@ class AlbumCleanActivity : BaseVMActivity(), AlbumCleanAdapter.OnImageSelectList ...@@ -29,7 +29,6 @@ class AlbumCleanActivity : BaseVMActivity(), AlbumCleanAdapter.OnImageSelectList
// 是否全选 // 是否全选
private var flag = false private var flag = false
private var rightInfo = "全选"
private val albumAdapter: AlbumCleanAdapter by lazy { private val albumAdapter: AlbumCleanAdapter by lazy {
AlbumCleanAdapter( AlbumCleanAdapter(
...@@ -41,20 +40,22 @@ class AlbumCleanActivity : BaseVMActivity(), AlbumCleanAdapter.OnImageSelectList ...@@ -41,20 +40,22 @@ class AlbumCleanActivity : BaseVMActivity(), AlbumCleanAdapter.OnImageSelectList
override fun initView() { override fun initView() {
binding.run { binding.run {
title = CleanHeaderTitle( title = CleanHeaderTitle(
R.string.app_name, getString(R.string.album_clean),
R.mipmap.ic_activity_arrow, R.mipmap.ic_activity_arrow,
{ {
onBackPressed() onBackPressed()
}, },
View.VISIBLE, View.VISIBLE,
rightInfo, getString(R.string.full_choice),
{ {
rightInfo = if (!flag) { if (!flag) {
albumAdapter.fullSelectImage() albumAdapter.fullSelectImage()
"取消全选" title?.rightInfo = getString(R.string.cancel_full_choice)
title?.title = "已选中" + albumAdapter.getSelectImageList().size + "项"
} else { } else {
albumAdapter.cancelFullSelectImage() albumAdapter.cancelFullSelectImage()
"全选" title?.rightInfo = getString(R.string.full_choice)
title?.title = getString(R.string.album_clean)
} }
flag = !flag flag = !flag
...@@ -110,24 +111,23 @@ class AlbumCleanActivity : BaseVMActivity(), AlbumCleanAdapter.OnImageSelectList ...@@ -110,24 +111,23 @@ class AlbumCleanActivity : BaseVMActivity(), AlbumCleanAdapter.OnImageSelectList
} }
override fun onImageSelect(selectCount: Int) { override fun onImageSelect(selectCount: Int) {
// 改变 删除按钮数据 // 改变 删除按钮数据
updateBtnText(selectCount) updateBtnText(selectCount)
} }
override fun onItemClick(image: Image?, position: Int) { override fun onItemClick(image: Image, position: Int) {
LogUtil.d("onItemClick: $position") startKtxActivity<PreviewActivity>(value = PreviewActivity.IMAGE to image)
} }
// 删除图片后更新图库 // 删除图片后更新图库
private fun updateAlbum(imgPath: String) { private fun updateAlbum(imgPath: String?) {
val intent = Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE) val intent = Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE)
intent.data = Uri.fromFile(File(imgPath)) intent.data = Uri.fromFile(File(imgPath))
sendBroadcast(intent) sendBroadcast(intent)
} }
// 若有选中图片,改变删除按钮样式,更新数据
private fun updateBtnText(selectCount: Int) { private fun updateBtnText(selectCount: Int) {
// 若有选中图片,改变删除按钮样式,更新数据
if (selectCount > 0) { if (selectCount > 0) {
btn_clean.background = ContextCompat.getDrawable(this, R.drawable.btn_clean_selected) btn_clean.background = ContextCompat.getDrawable(this, R.drawable.btn_clean_selected)
var selectSize = 0L var selectSize = 0L
...@@ -135,7 +135,7 @@ class AlbumCleanActivity : BaseVMActivity(), AlbumCleanAdapter.OnImageSelectList ...@@ -135,7 +135,7 @@ class AlbumCleanActivity : BaseVMActivity(), AlbumCleanAdapter.OnImageSelectList
for (element in selectImageList) { for (element in selectImageList) {
selectSize += element.size selectSize += element.size
} }
val selectSizeStr = FileUtils.formatFileSize(selectSize) val selectSizeStr = FormatUtils.formatFileSize(selectSize)
btn_clean.text = "删除($selectSizeStr)" btn_clean.text = "删除($selectSizeStr)"
} else { } else {
btn_clean.background = ContextCompat.getDrawable(this, R.drawable.btn_clean_unselected) btn_clean.background = ContextCompat.getDrawable(this, R.drawable.btn_clean_unselected)
......
...@@ -103,7 +103,7 @@ object AlbumCleanModel { ...@@ -103,7 +103,7 @@ object AlbumCleanModel {
var folders: ArrayList<Folder>? = null var folders: ArrayList<Folder>? = null
if (cacheImageList == null || isPreload) { if (cacheImageList == null || isPreload) {
val imageList: ArrayList<Image> = loadImage(context) val imageList: ArrayList<Image> = loadImage(context)
Collections.sort(imageList, Comparator<Image> { image, t1 -> imageList.sortWith(Comparator { image, t1 ->
when { when {
image.time > t1.time -> { image.time > t1.time -> {
1 1
......
...@@ -4,7 +4,7 @@ import android.view.LayoutInflater ...@@ -4,7 +4,7 @@ import android.view.LayoutInflater
import android.view.View import android.view.View
import android.widget.Toast import android.widget.Toast
import com.mints.cleaner.R import com.mints.cleaner.R
import com.mints.cleaner.adapter.clean.CleanAdapter import com.mints.cleaner.adapter.home.HomeAdapter
import com.mints.cleaner.databinding.FragmentCleanBinding import com.mints.cleaner.databinding.FragmentCleanBinding
import com.mints.cleaner.model.bean.HeaderTitle import com.mints.cleaner.model.bean.HeaderTitle
import com.mints.cleaner.ui.main.MainViewModel import com.mints.cleaner.ui.main.MainViewModel
...@@ -18,7 +18,7 @@ import org.koin.androidx.viewmodel.ext.android.viewModel ...@@ -18,7 +18,7 @@ import org.koin.androidx.viewmodel.ext.android.viewModel
class HomeFragment : BaseVMFragment<FragmentCleanBinding>(R.layout.fragment_clean) { class HomeFragment : BaseVMFragment<FragmentCleanBinding>(R.layout.fragment_clean) {
private val mainViewModel by viewModel<MainViewModel>() private val mainViewModel by viewModel<MainViewModel>()
private val cleanAdapter by lazy { CleanAdapter(mainViewModel.repository.getHomeData()) } private val cleanAdapter by lazy { HomeAdapter(mainViewModel.repository.getHomeData()) }
override fun initView() { override fun initView() {
binding.run { binding.run {
...@@ -27,7 +27,7 @@ class HomeFragment : BaseVMFragment<FragmentCleanBinding>(R.layout.fragment_clea ...@@ -27,7 +27,7 @@ class HomeFragment : BaseVMFragment<FragmentCleanBinding>(R.layout.fragment_clea
adapter = cleanAdapter adapter = cleanAdapter
title = HeaderTitle( title = HeaderTitle(
R.string.app_name, getString(R.string.app_name),
View.GONE, View.GONE,
R.mipmap.ic_activity_arrow, R.mipmap.ic_activity_arrow,
{}, {},
...@@ -71,7 +71,7 @@ class HomeFragment : BaseVMFragment<FragmentCleanBinding>(R.layout.fragment_clea ...@@ -71,7 +71,7 @@ class HomeFragment : BaseVMFragment<FragmentCleanBinding>(R.layout.fragment_clea
} }
// 网格布局功能点击事件 // 网格布局功能点击事件
setOnGridViewItemClickListener(object : CleanAdapter.OnGridViewItemClickListener { setOnGridViewItemClickListener(object : HomeAdapter.OnGridViewItemClickListener {
override fun onGridViewItemClick(position: Int) { override fun onGridViewItemClick(position: Int) {
when (position) { when (position) {
0 -> { 0 -> {
......
package com.mints.cleaner.ui.multiClean
import android.content.Intent
import android.net.Uri
import android.view.View
import androidx.core.content.ContextCompat
import com.mints.cleaner.R
import com.mints.cleaner.adapter.multiClean.MultiCleanAdapter
import com.mints.cleaner.databinding.ActivityMultiCleanBinding
import com.mints.cleaner.model.bean.CleanHeaderTitle
import com.mints.cleaner.model.bean.FileBean
import com.mints.cleaner.util.FileUtils
import com.mints.cleaner.util.FormatUtils
import com.mints.cleaner.util.IntentUtils
import com.mints.core.base.BaseVMActivity
import kotlinx.android.synthetic.main.activity_album_clean.btn_clean
import kotlinx.android.synthetic.main.activity_multi_clean.*
import java.io.File
import java.util.ArrayList
class MultiCleanActivity : BaseVMActivity(), MultiCleanAdapter.OnImageSelectListener,
MultiCleanAdapter.OnItemClickListener {
private val binding by binding<ActivityMultiCleanBinding>(R.layout.activity_multi_clean)
private val dataList = arrayListOf<FileBean>()
private val multiAdapter: MultiCleanAdapter by lazy {
MultiCleanAdapter(
R.layout.item_multi_clean,
dataList
)
}
// 是否全选
private var flag = false
override fun initView() {
binding.run {
title = CleanHeaderTitle(
getString(R.string.video_clean),
R.mipmap.ic_activity_arrow,
{
onBackPressed()
},
View.VISIBLE,
getString(R.string.full_choice),
{
if (!flag) {
multiAdapter.fullSelectImage()
title?.rightInfo = getString(R.string.cancel_full_choice)
title?.title = "已选中" + multiAdapter.getSelectImageList().size + "项"
} else {
multiAdapter.cancelFullSelectImage()
title?.rightInfo = getString(R.string.full_choice)
title?.title = getString(R.string.album_clean)
}
flag = !flag
},
R.color.theme
)
}
initRecyclerView()
btn_clean.setOnClickListener {
val selectImageList = multiAdapter.getSelectImageList()
if (selectImageList.isEmpty()) return@setOnClickListener
for (element in selectImageList) {
FileUtils.deleteImage(element.path, this)
updateFile(element.path)
}
dataList.removeAll(selectImageList)
multiAdapter.cleanSelectImage()
multiAdapter.notifyDataSetChanged()
}
}
private fun initRecyclerView() {
recyclerview_multi.run {
adapter = multiAdapter
multiAdapter.setOnImageSelectListener(this@MultiCleanActivity)
multiAdapter.setOnItemClickListener1(this@MultiCleanActivity)
}
}
override fun initData() {
MultiCleanModel.loadVideoForSDCard(this, object : MultiCleanModel.DataCallback {
override fun onSuccess(files: ArrayList<FileBean>?) {
files?.let {
dataList.addAll(it)
}
runOnUiThread {
multiAdapter.notifyDataSetChanged()
}
}
})
}
override fun startObserve() {
}
override fun onImageSelect(selectCount: Int) {
// 改变 删除按钮数据
updateBtnText(selectCount)
}
override fun onItemClick(fileBean: FileBean, position: Int) {
val videoFileIntent = IntentUtils.getVideoFileIntent(this, fileBean.path)
startActivity(videoFileIntent)
}
// 删除后更新手机
private fun updateFile(imgPath: String?) {
val intent = Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE)
intent.data = Uri.fromFile(File(imgPath))
sendBroadcast(intent)
}
// 若有选中图片,改变删除按钮样式,更新数据
private fun updateBtnText(selectCount: Int) {
if (selectCount > 0) {
btn_clean.background = ContextCompat.getDrawable(this, R.drawable.btn_clean_selected)
var selectSize = 0L
val selectImageList = multiAdapter.getSelectImageList()
for (element in selectImageList) {
selectSize += element.size
}
val selectSizeStr = FormatUtils.formatFileSize(selectSize)
btn_clean.text = "删除($selectSizeStr)"
} else {
btn_clean.background = ContextCompat.getDrawable(this, R.drawable.btn_clean_unselected)
btn_clean.text = "删除(0KB)"
}
}
}
\ No newline at end of file
package com.mints.cleaner.ui.multiClean
import android.Manifest
import android.content.Context
import android.content.pm.PackageManager
import android.database.ContentObserver
import android.database.Cursor
import android.net.Uri
import android.provider.MediaStore
import androidx.core.content.ContextCompat
import com.mints.cleaner.model.bean.FileBean
import com.mints.cleaner.ui.albumClean.AlbumCleanModel
import com.mints.cleaner.util.UriUtils
import java.io.File
import java.util.*
import kotlin.Comparator
object MultiCleanModel {
/**
* 缓存图片
*/
private var cacheImageList: ArrayList<FileBean>? = null
private var isNeedCache = false
private var observer: PhotoContentObserver? = null
/**
* 预加载图片
*
* @param context
*/
fun preloadAndRegisterContentObserver(context: Context) {
isNeedCache = true
if (observer == null) {
observer = PhotoContentObserver(context.applicationContext)
context.applicationContext.contentResolver.registerContentObserver(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI, false, observer!!
)
}
preload(context)
}
private fun preload(context: Context) {
val hasWriteExternalPermission =
ContextCompat.checkSelfPermission(
context,
Manifest.permission.WRITE_EXTERNAL_STORAGE
)
if (hasWriteExternalPermission == PackageManager.PERMISSION_GRANTED) {
//有权限,加载图片。
loadVideoForSDCard(context, true, null)
}
}
/**
* 清空缓存
*/
fun clearCache(context: Context) {
isNeedCache = false
if (observer != null) {
context.applicationContext.contentResolver.unregisterContentObserver(observer!!)
observer = null
}
Thread(Runnable {
synchronized(AlbumCleanModel::class.java) {
if (cacheImageList != null) {
cacheImageList!!.clear()
cacheImageList = null
}
}
}).start()
}
/**
* 从SDCard加载图片
*
* @param context
* @param callback
*/
fun loadVideoForSDCard(
context: Context,
callback: DataCallback?
) {
loadVideoForSDCard(context, false, callback)
}
/**
* 从SDCard加载图片
*
* @param context
* @param isPreload 是否是预加载
* @param callback
*/
private fun loadVideoForSDCard(
context: Context,
isPreload: Boolean,
callback: DataCallback?
) {
//由于扫描图片是耗时的操作,所以要在子线程处理。
Thread(Runnable {
synchronized(AlbumCleanModel::class.java) {
var files: ArrayList<FileBean>?
if (cacheImageList == null || isPreload) {
val imageList: ArrayList<FileBean> = loadVideo(context)
imageList.sortWith(Comparator { image, t1 ->
when {
image.time > t1.time -> {
1
}
image.time < t1.time -> {
-1
}
else -> {
0
}
}
})
files = imageList
if (isNeedCache) {
cacheImageList = imageList
}
} else {
files = cacheImageList
}
callback?.onSuccess(files)
}
}).start()
}
/**
* 从SDCard加载图片
*
* @param context
* @return
*/
@Synchronized
private fun loadVideo(context: Context): ArrayList<FileBean> {
// 扫描视频
val mImageUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI
val proj = arrayOf(
MediaStore.Video.Thumbnails._ID
, MediaStore.Video.Thumbnails.DATA
, MediaStore.Video.Media.DURATION
, MediaStore.Video.Media.SIZE
, MediaStore.Video.Media.DISPLAY_NAME
, MediaStore.Video.Media.DATE_MODIFIED
)
val mContentResolver = context.contentResolver
val mCursor: Cursor? = mContentResolver.query(
mImageUri,
proj,
MediaStore.Video.Media.MIME_TYPE + "=?",
arrayOf("video/mp4"),
MediaStore.Video.Media.DATE_MODIFIED + " DESC"
)
val files: ArrayList<FileBean> = arrayListOf()
mCursor?.run {
while (moveToNext()) {
// 获取视频的路径
val id = getInt(getColumnIndex(MediaStore.Video.Media._ID))
val path = getString(getColumnIndex(MediaStore.Video.Media.DATA))
// 获取视频的时间长短
val duration = getInt(getColumnIndex(MediaStore.Video.Media.DURATION))
// 获取视频的大小
var size = getLong(getColumnIndex(MediaStore.Video.Media.SIZE))
if (size < 0) {
//某些设备获取size<0,直接计算
size = File(path).length()
}
// 获取视频的名称
val displayName = getString(getColumnIndex(MediaStore.Video.Media.DISPLAY_NAME))
// 获取视频的修改时间
val modifyTime = getLong(getColumnIndex(MediaStore.Video.Media.DATE_MODIFIED))
//提前生成缩略图,再获取:http://stackoverflow.com/questions/27903264/how-to-get-the-video-thumbnail-path-and-not-the-bitmap
MediaStore.Video.Thumbnails.getThumbnail(
context.contentResolver,
id.toLong(),
MediaStore.Video.Thumbnails.MICRO_KIND,
null
)
val projection = arrayOf(
MediaStore.Video.Thumbnails._ID,
MediaStore.Video.Thumbnails.DATA
)
val cursor: Cursor? = context.contentResolver.query(
MediaStore.Video.Thumbnails.EXTERNAL_CONTENT_URI
, projection
, MediaStore.Video.Thumbnails.VIDEO_ID + "=?"
, arrayOf(id.toString()), null
)
var thumbPath = ""
cursor?.run {
while (moveToNext()) {
thumbPath = getString(getColumnIndex(MediaStore.Video.Thumbnails.DATA))
}
close()
}
files.add(
FileBean(
thumbPath, path,
duration.toLong(),
modifyTime,
displayName,
size
)
)
}
close()
}
return files
}
/**
* 检查图片是否存在。ContentResolver查询处理的数据有可能文件路径并不存在。
*
* @param filePath
* @return
*/
private fun checkFileExists(filePath: String): Boolean {
return File(filePath).exists()
}
private fun getPathForAndroidQ(
context: Context,
id: Long
): String? {
return UriUtils.getPathForUri(
context, MediaStore.Images.Media.EXTERNAL_CONTENT_URI.buildUpon()
.appendPath(id.toString()).build()
)
}
/**
* Java文件操作 获取文件扩展名
*/
fun getExtensionName(filename: String?): String {
if (filename != null && filename.isNotEmpty()) {
val dot = filename.lastIndexOf('.')
if (dot > -1 && dot < filename.length - 1) {
return filename.substring(dot + 1)
}
}
return ""
}
/**
* 根据图片路径,获取图片文件夹名称
*
* @param path
* @return
*/
private fun getFolderName(path: String): String {
if (path.isNotEmpty()) {
val strings =
path.split(File.separator.toRegex()).toTypedArray()
if (strings.size >= 2) {
return strings[strings.size - 2]
}
}
return ""
}
interface DataCallback {
fun onSuccess(files: ArrayList<FileBean>?)
}
private class PhotoContentObserver(private val context: Context) :
ContentObserver(null) {
override fun onChange(
selfChange: Boolean,
uri: Uri
) {
super.onChange(selfChange, uri)
preload(context)
}
}
}
\ No newline at end of file
...@@ -14,7 +14,7 @@ class SettingActivity : BaseVMActivity() { ...@@ -14,7 +14,7 @@ class SettingActivity : BaseVMActivity() {
override fun initView() { override fun initView() {
binding.run { binding.run {
title = HeaderTitle( title = HeaderTitle(
R.string.app_name, getString(R.string.app_name),
View.GONE, View.GONE,
R.mipmap.ic_activity_arrow, R.mipmap.ic_activity_arrow,
{}, {},
......
...@@ -11,35 +11,7 @@ import java.text.DecimalFormat ...@@ -11,35 +11,7 @@ import java.text.DecimalFormat
object FileUtils { object FileUtils {
//定义GB的计算常量 fun deleteImage(imgPath: String?, context: Context): Boolean {
private const val GB = 1024 * 1024 * 1024
//定义MB的计算常量
private const val MB = 1024 * 1024
//定义KB的计算常量
private const val KB = 1024
fun formatFileSize(bytes: Long): String {
//格式化小数
val format = DecimalFormat("###.0")
return when {
bytes / GB >= 1 -> {
format.format(bytes.toDouble() / GB) + "GB"
}
bytes / MB >= 1 -> {
format.format(bytes.toDouble() / MB) + "MB"
}
bytes / KB >= 1 -> {
format.format(bytes.toDouble() / KB) + "KB"
}
else -> {
bytes.toString() + "B"
}
}
}
fun deleteImage(imgPath: String, context: Context): Boolean {
val resolver: ContentResolver = context.contentResolver val resolver: ContentResolver = context.contentResolver
val cursor: Cursor = MediaStore.Images.Media.query( val cursor: Cursor = MediaStore.Images.Media.query(
resolver, resolver,
......
package com.mints.cleaner.util
import java.text.DecimalFormat
import kotlin.math.roundToLong
object FormatUtils {
//定义GB的计算常量
private const val GB = 1024 * 1024 * 1024
//定义MB的计算常量
private const val MB = 1024 * 1024
//定义KB的计算常量
private const val KB = 1024
fun formatFileSize(bytes: Long): String {
if (bytes <= 0) return ""
//格式化小数
val format = DecimalFormat("###.0")
return when {
bytes / GB >= 1 -> {
format.format(bytes.toDouble() / GB) + "GB"
}
bytes / MB >= 1 -> {
format.format(bytes.toDouble() / MB) + "MB"
}
bytes / KB >= 1 -> {
format.format(bytes.toDouble() / KB) + "KB"
}
else -> {
bytes.toString() + "B"
}
}
}
fun formatDuration(duration: Long): String {
if (duration <= 0) return ""
var time: String? = ""
val minute: Long = duration / 60000
val seconds: Long = duration % 60000
val second = (seconds.toFloat() / 1000).roundToLong()
if (minute < 10) {
time += "0"
}
time += "$minute:"
if (second < 10) {
time += "0"
}
time += second
return time!!
}
}
\ No newline at end of file
package com.mints.cleaner.util
import android.content.Context
import android.content.Intent
import android.net.Uri
import androidx.core.content.FileProvider
import java.io.File
object IntentUtils {
val isAndroidN = VersionUtils.isAndroidN()
fun openFile(context: Context, filePath: String?): Intent? {
val file = File(filePath)
if (!file.exists()) return null
/* 取得扩展名 */
val end: String =
file.name.substring(file.name.lastIndexOf(".") + 1, file.name.length)
.toLowerCase()
/* 依扩展名的类型决定MimeType */return if (end == "m4a" || end == "mp3" || end == "mid" || end == "xmf" || end == "ogg" || end == "wav") {
getAudioFileIntent(context, filePath)
} else if (end == "3gp" || end == "mp4") {
getAudioFileIntent(context, filePath)
} else if (end == "jpg" || end == "gif" || end == "png" || end == "jpeg" || end == "bmp") {
getImageFileIntent(context, filePath)
} else if (end == "apk") {
getApkFileIntent(context, filePath)
} else if (end == "ppt") {
getPptFileIntent(context, filePath)
} else if (end == "xls") {
getExcelFileIntent(context, filePath)
} else if (end == "doc") {
getWordFileIntent(context, filePath)
} else if (end == "pdf") {
getPdfFileIntent(context, filePath)
} else if (end == "chm") {
getChmFileIntent(context, filePath)
} else if (end == "txt") {
getTextFileIntent(filePath, false)
} else {
getAllIntent(context, filePath)
}
}
//Android获取一个用于打开APK文件的intent
fun getAllIntent(context: Context, param: String?): Intent? {
val intent = Intent()
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
intent.action = Intent.ACTION_VIEW
var uri: Uri?
uri = if (isAndroidN) {
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
FileProvider.getUriForFile(
context,
context.packageName + ".fileprovider",
File(param)
)
} else {
Uri.fromFile(File(param))
}
intent.setDataAndType(uri, "*/*")
return intent
}
//Android获取一个用于打开APK文件的intent
fun getApkFileIntent(context: Context, param: String?): Intent? {
val intent = Intent()
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
intent.action = Intent.ACTION_VIEW
var uri: Uri?
uri = if (isAndroidN) {
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
FileProvider.getUriForFile(
context,
context.packageName + ".fileprovider",
File(param)
)
} else {
Uri.fromFile(File(param))
}
intent.setDataAndType(uri, "application/vnd.android.package-archive")
return intent
}
//Android获取一个用于打开VIDEO文件的intent
fun getVideoFileIntent(context: Context, param: String?): Intent? {
val intent = Intent("android.intent.action.VIEW")
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
intent.putExtra("oneshot", 0)
intent.putExtra("configchange", 0)
var uri: Uri?
uri = if (isAndroidN) {
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
FileProvider.getUriForFile(
context,
context.packageName + ".fileprovider",
File(param)
)
} else {
Uri.fromFile(File(param))
}
intent.setDataAndType(uri, "video/*")
return intent
}
//Android获取一个用于打开AUDIO文件的intent
fun getAudioFileIntent(context: Context, param: String?): Intent? {
val intent = Intent("android.intent.action.VIEW")
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
intent.putExtra("oneshot", 0)
intent.putExtra("configchange", 0)
var uri: Uri?
uri = if (isAndroidN) {
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
FileProvider.getUriForFile(
context,
context.packageName + ".fileprovider",
File(param)
)
} else {
Uri.fromFile(File(param))
}
intent.setDataAndType(uri, "audio/*")
return intent
}
//Android获取一个用于打开Html文件的intent
fun getHtmlFileIntent(param: String?): Intent? {
val uri: Uri = Uri.parse(param).buildUpon().encodedAuthority("com.android.htmlfileprovider")
.scheme("content").encodedPath(param).build()
val intent = Intent("android.intent.action.VIEW")
intent.setDataAndType(uri, "text/html")
return intent
}
//Android获取一个用于打开图片文件的intent
fun getImageFileIntent(context: Context, param: String?): Intent? {
val intent = Intent("android.intent.action.VIEW")
intent.addCategory("android.intent.category.DEFAULT")
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
var uri: Uri?
uri = if (isAndroidN) {
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
FileProvider.getUriForFile(
context,
context.packageName + ".fileprovider",
File(param)
)
} else {
Uri.fromFile(File(param))
}
intent.setDataAndType(uri, "image/*")
return intent
}
//Android获取一个用于打开PPT文件的intent
fun getPptFileIntent(context: Context, param: String?): Intent? {
val intent = Intent("android.intent.action.VIEW")
intent.addCategory("android.intent.category.DEFAULT")
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
var uri: Uri?
uri = if (isAndroidN) {
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
FileProvider.getUriForFile(
context,
context.packageName + ".fileprovider",
File(param)
)
} else {
Uri.fromFile(File(param))
}
intent.setDataAndType(uri, "application/vnd.ms-powerpoint")
return intent
}
//Android获取一个用于打开Excel文件的intent
fun getExcelFileIntent(context: Context, param: String?): Intent? {
val intent = Intent("android.intent.action.VIEW")
intent.addCategory("android.intent.category.DEFAULT")
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
var uri: Uri?
uri = if (isAndroidN) {
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
FileProvider.getUriForFile(
context,
context.packageName + ".fileprovider",
File(param)
)
} else {
Uri.fromFile(File(param))
}
intent.setDataAndType(uri, "application/vnd.ms-excel")
return intent
}
//Android获取一个用于打开Word文件的intent
fun getWordFileIntent(context: Context, param: String?): Intent? {
val intent = Intent("android.intent.action.VIEW")
intent.addCategory("android.intent.category.DEFAULT")
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
var uri: Uri?
uri = if (isAndroidN) {
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
FileProvider.getUriForFile(
context,
context.packageName + ".fileprovider",
File(param)
)
} else {
Uri.fromFile(File(param))
}
intent.setDataAndType(uri, "application/msword")
return intent
}
//Android获取一个用于打开CHM文件的intent
fun getChmFileIntent(context: Context, param: String?): Intent? {
val intent = Intent("android.intent.action.VIEW")
intent.addCategory("android.intent.category.DEFAULT")
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
var uri: Uri?
uri = if (isAndroidN) {
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
FileProvider.getUriForFile(
context,
context.packageName + ".fileprovider",
File(param)
)
} else {
Uri.fromFile(File(param))
}
intent.setDataAndType(uri, "application/x-chm")
return intent
}
//Android获取一个用于打开文本文件的intent
fun getTextFileIntent(param: String?, paramBoolean: Boolean): Intent? {
val intent = Intent("android.intent.action.VIEW")
intent.addCategory("android.intent.category.DEFAULT")
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
if (paramBoolean) {
val uri1: Uri = Uri.parse(param)
intent.setDataAndType(uri1, "text/plain")
} else {
val uri2: Uri = Uri.fromFile(File(param))
intent.setDataAndType(uri2, "text/plain")
}
return intent
}
//Android获取一个用于打开PDF文件的intent
fun getPdfFileIntent(context: Context, param: String?): Intent? {
val intent = Intent("android.intent.action.VIEW")
intent.addCategory("android.intent.category.DEFAULT")
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
var uri: Uri?
uri = if (isAndroidN) {
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
FileProvider.getUriForFile(
context,
context.packageName + ".fileprovider",
File(param)
)
} else {
Uri.fromFile(File(param))
}
intent.setDataAndType(uri, "application/pdf")
return intent
}
}
\ No newline at end of file
...@@ -11,5 +11,4 @@ class RoundCheckBox : androidx.appcompat.widget.AppCompatCheckBox { ...@@ -11,5 +11,4 @@ class RoundCheckBox : androidx.appcompat.widget.AppCompatCheckBox {
constructor(context: Context) : this(context, null) constructor(context: Context) : this(context, null)
} }
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"> <layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<data> <data>
...@@ -15,7 +16,7 @@ ...@@ -15,7 +16,7 @@
<include <include
layout="@layout/clean_header_bar" layout="@layout/clean_header_bar"
title="title" /> app:title="@{title}" />
<androidx.recyclerview.widget.RecyclerView <androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerview_album" android:id="@+id/recyclerview_album"
......
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
<variable
name="title"
type="com.mints.cleaner.model.bean.CleanHeaderTitle" />
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<include
layout="@layout/clean_header_bar"
app:title="@{title}" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerview_multi"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<View style="@style/line_3" />
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/btn_clean"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="20dp"
android:layout_marginTop="10dp"
android:layout_marginEnd="20dp"
android:layout_marginBottom="10dp"
android:background="@drawable/btn_clean_unselected"
android:text="删除(0KB)"
android:textColor="@color/white"
android:textSize="18sp" />
</LinearLayout>
</LinearLayout>
</layout>
\ No newline at end of file
<?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:background="@color/black_01">
<com.github.chrisbanes.photoview.PhotoView
android:id="@+id/pv_preview"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
...@@ -20,8 +20,8 @@ ...@@ -20,8 +20,8 @@
<ImageView <ImageView
android:id="@+id/iv_header_left_clean" android:id="@+id/iv_header_left_clean"
onClick="@{title.leftAction}"
icon="@{title.leftIcon}" icon="@{title.leftIcon}"
onClick="@{title.leftAction}"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_centerVertical="true" android:layout_centerVertical="true"
......
...@@ -2,13 +2,12 @@ ...@@ -2,13 +2,12 @@
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:padding="4dp"> android:padding="2dp">
<ImageView <ImageView
android:id="@+id/iv_item_album" android:id="@+id/iv_item_album"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="150dp" android:layout_height="130dp" />
android:scaleType="centerCrop" />
<com.mints.cleaner.widget.RoundCheckBox <com.mints.cleaner.widget.RoundCheckBox
android:id="@+id/cb_item" android:id="@+id/cb_item"
......
<?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="100dp"
android:gravity="center_vertical">
<ImageView
android:id="@+id/iv_item_multi"
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_marginStart="10dp"
android:src="@mipmap/ic_launcher" />
<TextView
android:id="@+id/tv_item_multi_name"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginTop="10dp"
android:layout_toEndOf="@id/iv_item_multi"
android:ellipsize="middle"
android:singleLine="true"
android:focusable="true"
android:marqueeRepeatLimit="marquee_forever"
android:focusableInTouchMode="true"
android:scrollHorizontally="true"
android:textColor="@color/black"
android:textSize="18sp" />
<TextView
android:id="@+id/tv_item_multi_size"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/tv_item_multi_name"
android:layout_marginStart="10dp"
android:layout_marginTop="10dp"
android:layout_toEndOf="@id/iv_item_multi"
android:textColor="@color/gray"
android:textSize="18sp" />
<TextView
android:id="@+id/tv_item_multi_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/tv_item_multi_name"
android:layout_marginStart="10dp"
android:layout_marginTop="10dp"
android:layout_toEndOf="@id/tv_item_multi_size"
android:textColor="@color/gray"
android:textSize="18sp" />
<com.mints.cleaner.widget.RoundCheckBox
android:id="@+id/cb_item"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true" />
</RelativeLayout>
\ No newline at end of file
...@@ -11,6 +11,8 @@ ...@@ -11,6 +11,8 @@
<color name="theme">#6200EE</color> <color name="theme">#6200EE</color>
<color name="black">#000000</color> <color name="black">#000000</color>
<color name="black_01">#2A2B3D</color>
<color name="gray">#999999</color> <color name="gray">#999999</color>
<color name="gray_01">#F5F5F5</color> <color name="gray_01">#F5F5F5</color>
<color name="gray_02">#E8E8F0</color> <color name="gray_02">#E8E8F0</color>
......
...@@ -23,6 +23,9 @@ ...@@ -23,6 +23,9 @@
<string name="file_clean">文件清理</string> <string name="file_clean">文件清理</string>
<string name="music_clean">音乐清理</string> <string name="music_clean">音乐清理</string>
<string name="album_clean">相册清理</string>
<string name="apk_clean">安装包清理</string>
<string name="video_clean">视频清理</string>
<string name="zip_clean">压缩包清理</string> <string name="zip_clean">压缩包清理</string>
<string name="file_clean_info">释放更多空间</string> <string name="file_clean_info">释放更多空间</string>
<string name="music_clean_info">清理不喜欢的音乐</string> <string name="music_clean_info">清理不喜欢的音乐</string>
...@@ -32,6 +35,9 @@ ...@@ -32,6 +35,9 @@
<string name="feature_set">功能设置</string> <string name="feature_set">功能设置</string>
<string name="about_us">关于我们</string> <string name="about_us">关于我们</string>
<string name="full_choice">全选</string>
<string name="cancel_full_choice">取消全选</string>
<string name="selector_all_image">全部图片</string> <string name="selector_all_image">全部图片</string>
......
...@@ -2,10 +2,15 @@ ...@@ -2,10 +2,15 @@
<!-- Base application theme. --> <!-- Base application theme. -->
<style name="AppTheme" parent="Theme.MaterialComponents.Light.NoActionBar"> <style name="AppTheme" parent="Theme.MaterialComponents.Light.NoActionBar">
<!-- Customize your theme here. --> <!-- Customize your theme here. -->
<!-- <item name="colorPrimary">@color/colorPrimary</item>--> <item name="colorPrimary">@color/colorPrimary</item>
<!-- <item name="colorPrimaryDark">@color/colorPrimaryDark</item>--> <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<!-- <item name="colorAccent">@color/colorAccent</item>--> <item name="colorAccent">@color/colorAccent</item>
<item name="drawerArrowStyle">@style/DrawerArrowStyle</item> <item name="drawerArrowStyle">@style/DrawerArrowStyle</item>
</style>p
<style name="CustomerTransparentTheme" parent="AppTheme">
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowBackground">@android:color/transparent</item>
</style> </style>
<style name="DrawerArrowStyle" parent="Widget.AppCompat.DrawerArrowToggle"> <style name="DrawerArrowStyle" parent="Widget.AppCompat.DrawerArrowToggle">
...@@ -24,4 +29,5 @@ ...@@ -24,4 +29,5 @@
<item name="android:background">@color/gray_02</item> <item name="android:background">@color/gray_02</item>
</style> </style>
</resources> </resources>
\ No newline at end of file
...@@ -4,6 +4,10 @@ import android.view.View ...@@ -4,6 +4,10 @@ import android.view.View
import androidx.databinding.BindingAdapter import androidx.databinding.BindingAdapter
@BindingAdapter("onClick", requireAll = false) @BindingAdapter("onClick", requireAll = false)
fun View.init(action: () -> Unit) { fun View.init(action: (() -> Unit)?) {
setOnClickListener { action() } setOnClickListener {
if (action != null) {
action()
}
}
} }
\ No newline at end of file
...@@ -104,6 +104,7 @@ inline fun <reified T : Context> Context.getIntent( ...@@ -104,6 +104,7 @@ inline fun <reified T : Context> Context.getIntent(
is Array<*> -> putExtra(name, value) is Array<*> -> putExtra(name, value)
is ArrayList<*> -> putExtra(name, value) is ArrayList<*> -> putExtra(name, value)
is Serializable -> putExtra(name, value) is Serializable -> putExtra(name, value)
is Parcelable -> putExtra(name, value)
is BooleanArray -> putExtra(name, value) is BooleanArray -> putExtra(name, value)
is ByteArray -> putExtra(name, value) is ByteArray -> putExtra(name, value)
is ShortArray -> putExtra(name, value) is ShortArray -> putExtra(name, value)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment