Commit 872441d4 authored by wanglei's avatar wanglei

..

parent 679da567
...@@ -159,6 +159,9 @@ dependencies { ...@@ -159,6 +159,9 @@ dependencies {
implementation(libs.okhttp) implementation(libs.okhttp)
implementation(libs.logging.interceptor) implementation(libs.logging.interceptor)
implementation(libs.glide)
annotationProcessor(libs.glide.compiler)
} }
...@@ -23,7 +23,7 @@ object ActivityJumpHelps { ...@@ -23,7 +23,7 @@ object ActivityJumpHelps {
// R.string.junk_scan -> requestPermission(context, launcher) { CleanJunkActivity.start(context) } // R.string.junk_scan -> requestPermission(context, launcher) { CleanJunkActivity.start(context) }
// R.string.battery_info -> BatteryInfoActivity.start(context) // R.string.battery_info -> BatteryInfoActivity.start(context)
// R.string.app_process -> AppProcessActivity.start(context) // R.string.app_process -> AppProcessActivity.start(context)
// R.string.whatsapp_clean -> requestPermission(context, launcher) { WhatsappCleanActivity.start(context) } // R.string.whatsapp_clean -> requestPermission(context, launcher) { com.base.scanqrclear.luma.WhatsappCleanActivity.start(context) }
// R.string.screenshot_clean -> requestPermission(context, launcher) { ScreenshotCleanActivity.start(context) } // R.string.screenshot_clean -> requestPermission(context, launcher) { ScreenshotCleanActivity.start(context) }
// R.string.app_manager -> AppManagerActivity.start(context) // R.string.app_manager -> AppManagerActivity.start(context)
// R.string.large_files -> requestPermission(context, launcher) { LargeFileCleanActivity.start(context) } // R.string.large_files -> requestPermission(context, launcher) { LargeFileCleanActivity.start(context) }
...@@ -39,7 +39,7 @@ object ActivityJumpHelps { ...@@ -39,7 +39,7 @@ object ActivityJumpHelps {
) { ) {
when (notificationId) { when (notificationId) {
// ID_CLEAN_JUNK -> requestPermission(context, launcher) { CleanJunkActivity.start(context) } // ID_CLEAN_JUNK -> requestPermission(context, launcher) { CleanJunkActivity.start(context) }
// ID_WHATSAPP -> requestPermission(context, launcher) { WhatsappCleanActivity.start(context) } // ID_WHATSAPP -> requestPermission(context, launcher) { com.base.scanqrclear.luma.WhatsappCleanActivity.start(context) }
// ID_LARGE_FILE_CLEANER -> requestPermission(context, launcher) { LargeFileCleanActivity.start(context) } // ID_LARGE_FILE_CLEANER -> requestPermission(context, launcher) { LargeFileCleanActivity.start(context) }
// ID_PHOTO_COMPRESSION -> requestPermission(context, launcher) { PhotoCompressionActivity.start(context) } // ID_PHOTO_COMPRESSION -> requestPermission(context, launcher) { PhotoCompressionActivity.start(context) }
// ID_SCREENSHOT_CLEAN -> requestPermission(context, launcher) { ScreenshotCleanActivity.start(context) } // ID_SCREENSHOT_CLEAN -> requestPermission(context, launcher) { ScreenshotCleanActivity.start(context) }
...@@ -59,7 +59,7 @@ object ActivityJumpHelps { ...@@ -59,7 +59,7 @@ object ActivityJumpHelps {
when (notificationId) { when (notificationId) {
// ID_CLEAN_JUNK -> CleanJunkActivity.start(context) // ID_CLEAN_JUNK -> CleanJunkActivity.start(context)
// ID_WHATSAPP -> WhatsappCleanActivity.start(context) // ID_WHATSAPP -> com.base.scanqrclear.luma.WhatsappCleanActivity.start(context)
// ID_BATTERY_INFO -> BatteryInfoActivity.start(context) // ID_BATTERY_INFO -> BatteryInfoActivity.start(context)
// ID_LARGE_FILE_CLEANER -> LargeFileCleanActivity.start(context) // ID_LARGE_FILE_CLEANER -> LargeFileCleanActivity.start(context)
// ID_PHOTO_COMPRESSION -> PhotoCompressionActivity.start(context) // ID_PHOTO_COMPRESSION -> PhotoCompressionActivity.start(context)
......
package com.base.scanqrclear.luma
import android.app.ActivityManager
import android.content.Context
import android.os.Environment
import android.os.StatFs
object AppHelps {
fun getMemTotal(context: Context): Long {
val activityManager = context.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
val memoryInfo = ActivityManager.MemoryInfo()
activityManager.getMemoryInfo(memoryInfo)
return memoryInfo.totalMem
}
fun getMemAvailable(context: Context): Long {
val activityManager = context.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
val memoryInfo = ActivityManager.MemoryInfo()
activityManager.getMemoryInfo(memoryInfo)
return memoryInfo.availMem
}
fun getTotalExternalSize(): Long {
try {
val statFs = StatFs(Environment.getExternalStorageDirectory().path)
val statFs2 = StatFs(Environment.getRootDirectory().path)
val blockSizeLong =
statFs2.blockSizeLong * statFs2.blockCountLong + statFs.blockSizeLong * statFs.blockCountLong
return calculateTotalExternal(blockSizeLong)
} catch (e: Exception) {
return 0
}
}
fun getAvailableExternalSize(): Long {
try {
val statFs = StatFs(Environment.getExternalStorageDirectory().path)
val statFs2 = StatFs(Environment.getRootDirectory().path)
val blackSize =
statFs2.blockSizeLong * statFs2.availableBlocksLong + statFs.blockSizeLong * statFs.availableBlocksLong
return calculateAvailableExternal(blackSize)
} catch (e: Exception) {
return 0
}
}
private fun calculateTotalExternal(size: Long): Long {
var powerOfTwo: Long = 1
while (powerOfTwo < size) {
powerOfTwo *= 2
}
return powerOfTwo
}
private fun calculateAvailableExternal(size: Long): Long {
var value = size
var n = 0
while (true) {
val m: Long = 1000
if (value < m) {
break
}
value /= m
n++
}
for (i in 0 until n) {
value *= 1024
}
return value
}
fun Context.dpToPx(dp: Int): Float {
val density = resources.displayMetrics.density
return dp * density
}
}
\ No newline at end of file
...@@ -229,7 +229,7 @@ open class BaseActivity2 : AppCompatActivity() { ...@@ -229,7 +229,7 @@ open class BaseActivity2 : AppCompatActivity() {
// is LargeFileCleanActivity -> exit(ExitType.LARGE_FILE) // is LargeFileCleanActivity -> exit(ExitType.LARGE_FILE)
// is ScreenshotCleanActivity -> exit(ExitType.SCREENSHOT) // is ScreenshotCleanActivity -> exit(ExitType.SCREENSHOT)
// is SimilarPhotosActivity -> exit(ExitType.SIMILAR_PHOTOS) // is SimilarPhotosActivity -> exit(ExitType.SIMILAR_PHOTOS)
// is WhatsappCleanActivity -> exit(ExitType.WHATSAPP) // is com.base.scanqrclear.luma.WhatsappCleanActivity -> exit(ExitType.WHATSAPP)
// is PhotoCompressionActivity -> exit(ExitType.PHOTO_COMPRESSION) // is PhotoCompressionActivity -> exit(ExitType.PHOTO_COMPRESSION)
// else -> finishOrToMain() // else -> finishOrToMain()
} }
......
package com.base.scanqrclear.luma
import android.media.tv.TvTrackInfo.TYPE_AUDIO
import android.media.tv.TvTrackInfo.TYPE_VIDEO
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import com.base.scanqrclear.R
import com.bumptech.glide.load.resource.bitmap.RoundedCorners
import com.base.scanqrclear.databinding.ItemCleanDetailBinding
import com.base.scanqrclear.luma.AppHelps.dpToPx
import com.bumptech.glide.Glide
import com.bumptech.glide.load.resource.bitmap.CenterCrop
import com.bumptech.glide.request.RequestOptions
class CleanDetailAdapter(
var data: List<FileBean>,
private val type: Int = TYPE_VIDEO
) : BaseAdapter<FileBean, ItemCleanDetailBinding>(data) {
constructor(type: Int = TYPE_VIDEO) : this(emptyList(), type)
override fun getViewBinding(
layoutInflater: LayoutInflater,
parent: ViewGroup
): ItemCleanDetailBinding {
return ItemCleanDetailBinding.inflate(layoutInflater, parent, false)
}
override fun bind(
holder: BaseViewHolder<ItemCleanDetailBinding>,
position: Int,
item: FileBean
) {
if (type == TYPE_AUDIO) {
holder.binding.clVideoImage.visibility = View.GONE
holder.binding.clAudio.visibility = View.VISIBLE
holder.itemView.layoutParams =
ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
holder.binding.tvAudioName.text = item.name
holder.binding.tvAudioSize.text = Utils.getSize(item.length)
setSelection(holder.binding.ivAudioSelect, item)
holder.binding.viewLine.visibility = if (position == itemCount - 1) View.GONE else View.VISIBLE
holder.itemView.setOnClickListener {
item.isSelected = !item.isSelected
setSelection(holder.binding.ivAudioSelect, item)
callback?.onClicked(it, position, item)
}
} else {
holder.binding.clVideoImage.visibility = View.VISIBLE
holder.binding.clAudio.visibility = View.GONE
holder.binding.ivVideo.visibility = if (type == TYPE_VIDEO) View.VISIBLE else View.GONE
holder.itemView.layoutParams =
ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT)
val width = holder.itemView.context.resources.displayMetrics.widthPixels
val margin = holder.itemView.context.dpToPx(44).toInt()
val imageWidth = (width - margin) / 3
holder.binding.ivImage.layoutParams.width = imageWidth
holder.binding.ivImage.layoutParams.height = imageWidth
val round = holder.itemView.context.dpToPx(8).toInt()
val options = RequestOptions().transform(CenterCrop(), RoundedCorners(round))
Glide.with(holder.itemView.context)
.load(item.path)
.apply(options)
.into(holder.binding.ivImage)
holder.binding.tvSize.text = Utils.getSize(item.length)
holder.binding.ivVideo.visibility = if (type == 0) View.VISIBLE else View.GONE
setSelection(holder.binding.ivSelect, item)
holder.itemView.setOnClickListener {
item.isSelected = !item.isSelected
setSelection(holder.binding.ivSelect, item)
callback?.onClicked(it, position, item)
}
}
}
private fun setSelection(imageView: ImageView, item: FileBean) {
imageView.setImageResource(if (item.isSelected) R.mipmap.icon_yuan_junk_s else R.mipmap.icon_yuan_n)
}
}
\ No newline at end of file
package com.base.scanqrclear.luma
import android.webkit.MimeTypeMap
object MineTypeHelps {
val TYPE_VIDEO = 0
val TYPE_IMAGE = 1
val TYPE_AUDIO = 2
val mineTypes by lazy {
listOf(
"image/",
"video/",
"audio/",
"text/",
MimeTypeMap.getSingleton().getMimeTypeFromExtension("pdf") ?: "",
MimeTypeMap.getSingleton().getMimeTypeFromExtension("doc") ?: "",
MimeTypeMap.getSingleton().getMimeTypeFromExtension("docx") ?: "",
MimeTypeMap.getSingleton().getMimeTypeFromExtension("xls") ?: "",
MimeTypeMap.getSingleton().getMimeTypeFromExtension("xlsx") ?: "",
MimeTypeMap.getSingleton().getMimeTypeFromExtension("ppt") ?: "",
MimeTypeMap.getSingleton().getMimeTypeFromExtension("apk") ?: "",
)
}
val images = listOf(".jpeg", ".jpg", ".png", ".gif", ".webp", ".ico", ".raw") // 图像
val videos = listOf(".mp4", ".avi", ".mov", ".wmv", ".flv") // 视频
val audios = listOf(".mp3", ".wav", ".m4a", ".ncm") // 音频
fun isImage(mineType: String): Boolean {
return mineType.startsWith(mineTypes[0])
}
fun isVideo(mineType: String): Boolean {
return mineType.startsWith(mineTypes[1])
}
fun isAudio(mineType: String): Boolean {
return mineType.startsWith(mineTypes[2])
}
fun isDoc(mineType: String): Boolean {
return mineType.startsWith(mineTypes[3])
|| mineType.startsWith(mineTypes[4])
|| mineType.startsWith(mineTypes[5])
|| mineType.startsWith(mineTypes[6])
|| mineType.startsWith(mineTypes[7])
|| mineType.startsWith(mineTypes[8])
|| mineType.startsWith(mineTypes[9])
}
fun isApk(mineType: String): Boolean {
return mineType.startsWith(mineTypes[10])
}
}
\ No newline at end of file
...@@ -3,7 +3,6 @@ package com.base.scanqrclear.luma ...@@ -3,7 +3,6 @@ package com.base.scanqrclear.luma
import android.content.Context import android.content.Context
import java.math.BigDecimal import java.math.BigDecimal
import java.math.RoundingMode import java.math.RoundingMode
import java.text.DecimalFormat
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.Calendar import java.util.Calendar
import java.util.Date import java.util.Date
......
package com.base.scanqrclear.luma
import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.view.View
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.GridLayoutManager
import com.base.scanqrclear.R
import com.base.scanqrclear.databinding.ActivityWhatsappCleanBinding
import com.base.scanqrclear.luma.MineTypeHelps.TYPE_AUDIO
import com.base.scanqrclear.luma.MineTypeHelps.TYPE_IMAGE
import com.base.scanqrclear.luma.MineTypeHelps.TYPE_VIDEO
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.async
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.util.Locale
class WhatsappCleanActivity : BaseActivity2() {
companion object {
fun start(context: Context) {
val intent = Intent(context, WhatsappCleanActivity::class.java)
context.startActivity(intent)
}
}
private val binding by lazy {
ActivityWhatsappCleanBinding.inflate(layoutInflater)
}
private lateinit var videoAdapter: WhatsappCleanAdapter
private lateinit var imageAdapter: WhatsappCleanAdapter
private var videoList = listOf<FileBean>()
private var imageList = listOf<FileBean>()
private var audioList = listOf<FileBean>()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(binding.root)
initView()
initData()
showAnimationAd(LottieType.WHATSAPP)
}
private fun initView() {
videoAdapter = WhatsappCleanAdapter(TYPE_VIDEO)
binding.rvVideo.adapter = videoAdapter
binding.rvVideo.layoutManager = GridLayoutManager(this, 3, GridLayoutManager.VERTICAL, false)
imageAdapter = WhatsappCleanAdapter(TYPE_IMAGE)
binding.rvImage.adapter = imageAdapter
binding.rvImage.layoutManager = GridLayoutManager(this, 3, GridLayoutManager.VERTICAL, false)
binding.viewVideo.setOnClickListener {
toDetail(videoList, videoAdapter.type, getString(R.string.video_messages))
}
binding.viewImage.setOnClickListener {
toDetail(imageList, imageAdapter.type, getString(R.string.image_messages))
}
binding.flBack.setOnClickListener { backPressed() }
binding.clVideoMessage.setOnClickListener { toDetail(videoList, videoAdapter.type, getString(R.string.video_messages)) }
binding.clImageMessage.setOnClickListener { toDetail(imageList, imageAdapter.type, getString(R.string.image_messages)) }
binding.llAudioMessage.setOnClickListener { toDetail(audioList, TYPE_AUDIO, getString(R.string.audio_messages)) }
}
private fun initData() {
lifecycleScope.launch(Dispatchers.IO) {
val filesDeferred = async { FileHelps.findWhatsappFiles() }
val files = filesDeferred.await()
videoList = files.filter { file ->
MineTypeHelps.videos.any { suffix -> file.name.lowercase(Locale.ROOT).endsWith(suffix) }
}
imageList = files.filter { file ->
MineTypeHelps.images.any { suffix -> file.name.lowercase(Locale.ROOT).endsWith(suffix) }
}
audioList = files.filter { file ->
MineTypeHelps.audios.any { suffix -> file.name.lowercase(Locale.ROOT).endsWith(suffix) }
}
val videoSize = videoList.sumOf { it.length }
val imageSize = imageList.sumOf { it.length }
val audioSize = audioList.sumOf { it.length }
val total = videoSize + imageSize + audioSize
val value = Utils.getSizeArray(total)
withContext(Dispatchers.Main) {
binding.tvSize.text = value[0]
binding.tvUnit.text = value[1]
binding.tvVideoSize.text = Utils.getSize(videoSize)
binding.tvImageSize.text = Utils.getSize(imageSize)
binding.tvAudioSize.text = Utils.getSize(audioSize)
binding.tvNoVideo.visibility = if (videoList.isEmpty()) View.VISIBLE else View.GONE
binding.tvNoImage.visibility = if (imageList.isEmpty()) View.VISIBLE else View.GONE
val textColor = if (videoList.isEmpty()) getColor(R.color.color_aeb4bd) else getColor(R.color.colorPrimary)
binding.tvVideoSize.setTextColor(textColor)
binding.tvImageSize.setTextColor(textColor)
binding.tvAudioSize.setTextColor(textColor)
if (audioList.isNotEmpty()) {
val foundVoiceMessage = getString(R.string.found_voice_message).replace("3", "${audioList.size}")
binding.tvNoAudio.text = foundVoiceMessage
}
videoAdapter.updateData(videoList)
imageAdapter.updateData(imageList)
}
}
}
private fun toDetail(list: List<FileBean>, type: Int, title: String) {
if (list.isEmpty()) return
list.forEach { it.isSelected = false }
WhatsappCleanDetailActivity.start(this, list, type, title)
}
}
\ No newline at end of file
package com.base.scanqrclear.luma
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.base.scanqrclear.databinding.ItemWhatsappCleanBinding
import com.base.scanqrclear.luma.AppHelps.dpToPx
import com.base.scanqrclear.luma.MineTypeHelps.TYPE_VIDEO
import com.bumptech.glide.Glide
import com.bumptech.glide.load.resource.bitmap.CenterCrop
import com.bumptech.glide.load.resource.bitmap.RoundedCorners
import com.bumptech.glide.request.RequestOptions
class WhatsappCleanAdapter(
var data: List<FileBean>,
val type: Int = TYPE_VIDEO
) : BaseAdapter<FileBean, ItemWhatsappCleanBinding>(data.take(3)) {
constructor(type: Int = TYPE_VIDEO): this(emptyList(), type)
fun updateData(data: List<FileBean>) {
this.data = data
submitList(data.take(3))
}
override fun getViewBinding(
layoutInflater: LayoutInflater,
parent: ViewGroup
): ItemWhatsappCleanBinding {
return ItemWhatsappCleanBinding.inflate(layoutInflater, parent, false)
}
override fun bind(
holder: BaseViewHolder<ItemWhatsappCleanBinding>,
position: Int,
item: FileBean
) {
val width = holder.itemView.context.resources.displayMetrics.widthPixels
val margin = holder.itemView.context.dpToPx(128).toInt()
val imageWidth = (width - margin) / 3
holder.binding.ivImage.layoutParams.width = imageWidth
holder.binding.ivImage.layoutParams.height = imageWidth
val round = holder.itemView.context.dpToPx(8).toInt()
val options = RequestOptions().transform(CenterCrop(), RoundedCorners(round))
Glide.with(holder.itemView.context)
.load(item.path)
.apply(options)
.into(holder.binding.ivImage)
holder.binding.tvSize.text = ""
holder.binding.ivVideo.visibility = if (type == TYPE_VIDEO) View.VISIBLE else View.GONE
if (data.size > 3 && position == itemCount - 1) {
holder.binding.tvSize.text = "+${data.size - itemCount}"
} else {
holder.binding.ivShadow.visibility = View.GONE
}
}
}
\ No newline at end of file
package com.base.scanqrclear.luma
import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.view.View
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
import com.base.scanqrclear.R
import com.base.scanqrclear.databinding.ActivityWhatsappCleanDetailBinding
class WhatsappCleanDetailActivity : BaseActivity2() {
companion object {
var list = listOf<FileBean>()
var type = 0
var titleName = ""
fun start(context: Context, list: List<FileBean>, type: Int, titleName: String) {
Companion.list = list
Companion.type = type
Companion.titleName = titleName
val intent = Intent(context, WhatsappCleanDetailActivity::class.java)
context.startActivity(intent)
}
}
private val binding by lazy {
ActivityWhatsappCleanDetailBinding.inflate(layoutInflater)
}
private lateinit var adapter: CleanDetailAdapter
private var total: Long = 0
private var isSelectAll = false
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(binding.root)
initView()
}
private fun initView() {
adapter = CleanDetailAdapter(list, type)
adapter.callback = object : BaseAdapter.OnClickCallback<FileBean> {
override fun onClicked(view: View, position: Int, item: FileBean) {
if (item.isSelected) total += item.length
else total -= item.length
isSelectAll = adapter.list.stream().allMatch(FileBean::isSelected)
updateView(total > 0)
}
}
binding.rvWhatsapp.adapter = adapter
binding.rvWhatsapp.layoutManager = if (type == 2) {
LinearLayoutManager(this)
} else {
GridLayoutManager(this, 3, GridLayoutManager.VERTICAL, false)
}
if (titleName.isNotEmpty()) binding.tvTitle.text = titleName
binding.flBack.setOnClickListener { backPressed() }
binding.llSelectAll.setOnClickListener {
isSelectAll = !isSelectAll
val list = adapter.list
list.forEach { it.isSelected = isSelectAll }
adapter.submitList(list)
total = list.filter { it.isSelected }.sumOf { it.length }
updateView(isSelectAll)
}
binding.tvDelete.setOnClickListener {
if (total <= 0) return@setOnClickListener
DialogHelps.showDeleteDialog(this, binding.tvDelete) {
showAnimationAd {
toCleanResult(total, getString(R.string.whatsapp_clean))
}
cleanFiles(adapter.list)
}
}
}
private fun updateView(isSelection: Boolean) {
binding.ivSelectAll.setImageResource(if (isSelectAll) R.mipmap.icon_yuan_junk_s else R.mipmap.icon_all_photo_off)
binding.tvDelete.setBackgroundResource(if (isSelection) R.drawable.gradient_4 else R.drawable.gradient_not_clickable_4)
val value = Utils.getSizeArray(total)
binding.tvSize.text = value[0]
binding.tvUnit.text = value[1]
}
}
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/color_f7fafa">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/cl_top"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/gradient_background"
app:layout_constraintTop_toTopOf="parent">
<androidx.appcompat.widget.LinearLayoutCompat
android:id="@+id/ll_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="6dp"
android:paddingBottom="6dp"
android:gravity="center_vertical"
android:orientation="horizontal"
app:layout_constraintTop_toTopOf="parent">
<FrameLayout
android:id="@+id/fl_back"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="11dp"
android:padding="4dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent">
<androidx.appcompat.widget.AppCompatImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@mipmap/icon_return_bar_nor" />
</FrameLayout>
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/tv_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/whatsapp_clean"
android:textColor="@color/white"
android:textSize="20sp"
android:textStyle="bold"
app:layout_constraintTop_toTopOf="@id/fl_back"
app:layout_constraintBottom_toBottomOf="@id/fl_back"
app:layout_constraintStart_toEndOf="@id/fl_back" />
</androidx.appcompat.widget.LinearLayoutCompat>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/cl_size"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="34dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/ll_title">
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/tv_size"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="0"
android:textColor="@color/white"
android:textSize="32sp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/tv_unit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="KB"
android:textColor="@color/white"
android:textSize="12sp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toEndOf="@id/tv_size" />
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.appcompat.widget.AppCompatTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:layout_marginBottom="67dp"
android:text="@string/selected"
android:textColor="@color/white"
android:textSize="16sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/cl_size" />
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_whatsapp"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginTop="16dp"
android:paddingBottom="8dp"
android:paddingStart="16dp"
android:paddingEnd="16dp"
android:scrollbars="none"
app:layout_constraintTop_toBottomOf="@id/cl_top"
app:layout_constraintBottom_toTopOf="@id/ll_bottom" />
<androidx.appcompat.widget.LinearLayoutCompat
android:id="@+id/ll_bottom"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="16dp"
android:gravity="center"
android:background="@color/white"
android:orientation="horizontal"
app:layout_constraintBottom_toBottomOf="parent">
<androidx.appcompat.widget.LinearLayoutCompat
android:id="@+id/ll_select_all"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="vertical">
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/iv_select_all"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@mipmap/icon_all_photo_off" />
<androidx.appcompat.widget.AppCompatTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="2dp"
android:text="@string/select_all"
android:textColor="@color/color_666666"
android:textSize="12sp" />
</androidx.appcompat.widget.LinearLayoutCompat>
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/tv_delete"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginStart="16dp"
android:paddingTop="12dp"
android:paddingBottom="12dp"
android:gravity="center"
android:background="@drawable/gradient_not_clickable_4"
android:text="@string/delete"
android:textColor="@color/white"
android:textSize="14sp" />
</androidx.appcompat.widget.LinearLayoutCompat>
<include
android:id="@+id/animation"
android:visibility="gone"
layout="@layout/custom_animation" />
</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/cl_video_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/iv_image"
android:layout_width="110dp"
android:layout_height="110dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/iv_select"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:src="@mipmap/icon_weixuanzhong_photo_off"
app:layout_constraintTop_toTopOf="@id/iv_image"
app:layout_constraintEnd_toEndOf="parent" />
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/iv_video"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@mipmap/icon_play_whatsapp"
app:layout_constraintTop_toTopOf="@id/iv_image"
app:layout_constraintBottom_toBottomOf="@id/iv_image"
app:layout_constraintStart_toStartOf="@id/iv_image"
app:layout_constraintEnd_toEndOf="@id/iv_image" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/tv_size"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:paddingTop="4dp"
android:paddingBottom="4dp"
android:gravity="center"
android:background="@drawable/shadow_background"
android:text="12.5MB"
android:textColor="@color/white"
android:textSize="14sp"
app:layout_constraintStart_toStartOf="@id/iv_image"
app:layout_constraintEnd_toEndOf="@id/iv_image"
app:layout_constraintBottom_toBottomOf="@id/iv_image" />
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/cl_audio"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="gone"
app:layout_constraintTop_toTopOf="parent">
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/iv_audio"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@mipmap/icon_audio_junk_nor"
app:layout_constraintTop_toTopOf="@id/ll_audio"
app:layout_constraintBottom_toBottomOf="@id/ll_audio"
app:layout_constraintStart_toStartOf="parent" />
<androidx.appcompat.widget.LinearLayoutCompat
android:id="@+id/ll_audio"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
android:orientation="vertical"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toEndOf="@id/iv_audio"
app:layout_constraintEnd_toStartOf="@id/iv_audio_select">
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/tv_audio_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxLines="1"
android:ellipsize="end"
android:text="@string/app_name"
android:textColor="@color/color_181b1f"
android:textSize="16sp" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/tv_audio_size"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="2dp"
android:text="@string/app_name"
android:textColor="@color/color_aeb4bd"
android:textSize="12sp" />
</androidx.appcompat.widget.LinearLayoutCompat>
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/iv_audio_select"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@mipmap/icon_weixuanzhong_photo_off"
app:layout_constraintTop_toTopOf="@id/ll_audio"
app:layout_constraintBottom_toBottomOf="@id/ll_audio"
app:layout_constraintEnd_toEndOf="parent" />
<View
android:id="@+id/view_line"
android:layout_width="match_parent"
android:layout_height="0.5dp"
android:layout_marginTop="12dp"
android:background="@color/color_ebebeb"
app:layout_constraintTop_toBottomOf="@id/iv_audio" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/iv_image"
android:layout_width="84dp"
android:layout_height="84dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/iv_video"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@mipmap/icon_play_whatsapp"
app:layout_constraintTop_toTopOf="@id/iv_image"
app:layout_constraintBottom_toBottomOf="@id/iv_image"
app:layout_constraintStart_toStartOf="@id/iv_image"
app:layout_constraintEnd_toEndOf="@id/iv_image" />
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/iv_shadow"
android:layout_width="0dp"
android:layout_height="0dp"
android:src="@drawable/shadow_bg"
app:layout_constraintTop_toTopOf="@id/iv_image"
app:layout_constraintBottom_toBottomOf="@id/iv_image"
app:layout_constraintStart_toStartOf="@id/iv_image"
app:layout_constraintEnd_toEndOf="@id/iv_image" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/tv_size"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="+2"
android:textColor="@color/white"
android:textSize="24sp"
android:textStyle="bold"
app:layout_constraintTop_toTopOf="@id/iv_image"
app:layout_constraintBottom_toBottomOf="@id/iv_image"
app:layout_constraintStart_toStartOf="@id/iv_image"
app:layout_constraintEnd_toEndOf="@id/iv_image" />
</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
...@@ -23,6 +23,8 @@ protoliteWellKnownTypes = "18.0.0" ...@@ -23,6 +23,8 @@ protoliteWellKnownTypes = "18.0.0"
lottie = "6.5.2" lottie = "6.5.2"
expandablerecyclerview = "0.9.3" expandablerecyclerview = "0.9.3"
okhttp = "4.12.0" okhttp = "4.12.0"
glide = "4.16.0"
...@@ -59,7 +61,8 @@ lottie = { group = "com.airbnb.android", name = "lottie", version.ref = "lottie" ...@@ -59,7 +61,8 @@ lottie = { group = "com.airbnb.android", name = "lottie", version.ref = "lottie"
expandablerecyclerview = { group = "com.github.pokercc", name = "ExpandableRecyclerView", version.ref = "expandablerecyclerview" } expandablerecyclerview = { group = "com.github.pokercc", name = "ExpandableRecyclerView", version.ref = "expandablerecyclerview" }
okhttp = { group = "com.squareup.okhttp3", name = "okhttp", version.ref = "okhttp" } okhttp = { group = "com.squareup.okhttp3", name = "okhttp", version.ref = "okhttp" }
logging-interceptor = { group = "com.squareup.okhttp3", name = "logging-interceptor", version.ref = "okhttp" } logging-interceptor = { group = "com.squareup.okhttp3", name = "logging-interceptor", version.ref = "okhttp" }
glide = { group = "com.github.bumptech.glide", name = "glide", version.ref = "glide" }
glide-compiler = { group = "com.github.bumptech.glide", name = "compiler", version.ref = "glide" }
......
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