mirror of
https://gitlab.com/ultrasonic/ultrasonic.git
synced 2025-04-15 17:00:36 +03:00
Merge branch 'refactor/trackDisplayLinear' into 'develop'
Use Linear layout in Track display See merge request ultrasonic/ultrasonic!859
This commit is contained in:
commit
065f5253ea
@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<issues format="6" by="lint 7.3.0" type="baseline" client="gradle" dependencies="true" name="AGP (7.3.0)" variant="all" version="7.3.0">
|
||||
<issues format="6" by="lint 7.3.1" type="baseline" client="gradle" dependencies="true" name="AGP (7.3.1)" variant="all" version="7.3.1">
|
||||
|
||||
<issue
|
||||
id="PluralsCandidate"
|
||||
|
@ -13,6 +13,7 @@ import org.koin.core.component.KoinComponent
|
||||
import org.moire.ultrasonic.R
|
||||
import org.moire.ultrasonic.domain.Identifiable
|
||||
import org.moire.ultrasonic.domain.Track
|
||||
import timber.log.Timber
|
||||
|
||||
@Suppress("LongParameterList")
|
||||
class TrackViewBinder(
|
||||
@ -62,6 +63,8 @@ class TrackViewBinder(
|
||||
diffAdapter.isSelected(item.longId)
|
||||
)
|
||||
|
||||
Timber.v("Setting listeners")
|
||||
|
||||
holder.itemView.setOnLongClickListener {
|
||||
if (onContextMenuClick != null) {
|
||||
val popup = createContextMenu(holder.itemView, track)
|
||||
@ -114,6 +117,8 @@ class TrackViewBinder(
|
||||
|
||||
if (newStatus != holder.check.isChecked) holder.check.isChecked = newStatus
|
||||
}
|
||||
|
||||
Timber.v("Setting listeners done")
|
||||
}
|
||||
|
||||
override fun onViewRecycled(holder: TrackViewHolder) {
|
||||
|
@ -7,11 +7,15 @@ import android.widget.ImageView
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.TextView
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.view.isGone
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.google.android.material.progressindicator.CircularProgressIndicator
|
||||
import io.reactivex.rxjava3.disposables.CompositeDisposable
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import org.koin.core.component.KoinComponent
|
||||
import org.moire.ultrasonic.R
|
||||
import org.moire.ultrasonic.data.ActiveServerProvider
|
||||
@ -31,7 +35,11 @@ const val INDICATOR_THICKNESS_DEFINITE = 10
|
||||
/**
|
||||
* Used to display songs and videos in a `ListView`.
|
||||
*/
|
||||
class TrackViewHolder(val view: View) : RecyclerView.ViewHolder(view), Checkable, KoinComponent {
|
||||
class TrackViewHolder(val view: View) :
|
||||
RecyclerView.ViewHolder(view),
|
||||
Checkable,
|
||||
KoinComponent,
|
||||
CoroutineScope by CoroutineScope(Dispatchers.IO) {
|
||||
|
||||
var entry: Track? = null
|
||||
private set
|
||||
@ -39,7 +47,7 @@ class TrackViewHolder(val view: View) : RecyclerView.ViewHolder(view), Checkable
|
||||
var drag: ImageView = view.findViewById(R.id.song_drag)
|
||||
var observableChecked = MutableLiveData(false)
|
||||
|
||||
private var rating: LinearLayout = view.findViewById(R.id.song_five_star)
|
||||
private var rating: LinearLayout = view.findViewById(R.id.song_rating)
|
||||
private var fiveStar1: ImageView = view.findViewById(R.id.song_five_star_1)
|
||||
private var fiveStar2: ImageView = view.findViewById(R.id.song_five_star_2)
|
||||
private var fiveStar3: ImageView = view.findViewById(R.id.song_five_star_3)
|
||||
@ -62,12 +70,18 @@ class TrackViewHolder(val view: View) : RecyclerView.ViewHolder(view), Checkable
|
||||
|
||||
private var rxBusSubscription: CompositeDisposable? = null
|
||||
|
||||
init {
|
||||
Timber.v("New ViewHolder created")
|
||||
}
|
||||
|
||||
@Suppress("ComplexMethod")
|
||||
fun setSong(
|
||||
song: Track,
|
||||
checkable: Boolean,
|
||||
draggable: Boolean,
|
||||
isSelected: Boolean = false
|
||||
) {
|
||||
Timber.v("Setting song")
|
||||
val useFiveStarRating = Settings.useFiveStarRating
|
||||
entry = song
|
||||
|
||||
@ -80,21 +94,28 @@ class TrackViewHolder(val view: View) : RecyclerView.ViewHolder(view), Checkable
|
||||
if (Settings.shouldShowTrackNumber && song.track != null && song.track!! > 0) {
|
||||
track.text = entryDescription.trackNumber
|
||||
} else {
|
||||
track.isVisible = false
|
||||
if (!track.isGone) track.isGone = true
|
||||
}
|
||||
|
||||
check.isVisible = (checkable && !song.isVideo)
|
||||
initChecked(isSelected)
|
||||
drag.isVisible = draggable
|
||||
val checkValue = (checkable && !song.isVideo)
|
||||
if (check.isVisible != checkValue) check.isVisible = checkValue
|
||||
if (checkValue) initChecked(isSelected)
|
||||
if (drag.isVisible != draggable) drag.isVisible = draggable
|
||||
|
||||
if (ActiveServerProvider.isOffline()) {
|
||||
star.isVisible = false
|
||||
rating.isVisible = false
|
||||
star.isGone = true
|
||||
} else {
|
||||
setupStarButtons(song, useFiveStarRating)
|
||||
}
|
||||
|
||||
updateStatus(DownloadService.getDownloadState(song), null)
|
||||
// Instead of blocking the UI thread while looking up the current state,
|
||||
// launch the request in an IO thread and propagate the result through RX
|
||||
launch {
|
||||
val state = DownloadService.getDownloadState(song)
|
||||
RxBus.trackDownloadStatePublisher.onNext(
|
||||
RxBus.TrackDownloadState(song.id, state, null)
|
||||
)
|
||||
}
|
||||
|
||||
if (useFiveStarRating) {
|
||||
setFiveStars(entry?.userRating ?: 0)
|
||||
@ -103,8 +124,8 @@ class TrackViewHolder(val view: View) : RecyclerView.ViewHolder(view), Checkable
|
||||
}
|
||||
|
||||
if (song.isVideo) {
|
||||
artist.isVisible = false
|
||||
progressIndicator.isVisible = false
|
||||
artist.isGone = true
|
||||
progressIndicator.isGone = true
|
||||
}
|
||||
|
||||
// Create new Disposable for the new Subscriptions
|
||||
@ -117,6 +138,8 @@ class TrackViewHolder(val view: View) : RecyclerView.ViewHolder(view), Checkable
|
||||
if (it.id != song.id) return@subscribe
|
||||
updateStatus(it.state, it.progress)
|
||||
}
|
||||
|
||||
Timber.v("Setting song done")
|
||||
}
|
||||
|
||||
// This is called when the Holder is recycled and receives a new Song
|
||||
@ -145,13 +168,13 @@ class TrackViewHolder(val view: View) : RecyclerView.ViewHolder(view), Checkable
|
||||
private fun setupStarButtons(song: Track, useFiveStarRating: Boolean) {
|
||||
if (useFiveStarRating) {
|
||||
// Hide single star
|
||||
star.visibility = View.INVISIBLE
|
||||
star.isGone = true
|
||||
rating.isVisible = true
|
||||
val rating = if (song.userRating == null) 0 else song.userRating!!
|
||||
setFiveStars(rating)
|
||||
} else {
|
||||
// Hide five stars
|
||||
rating.isVisible = false
|
||||
|
||||
star.isVisible = true
|
||||
rating.isGone = true
|
||||
setSingleStar(song.starred)
|
||||
star.setOnClickListener {
|
||||
val isStarred = song.starred
|
||||
@ -241,7 +264,7 @@ class TrackViewHolder(val view: View) : RecyclerView.ViewHolder(view), Checkable
|
||||
}
|
||||
|
||||
private fun showStatusImage(image: Int?) {
|
||||
progressIndicator.isVisible = false
|
||||
progressIndicator.isGone = true
|
||||
statusImage.isVisible = true
|
||||
if (image != null) {
|
||||
statusImage.setImageResource(image)
|
||||
@ -251,7 +274,7 @@ class TrackViewHolder(val view: View) : RecyclerView.ViewHolder(view), Checkable
|
||||
}
|
||||
|
||||
private fun showIndefiniteProgress() {
|
||||
statusImage.isVisible = false
|
||||
statusImage.isGone = true
|
||||
progressIndicator.isVisible = true
|
||||
progressIndicator.isIndeterminate = true
|
||||
progressIndicator.indicatorDirection =
|
||||
@ -260,7 +283,7 @@ class TrackViewHolder(val view: View) : RecyclerView.ViewHolder(view), Checkable
|
||||
}
|
||||
|
||||
private fun showProgress() {
|
||||
statusImage.isVisible = false
|
||||
statusImage.isGone = true
|
||||
progressIndicator.isVisible = true
|
||||
progressIndicator.isIndeterminate = false
|
||||
progressIndicator.indicatorDirection =
|
||||
|
@ -1,169 +1,45 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:a="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
<!-- DON'T CONVERT TO ConstraintLayout! We have been there and it was slower than LinearLayout :) -->
|
||||
<LinearLayout xmlns:a="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
a:id="@+id/song_layout"
|
||||
a:layout_width="fill_parent"
|
||||
a:layout_height="wrap_content"
|
||||
a:minHeight="?android:attr/listPreferredItemHeight">
|
||||
a:layout_height="?android:attr/listPreferredItemHeight"
|
||||
a:minHeight="?android:attr/listPreferredItemHeight"
|
||||
a:orientation="horizontal">
|
||||
|
||||
<ImageView
|
||||
a:id="@+id/song_drag"
|
||||
a:layout_width="wrap_content"
|
||||
a:layout_height="0dp"
|
||||
a:layout_width="38dp"
|
||||
a:layout_height="fill_parent"
|
||||
a:background="@android:color/transparent"
|
||||
a:focusable="false"
|
||||
a:gravity="center_vertical"
|
||||
a:importantForAccessibility="no"
|
||||
a:paddingStart="5dip"
|
||||
a:paddingEnd="6dip"
|
||||
a:paddingStart="7dip"
|
||||
a:paddingEnd="4dip"
|
||||
a:src="@drawable/ic_drag_vertical"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@+id/song_check"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
a:visibility="gone" />
|
||||
|
||||
<CheckedTextView
|
||||
a:id="@+id/song_check"
|
||||
a:layout_width="wrap_content"
|
||||
a:layout_height="0dp"
|
||||
a:layout_marginStart="4dp"
|
||||
a:layout_width="38dp"
|
||||
a:layout_height="fill_parent"
|
||||
a:checkMark="@drawable/btn_check_custom"
|
||||
a:gravity="center_vertical"
|
||||
a:paddingEnd="4dip"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@+id/song_drag"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
a:visibility="gone" />
|
||||
|
||||
|
||||
<TextView
|
||||
a:id="@+id/song_track"
|
||||
a:layout_width="wrap_content"
|
||||
a:layout_height="wrap_content"
|
||||
a:layout_marginTop="8dp"
|
||||
a:paddingEnd="6dip"
|
||||
a:textAppearance="?android:attr/textAppearanceMedium"
|
||||
a:visibility="visible"
|
||||
app:layout_constraintEnd_toStartOf="@+id/song_title"
|
||||
app:layout_constraintStart_toEndOf="@+id/song_check"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:text="Track"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<TextView
|
||||
a:id="@+id/song_title"
|
||||
a:layout_width="0dp"
|
||||
a:layout_height="wrap_content"
|
||||
a:layout_marginTop="8dp"
|
||||
a:drawablePadding="4dip"
|
||||
a:ellipsize="end"
|
||||
a:paddingEnd="4dip"
|
||||
a:singleLine="true"
|
||||
a:textAppearance="?android:attr/textAppearanceMedium"
|
||||
app:layout_constraintEnd_toStartOf="@id/barrier"
|
||||
app:layout_constraintStart_toEndOf="@+id/song_track"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:text="Title" />
|
||||
|
||||
<TextView
|
||||
a:id="@+id/song_artist"
|
||||
a:layout_width="0dp"
|
||||
a:layout_height="wrap_content"
|
||||
a:layout_marginBottom="10dp"
|
||||
a:ellipsize="middle"
|
||||
a:paddingStart="1dip"
|
||||
a:paddingEnd="4dip"
|
||||
a:singleLine="true"
|
||||
a:textAppearance="?android:attr/textAppearanceSmall"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@+id/barrier"
|
||||
app:layout_constraintStart_toEndOf="@+id/song_check"
|
||||
tools:text="Artist" />
|
||||
|
||||
<ImageView
|
||||
a:id="@+id/song_status_image"
|
||||
a:layout_width="25dp"
|
||||
a:layout_height="0dp"
|
||||
a:layout_marginTop="8dp"
|
||||
a:layout_marginEnd="10dip"
|
||||
a:importantForAccessibility="no"
|
||||
app:layout_constraintBottom_toTopOf="@id/song_duration"
|
||||
app:layout_constraintEnd_toEndOf="@id/star_barrier"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<com.google.android.material.progressindicator.CircularProgressIndicator
|
||||
a:id="@+id/song_status_progress"
|
||||
a:layout_width="wrap_content"
|
||||
a:layout_height="0dp"
|
||||
a:layout_marginTop="8dp"
|
||||
a:layout_marginEnd="10dip"
|
||||
a:indeterminate="true"
|
||||
app:indicatorColor="?attr/colorOnSurface"
|
||||
app:indicatorSize="20dp"
|
||||
app:layout_constraintBottom_toTopOf="@id/song_duration"
|
||||
app:layout_constraintEnd_toEndOf="@id/star_barrier"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:trackColor="?attr/colorSurfaceVariant" />
|
||||
|
||||
<TextView
|
||||
a:id="@+id/song_duration"
|
||||
a:layout_width="wrap_content"
|
||||
a:layout_height="wrap_content"
|
||||
a:layout_marginBottom="10dp"
|
||||
a:paddingStart="3dip"
|
||||
a:paddingEnd="9dip"
|
||||
a:singleLine="true"
|
||||
a:textAppearance="?android:attr/textAppearanceSmall"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="@id/star_barrier"
|
||||
tools:text="Duration" />
|
||||
|
||||
<androidx.constraintlayout.widget.Barrier
|
||||
a:id="@+id/barrier"
|
||||
a:layout_width="wrap_content"
|
||||
a:layout_height="wrap_content"
|
||||
app:barrierDirection="left"
|
||||
app:constraint_referenced_ids="song_duration"
|
||||
tools:layout_editor_absoluteX="289dp" />
|
||||
|
||||
|
||||
<androidx.constraintlayout.widget.Barrier
|
||||
a:id="@+id/star_barrier"
|
||||
a:layout_width="wrap_content"
|
||||
a:layout_height="wrap_content"
|
||||
app:barrierDirection="left"
|
||||
app:constraint_referenced_ids="song_five_star,song_star"
|
||||
tools:layout_editor_absoluteX="354dp" />
|
||||
|
||||
<ImageView
|
||||
a:id="@+id/song_star"
|
||||
a:layout_width="wrap_content"
|
||||
a:layout_height="0dp"
|
||||
a:background="@android:color/transparent"
|
||||
a:contentDescription="@string/download.menu_star"
|
||||
a:focusable="false"
|
||||
a:gravity="center_vertical"
|
||||
a:importantForAccessibility="no"
|
||||
a:paddingStart="5dip"
|
||||
a:paddingEnd="6dip"
|
||||
a:src="@drawable/ic_star_hollow"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@id/star_barrier"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:visibility="invisible" />
|
||||
<include layout="@layout/list_item_track_details" />
|
||||
|
||||
<LinearLayout
|
||||
a:id="@+id/song_five_star"
|
||||
a:id="@+id/song_rating"
|
||||
a:layout_width="wrap_content"
|
||||
a:layout_height="0dp"
|
||||
a:layout_height="fill_parent"
|
||||
a:layout_gravity="center_vertical"
|
||||
a:orientation="horizontal"
|
||||
a:visibility="visible"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@id/star_barrier"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
a:visibility="gone"
|
||||
tools:visibility="visible">
|
||||
|
||||
<ImageView
|
||||
a:id="@+id/song_five_star_1"
|
||||
@ -223,4 +99,16 @@
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
<ImageView
|
||||
a:id="@+id/song_star"
|
||||
a:layout_width="38dp"
|
||||
a:layout_height="fill_parent"
|
||||
a:background="@android:color/transparent"
|
||||
a:contentDescription="@string/download.menu_star"
|
||||
a:focusable="false"
|
||||
a:gravity="center_vertical"
|
||||
a:paddingEnd="8dip"
|
||||
a:src="@drawable/ic_star_hollow"
|
||||
a:visibility="gone" />
|
||||
|
||||
</LinearLayout>
|
102
ultrasonic/src/main/res/layout/list_item_track_details.xml
Normal file
102
ultrasonic/src/main/res/layout/list_item_track_details.xml
Normal file
@ -0,0 +1,102 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- DON'T CONVERT TO ConstraintLayout! We have been there and it was slower than LinearLayout :) -->
|
||||
<LinearLayout xmlns:a="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
a:layout_width="0dp"
|
||||
a:layout_height="?android:attr/listPreferredItemHeight"
|
||||
a:layout_gravity="center_vertical"
|
||||
a:layout_marginStart="4dp"
|
||||
a:layout_weight="1"
|
||||
a:orientation="vertical"
|
||||
tools:layout_height="?android:attr/listPreferredItemHeight"
|
||||
tools:layout_width="match_parent">
|
||||
|
||||
<LinearLayout
|
||||
a:layout_width="fill_parent"
|
||||
a:layout_height="0dp"
|
||||
a:layout_weight="3"
|
||||
a:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
a:id="@+id/song_track"
|
||||
a:layout_width="wrap_content"
|
||||
a:layout_height="wrap_content"
|
||||
a:layout_gravity="left|center_vertical"
|
||||
a:paddingEnd="6dip"
|
||||
a:textAppearance="?android:attr/textAppearanceMedium"
|
||||
a:visibility="gone"
|
||||
tools:text="0/1" />
|
||||
|
||||
<TextView
|
||||
a:id="@+id/song_title"
|
||||
a:layout_width="0dp"
|
||||
a:layout_height="wrap_content"
|
||||
a:layout_gravity="bottom|left"
|
||||
a:layout_weight="1"
|
||||
a:drawablePadding="4dip"
|
||||
a:ellipsize="end"
|
||||
a:paddingEnd="4dip"
|
||||
a:singleLine="true"
|
||||
a:textAppearance="?android:attr/textAppearanceMedium"
|
||||
tools:text="Title"
|
||||
tools:ignore="NestedWeights" />
|
||||
|
||||
<ImageView
|
||||
a:id="@+id/song_status_image"
|
||||
a:layout_width="wrap_content"
|
||||
a:layout_height="match_parent"
|
||||
a:layout_marginTop="8dp"
|
||||
a:layout_marginEnd="10dip"
|
||||
a:importantForAccessibility="no"
|
||||
a:visibility="gone" />
|
||||
|
||||
<com.google.android.material.progressindicator.CircularProgressIndicator
|
||||
a:id="@+id/song_status_progress"
|
||||
a:layout_width="wrap_content"
|
||||
a:layout_height="match_parent"
|
||||
a:layout_gravity="bottom|right"
|
||||
a:layout_marginTop="8dp"
|
||||
a:layout_marginEnd="10dip"
|
||||
a:indeterminate="true"
|
||||
a:visibility="gone"
|
||||
app:indicatorColor="?attr/colorOnSurface"
|
||||
app:indicatorSize="20dp"
|
||||
app:trackColor="?attr/colorSurfaceVariant"
|
||||
tools:visibility="visible" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
a:layout_width="fill_parent"
|
||||
a:layout_height="wrap_content"
|
||||
a:layout_gravity="center_vertical"
|
||||
a:layout_weight="1"
|
||||
a:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
a:id="@+id/song_artist"
|
||||
a:layout_width="0dip"
|
||||
a:layout_height="wrap_content"
|
||||
a:layout_gravity="top|left"
|
||||
a:layout_weight="1"
|
||||
a:ellipsize="middle"
|
||||
a:paddingStart="1dip"
|
||||
a:paddingEnd="4dip"
|
||||
a:singleLine="true"
|
||||
a:textAppearance="?android:attr/textAppearanceSmall"
|
||||
tools:text="Artist"
|
||||
tools:ignore="NestedWeights" />
|
||||
|
||||
<TextView
|
||||
a:id="@+id/song_duration"
|
||||
a:layout_width="wrap_content"
|
||||
a:layout_height="wrap_content"
|
||||
a:layout_gravity="right|top"
|
||||
a:paddingStart="3dip"
|
||||
a:paddingEnd="9dip"
|
||||
a:singleLine="true"
|
||||
a:textAppearance="?android:attr/textAppearanceSmall"
|
||||
tools:text="00:00" />
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
Loading…
x
Reference in New Issue
Block a user