PlayerAndroid/app/src/main/java/code/name/monkey/retromusic/adapter/SongFileAdapter.kt

208 lines
6.8 KiB
Kotlin
Raw Normal View History

2020-05-22 10:51:08 +00:00
/*
* Copyright 2019 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
2019-04-20 05:29:45 +00:00
package code.name.monkey.retromusic.adapter
2018-11-30 01:06:16 +00:00
import android.graphics.PorterDuff
2019-12-06 14:25:21 +00:00
import android.view.LayoutInflater
import android.view.MenuItem
import android.view.View
import android.view.ViewGroup
2018-11-30 01:06:16 +00:00
import androidx.appcompat.app.AppCompatActivity
import code.name.monkey.appthemehelper.util.ATHUtil
import code.name.monkey.retromusic.R
2019-12-06 14:25:21 +00:00
import code.name.monkey.retromusic.adapter.base.AbsMultiSelectAdapter
import code.name.monkey.retromusic.adapter.base.MediaEntryViewHolder
2018-11-30 01:06:16 +00:00
import code.name.monkey.retromusic.glide.audiocover.AudioFileCover
import code.name.monkey.retromusic.interfaces.CabHolder
2020-01-17 17:19:06 +00:00
import code.name.monkey.retromusic.util.MusicUtil
2018-11-30 01:06:16 +00:00
import code.name.monkey.retromusic.util.RetroUtil
import com.bumptech.glide.Glide
2018-11-30 01:06:16 +00:00
import com.bumptech.glide.load.engine.DiskCacheStrategy
import com.bumptech.glide.signature.MediaStoreSignature
2020-01-17 17:19:06 +00:00
import me.zhanghai.android.fastscroll.PopupTextProvider
2018-11-30 01:06:16 +00:00
import java.io.File
import java.text.DecimalFormat
2020-02-25 13:15:23 +00:00
import java.util.*
2019-12-06 14:25:21 +00:00
import kotlin.math.log10
import kotlin.math.pow
2018-12-12 20:59:07 +00:00
2019-09-03 16:02:10 +00:00
class SongFileAdapter(
2020-01-17 17:19:06 +00:00
private val activity: AppCompatActivity,
private var dataSet: List<File>,
private val itemLayoutRes: Int,
private val callbacks: Callbacks?,
cabHolder: CabHolder?
2019-11-15 17:44:42 +00:00
) : AbsMultiSelectAdapter<SongFileAdapter.ViewHolder, File>(
2020-01-17 17:19:06 +00:00
activity, cabHolder, R.menu.menu_media_selection
), PopupTextProvider {
2019-11-15 17:44:42 +00:00
2019-12-06 14:25:21 +00:00
init {
this.setHasStableIds(true)
}
override fun getItemViewType(position: Int): Int {
2020-01-17 17:19:06 +00:00
return if (dataSet[position].isDirectory) FOLDER else FILE
2019-12-06 14:25:21 +00:00
}
override fun getItemId(position: Int): Long {
2020-01-17 17:19:06 +00:00
return dataSet[position].hashCode().toLong()
2019-12-06 14:25:21 +00:00
}
fun swapDataSet(songFiles: List<File>) {
this.dataSet = songFiles
notifyDataSetChanged()
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
return ViewHolder(LayoutInflater.from(activity).inflate(itemLayoutRes, parent, false))
}
override fun onBindViewHolder(holder: ViewHolder, index: Int) {
2020-01-17 17:19:06 +00:00
val file = dataSet[index]
2019-12-06 14:25:21 +00:00
holder.itemView.isActivated = isChecked(file)
holder.title?.text = getFileTitle(file)
if (holder.text != null) {
if (holder.itemViewType == FILE) {
holder.text?.text = getFileText(file)
} else {
holder.text?.visibility = View.GONE
}
}
if (holder.image != null) {
loadFileImage(file, holder)
}
}
private fun getFileTitle(file: File): String {
return file.name
}
private fun getFileText(file: File): String? {
return if (file.isDirectory) null else readableFileSize(file.length())
}
private fun loadFileImage(file: File, holder: ViewHolder) {
val iconColor = ATHUtil.resolveColor(activity, R.attr.colorControlNormal)
if (file.isDirectory) {
holder.image?.let {
it.setColorFilter(iconColor, PorterDuff.Mode.SRC_IN)
it.setImageResource(R.drawable.ic_folder_white_24dp)
}
2020-02-25 13:15:23 +00:00
holder.imageTextContainer?.setCardBackgroundColor(
ATHUtil.resolveColor(
activity,
R.attr.colorSurface
)
)
2019-12-06 14:25:21 +00:00
} else {
val error = RetroUtil.getTintedVectorDrawable(
2020-01-17 17:19:06 +00:00
activity, R.drawable.ic_file_music_white_24dp, iconColor
2019-12-06 14:25:21 +00:00
)
2020-04-15 08:49:28 +00:00
Glide.with(activity)
.load(AudioFileCover(file.path))
.diskCacheStrategy(DiskCacheStrategy.NONE)
.error(error)
.placeholder(error)
2020-01-17 17:19:06 +00:00
.animate(android.R.anim.fade_in)
2020-04-15 08:49:28 +00:00
.signature(MediaStoreSignature("", file.lastModified(), 0))
.into(holder.image)
2019-12-06 14:25:21 +00:00
}
}
override fun getItemCount(): Int {
2020-01-17 17:19:06 +00:00
return dataSet.size
2019-12-06 14:25:21 +00:00
}
override fun getIdentifier(position: Int): File? {
2020-01-17 17:19:06 +00:00
return dataSet[position]
2019-12-06 14:25:21 +00:00
}
override fun getName(`object`: File): String {
return getFileTitle(`object`)
}
override fun onMultipleItemAction(menuItem: MenuItem, selection: ArrayList<File>) {
if (callbacks == null) return
callbacks.onMultipleItemAction(menuItem, selection)
}
2020-01-17 17:19:06 +00:00
override fun getPopupText(position: Int): String {
return getSectionName(position)
}
private fun getSectionName(position: Int): String {
return MusicUtil.getSectionName(dataSet[position].name)
2019-12-06 14:25:21 +00:00
}
interface Callbacks {
fun onFileSelected(file: File)
fun onFileMenuClicked(file: File, view: View)
fun onMultipleItemAction(item: MenuItem, files: ArrayList<File>)
}
inner class ViewHolder(itemView: View) : MediaEntryViewHolder(itemView) {
init {
if (menu != null && callbacks != null) {
menu?.setOnClickListener { v ->
val position = layoutPosition
2019-12-06 14:25:21 +00:00
if (isPositionInRange(position)) {
2020-01-17 17:19:06 +00:00
callbacks.onFileMenuClicked(dataSet[position], v)
2019-12-06 14:25:21 +00:00
}
}
}
if (imageTextContainer != null) {
imageTextContainer?.cardElevation = 0f
}
}
override fun onClick(v: View?) {
val position = layoutPosition
2019-12-06 14:25:21 +00:00
if (isPositionInRange(position)) {
if (isInQuickSelectMode) {
toggleChecked(position)
} else {
2020-01-17 17:19:06 +00:00
callbacks?.onFileSelected(dataSet[position])
2019-12-06 14:25:21 +00:00
}
}
}
override fun onLongClick(v: View?): Boolean {
val position = layoutPosition
2019-12-06 14:25:21 +00:00
return isPositionInRange(position) && toggleChecked(position)
}
private fun isPositionInRange(position: Int): Boolean {
2020-01-17 17:19:06 +00:00
return position >= 0 && position < dataSet.size
2019-12-06 14:25:21 +00:00
}
}
companion object {
private const val FILE = 0
private const val FOLDER = 1
fun readableFileSize(size: Long): String {
if (size <= 0) return "$size B"
val units = arrayOf("B", "KB", "MB", "GB", "TB")
val digitGroups = (log10(size.toDouble()) / log10(1024.0)).toInt()
return DecimalFormat("#,##0.##").format(size / 1024.0.pow(digitGroups.toDouble())) + " " + units[digitGroups]
}
}
2018-11-30 01:06:16 +00:00
}