Fix alignments

main
h4h13 2020-01-04 00:10:57 +05:30
parent 4d0107bd74
commit 0a49d98c24
16 changed files with 1082 additions and 1092 deletions

View File

@ -4,24 +4,26 @@ import androidx.annotation.DrawableRes
import androidx.annotation.StringRes
import code.name.monkey.retromusic.R
enum class NowPlayingScreen constructor(
@param:StringRes @field:StringRes
val titleRes: Int,
@param:DrawableRes @field:DrawableRes val drawableResId: Int,
val id: Int
) {
NORMAL(R.string.normal, R.drawable.np_normal, 0),
FLAT(R.string.flat, R.drawable.np_flat, 1),
FIT(R.string.fit, R.drawable.np_fit, 12),
TINY(R.string.tiny, R.drawable.np_tiny, 7),
PEAK(R.string.peak, R.drawable.np_peak, 14),
enum class NowPlayingScreen constructor(@param:StringRes @field:StringRes
val titleRes: Int,
@param:DrawableRes @field:DrawableRes val drawableResId: Int,
val id: Int) {
ADAPTIVE(R.string.adaptive, R.drawable.np_adaptive, 10),
BLUR(R.string.blur, R.drawable.np_blur, 4),
BLUR_CARD(R.string.blur_card, R.drawable.np_blur_card, 9),
CARD(R.string.card, R.drawable.np_card, 6),
COLOR(R.string.color, R.drawable.np_color, 5),
FIT(R.string.fit, R.drawable.np_fit, 12),
FLAT(R.string.flat, R.drawable.np_flat, 1),
FULL(R.string.full, R.drawable.np_full, 2),
MATERIAL(R.string.material, R.drawable.np_material, 11),
NORMAL(R.string.normal, R.drawable.np_normal, 0),
PLAIN(R.string.plain, R.drawable.np_plain, 3),
TINY(R.string.tiny, R.drawable.np_tiny, 7),
SIMPLE(R.string.simple, R.drawable.np_simple, 8),
PEAK(R.string.peak, R.drawable.np_peak, 14)
}

View File

@ -26,8 +26,11 @@ import kotlinx.android.synthetic.main.fragment_color_player_playback_controls.so
import kotlinx.android.synthetic.main.fragment_color_player_playback_controls.songTotalTime
import kotlinx.android.synthetic.main.fragment_color_player_playback_controls.text
import kotlinx.android.synthetic.main.fragment_color_player_playback_controls.title
import kotlinx.android.synthetic.main.fragment_player_playback_controls.*
import kotlinx.android.synthetic.main.fragment_player_playback_controls.nextButton
import kotlinx.android.synthetic.main.fragment_player_playback_controls.playPauseButton
import kotlinx.android.synthetic.main.fragment_player_playback_controls.previousButton
import kotlinx.android.synthetic.main.fragment_player_playback_controls.repeatButton
import kotlinx.android.synthetic.main.fragment_player_playback_controls.shuffleButton
class ColorPlaybackControlsFragment : AbsPlayerControlsFragment() {
@ -91,7 +94,6 @@ class ColorPlaybackControlsFragment : AbsPlayerControlsFragment() {
updateShuffleState()
}
fun setDark(textColor: Int, background: Int) {
setDark(textColor)
TintHelper.setTintAuto(playPauseButton, background, false)
@ -123,15 +125,13 @@ class ColorPlaybackControlsFragment : AbsPlayerControlsFragment() {
playPauseButton.setOnClickListener(PlayPauseButtonOnClickHandler())
}
private fun updatePlayPauseDrawableState() {
when {
MusicPlayerRemote.isPlaying -> playPauseButton.setImageResource(R.drawable.ic_pause_white_24dp)
else -> playPauseButton.setImageResource(R.drawable.ic_play_arrow_white_32dp)
else -> playPauseButton.setImageResource(R.drawable.ic_play_arrow_white_24dp)
}
}
private fun setUpMusicControllers() {
setUpPlayPauseFab()
setUpPrevNext()
@ -157,7 +157,10 @@ class ColorPlaybackControlsFragment : AbsPlayerControlsFragment() {
override fun updateShuffleState() {
when (MusicPlayerRemote.shuffleMode) {
MusicService.SHUFFLE_MODE_SHUFFLE -> shuffleButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
MusicService.SHUFFLE_MODE_SHUFFLE -> shuffleButton.setColorFilter(
lastPlaybackControlsColor,
PorterDuff.Mode.SRC_IN
)
else -> shuffleButton.setColorFilter(lastDisabledPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
}
}
@ -183,14 +186,13 @@ class ColorPlaybackControlsFragment : AbsPlayerControlsFragment() {
}
}
public override fun show() {
playPauseButton!!.animate()
.scaleX(1f)
.scaleY(1f)
.rotation(360f)
.setInterpolator(DecelerateInterpolator())
.start()
.scaleX(1f)
.scaleY(1f)
.rotation(360f)
.setInterpolator(DecelerateInterpolator())
.start()
}
public override fun hide() {

View File

@ -36,7 +36,6 @@ import kotlinx.android.synthetic.main.fragment_player_playback_controls.songTota
import kotlinx.android.synthetic.main.fragment_player_playback_controls.text
import kotlinx.android.synthetic.main.fragment_player_playback_controls.title
class PlayerPlaybackControlsFragment : AbsPlayerControlsFragment() {
private var lastPlaybackControlsColor: Int = 0
@ -48,8 +47,10 @@ class PlayerPlaybackControlsFragment : AbsPlayerControlsFragment() {
progressViewUpdateHelper = MusicProgressViewUpdateHelper(this)
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment_player_playback_controls, container, false)
}
@ -72,10 +73,12 @@ class PlayerPlaybackControlsFragment : AbsPlayerControlsFragment() {
val colorBg = ATHUtil.resolveColor(requireContext(), android.R.attr.colorBackground)
if (ColorUtil.isColorLight(colorBg)) {
lastPlaybackControlsColor = MaterialValueHelper.getSecondaryTextColor(requireContext(), true)
lastDisabledPlaybackControlsColor = MaterialValueHelper.getSecondaryDisabledTextColor(requireContext(), true)
lastDisabledPlaybackControlsColor =
MaterialValueHelper.getSecondaryDisabledTextColor(requireContext(), true)
} else {
lastPlaybackControlsColor = MaterialValueHelper.getPrimaryTextColor(requireContext(), false)
lastDisabledPlaybackControlsColor = MaterialValueHelper.getPrimaryDisabledTextColor(requireContext(), false)
lastDisabledPlaybackControlsColor =
MaterialValueHelper.getPrimaryDisabledTextColor(requireContext(), false)
}
val colorFinal = if (PreferenceUtil.getInstance(requireContext()).adaptiveColor) {
@ -84,7 +87,11 @@ class PlayerPlaybackControlsFragment : AbsPlayerControlsFragment() {
ThemeStore.accentColor(requireContext())
}.ripAlpha()
TintHelper.setTintAuto(playPauseButton, MaterialValueHelper.getPrimaryTextColor(requireContext(), ColorUtil.isColorLight(colorFinal)), false)
TintHelper.setTintAuto(
playPauseButton,
MaterialValueHelper.getPrimaryTextColor(requireContext(), ColorUtil.isColorLight(colorFinal)),
false
)
TintHelper.setTintAuto(playPauseButton, colorFinal, true)
ViewUtil.setProgressDrawable(progressSlider, colorFinal, false)
@ -173,7 +180,10 @@ class PlayerPlaybackControlsFragment : AbsPlayerControlsFragment() {
override fun updateShuffleState() {
when (MusicPlayerRemote.shuffleMode) {
MusicService.SHUFFLE_MODE_SHUFFLE -> shuffleButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
MusicService.SHUFFLE_MODE_SHUFFLE -> shuffleButton.setColorFilter(
lastPlaybackControlsColor,
PorterDuff.Mode.SRC_IN
)
else -> shuffleButton.setColorFilter(lastDisabledPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
}
}
@ -201,11 +211,11 @@ class PlayerPlaybackControlsFragment : AbsPlayerControlsFragment() {
public override fun show() {
playPauseButton!!.animate()
.scaleX(1f)
.scaleY(1f)
.rotation(360f)
.setInterpolator(DecelerateInterpolator())
.start()
.scaleX(1f)
.scaleY(1f)
.rotation(360f)
.setInterpolator(DecelerateInterpolator())
.start()
}
public override fun hide() {
@ -223,8 +233,10 @@ class PlayerPlaybackControlsFragment : AbsPlayerControlsFragment() {
override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) {
if (fromUser) {
MusicPlayerRemote.seekTo(progress)
onUpdateProgressViews(MusicPlayerRemote.songProgressMillis,
MusicPlayerRemote.songDurationMillis)
onUpdateProgressViews(
MusicPlayerRemote.songProgressMillis,
MusicPlayerRemote.songDurationMillis
)
}
}
})
@ -241,5 +253,4 @@ class PlayerPlaybackControlsFragment : AbsPlayerControlsFragment() {
songTotalTime.text = MusicUtil.getReadableDurationString(total.toLong())
songCurrentProgress.text = MusicUtil.getReadableDurationString(progress.toLong())
}
}

View File

@ -26,10 +26,14 @@ import code.name.monkey.retromusic.service.MusicService
import code.name.monkey.retromusic.util.MusicUtil
import code.name.monkey.retromusic.util.PreferenceUtil
import code.name.monkey.retromusic.util.ViewUtil
import kotlinx.android.synthetic.main.fragment_plain_controls_fragment.*
import kotlinx.android.synthetic.main.media_button.playPauseButton
import kotlinx.android.synthetic.main.media_button.repeatButton
import kotlinx.android.synthetic.main.media_button.shuffleButton
import kotlinx.android.synthetic.main.fragment_plain_controls_fragment.nextButton
import kotlinx.android.synthetic.main.fragment_plain_controls_fragment.playPauseButton
import kotlinx.android.synthetic.main.fragment_plain_controls_fragment.previousButton
import kotlinx.android.synthetic.main.fragment_plain_controls_fragment.progressSlider
import kotlinx.android.synthetic.main.fragment_plain_controls_fragment.repeatButton
import kotlinx.android.synthetic.main.fragment_plain_controls_fragment.shuffleButton
import kotlinx.android.synthetic.main.fragment_plain_controls_fragment.songCurrentProgress
import kotlinx.android.synthetic.main.fragment_plain_controls_fragment.songTotalTime
/**
* @author Hemanth S (h4h13).
@ -41,7 +45,6 @@ class PlainPlaybackControlsFragment : AbsPlayerControlsFragment() {
private var lastDisabledPlaybackControlsColor: Int = 0
private lateinit var progressViewUpdateHelper: MusicProgressViewUpdateHelper
override fun onPlayStateChanged() {
updatePlayPauseDrawableState()
}
@ -70,7 +73,6 @@ class PlainPlaybackControlsFragment : AbsPlayerControlsFragment() {
return inflater.inflate(R.layout.fragment_plain_controls_fragment, container, false)
}
override fun onResume() {
super.onResume()
progressViewUpdateHelper.start()
@ -118,7 +120,6 @@ class PlainPlaybackControlsFragment : AbsPlayerControlsFragment() {
previousButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
}
override fun setDark(color: Int) {
val colorBg = ATHUtil.resolveColor(context!!, android.R.attr.colorBackground)
if (ColorUtil.isColorLight(colorBg)) {
@ -136,7 +137,11 @@ class PlainPlaybackControlsFragment : AbsPlayerControlsFragment() {
}
volumeFragment?.setTintable(colorFinal)
TintHelper.setTintAuto(playPauseButton, MaterialValueHelper.getPrimaryTextColor(context!!, ColorUtil.isColorLight(colorFinal)), false)
TintHelper.setTintAuto(
playPauseButton,
MaterialValueHelper.getPrimaryTextColor(context!!, ColorUtil.isColorLight(colorFinal)),
false
)
TintHelper.setTintAuto(playPauseButton, colorFinal, true)
ViewUtil.setProgressDrawable(progressSlider, colorFinal.ripAlpha(), true)
@ -152,7 +157,10 @@ class PlainPlaybackControlsFragment : AbsPlayerControlsFragment() {
override fun updateShuffleState() {
when (MusicPlayerRemote.shuffleMode) {
MusicService.SHUFFLE_MODE_SHUFFLE -> shuffleButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
MusicService.SHUFFLE_MODE_SHUFFLE -> shuffleButton.setColorFilter(
lastPlaybackControlsColor,
PorterDuff.Mode.SRC_IN
)
else -> shuffleButton.setColorFilter(lastDisabledPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
}
}
@ -180,11 +188,11 @@ class PlainPlaybackControlsFragment : AbsPlayerControlsFragment() {
public override fun show() {
playPauseButton!!.animate()
.scaleX(1f)
.scaleY(1f)
.rotation(360f)
.setInterpolator(DecelerateInterpolator())
.start()
.scaleX(1f)
.scaleY(1f)
.rotation(360f)
.setInterpolator(DecelerateInterpolator())
.start()
}
public override fun hide() {
@ -202,8 +210,10 @@ class PlainPlaybackControlsFragment : AbsPlayerControlsFragment() {
override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) {
if (fromUser) {
MusicPlayerRemote.seekTo(progress)
onUpdateProgressViews(MusicPlayerRemote.songProgressMillis,
MusicPlayerRemote.songDurationMillis)
onUpdateProgressViews(
MusicPlayerRemote.songProgressMillis,
MusicPlayerRemote.songDurationMillis
)
}
}
})
@ -219,16 +229,16 @@ class PlainPlaybackControlsFragment : AbsPlayerControlsFragment() {
pivotY = (height / 2).toFloat()
animate().setDuration(200)
.setInterpolator(DecelerateInterpolator())
.scaleX(1.1f)
.scaleY(1.1f)
.withEndAction {
animate().setDuration(200)
.setInterpolator(AccelerateInterpolator())
.scaleX(1f)
.scaleY(1f)
.alpha(1f).start()
}.start()
.setInterpolator(DecelerateInterpolator())
.scaleX(1.1f)
.scaleY(1.1f)
.withEndAction {
animate().setDuration(200)
.setInterpolator(AccelerateInterpolator())
.scaleX(1f)
.scaleY(1f)
.alpha(1f).start()
}.start()
}
}
@ -251,5 +261,4 @@ class PlainPlaybackControlsFragment : AbsPlayerControlsFragment() {
songTotalTime.text = MusicUtil.getReadableDurationString(total.toLong())
songCurrentProgress.text = MusicUtil.getReadableDurationString(progress.toLong())
}
}

View File

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

View File

@ -66,7 +66,7 @@
tools:ignore="MissingPrefix"
tools:tint="@color/md_black_1000" />
<androidx.appcompat.widget.AppCompatImageButton
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/playPauseButton"
android:layout_width="96dp"
android:layout_height="96dp"

View File

@ -22,7 +22,7 @@
<View
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#90000000" />
android:background="#C0000000" />
<LinearLayout
@ -86,9 +86,9 @@
android:id="@+id/nextSong"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:ellipsize="marquee"
android:layout_marginTop="4dp"
android:ellipsize="end"
android:gravity="center"
android:marqueeRepeatLimit="marquee_forever"
android:paddingStart="16dp"
android:paddingEnd="16dp"
android:singleLine="true"

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/player_footer_frame"
@ -8,207 +8,200 @@
android:orientation="vertical"
tools:background="@color/md_grey_800">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/playerMenu"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="?attr/roundSelector"
android:padding="12dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/ic_more_vert_white_24dp" />
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/playerMenu"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="?attr/roundSelector"
android:padding="12dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/ic_more_vert_white_24dp" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:ellipsize="marquee"
android:gravity="center"
android:marqueeRepeatLimit="marquee_forever"
android:paddingStart="8dp"
android:paddingEnd="8dp"
android:singleLine="true"
android:textAppearance="@style/TextViewHeadline6"
android:textColor="@color/md_white_1000"
android:textStyle="bold"
app:layout_constraintEnd_toStartOf="@+id/playerMenu"
app:layout_constraintStart_toEndOf="@+id/songFavourite"
app:layout_constraintTop_toTopOf="parent"
tools:text="@tools:sample/lorem/random" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/title"
android:layout_width="315dp"
android:layout_height="wrap_content"
android:ellipsize="marquee"
android:gravity="center"
android:marqueeRepeatLimit="marquee_forever"
android:paddingStart="8dp"
android:paddingEnd="8dp"
android:singleLine="true"
android:textAppearance="@style/TextViewHeadline6"
android:textColor="@color/md_white_1000"
android:textStyle="bold"
app:layout_constraintBottom_toTopOf="@+id/text"
app:layout_constraintEnd_toStartOf="@+id/playerMenu"
app:layout_constraintStart_toEndOf="@+id/songFavourite"
app:layout_constraintTop_toTopOf="parent"
tools:text="@tools:sample/lorem/random" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/text"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:alpha="0.75"
android:ellipsize="end"
android:gravity="center"
android:maxLines="2"
android:paddingStart="8dp"
android:paddingTop="12dp"
android:paddingEnd="8dp"
android:textColor="@color/md_white_1000"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/playerMenu"
app:layout_constraintStart_toEndOf="@+id/songFavourite"
app:layout_constraintTop_toBottomOf="@+id/title"
tools:text="@tools:sample/lorem/random" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/text"
android:layout_width="315dp"
android:layout_height="wrap_content"
android:alpha="0.75"
android:ellipsize="end"
android:gravity="center"
android:maxLines="2"
android:paddingStart="8dp"
android:paddingTop="12dp"
android:paddingEnd="8dp"
android:textColor="@color/md_white_1000"
app:layout_constraintBottom_toTopOf="@+id/progressSlider"
app:layout_constraintEnd_toStartOf="@+id/playerMenu"
app:layout_constraintStart_toEndOf="@+id/songFavourite"
app:layout_constraintTop_toBottomOf="@+id/title"
tools:layout_editor_absoluteX="48dp"
tools:text="@tools:sample/lorem/random" />
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/songFavourite"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="?attr/roundSelector"
android:padding="12dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0"
app:srcCompat="@drawable/ic_favorite_border_white_24dp" />
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/songFavourite"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="?attr/roundSelector"
android:padding="12dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0"
app:srcCompat="@drawable/ic_favorite_border_white_24dp" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="@dimen/progress_slider_height"
<com.google.android.material.textview.MaterialTextView
android:id="@+id/songCurrentProgress"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_alignParentLeft="true"
android:layout_marginStart="16dp"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:paddingStart="12dp"
android:paddingEnd="12dp">
android:gravity="center_vertical|left|end"
android:singleLine="true"
android:textColor="@color/md_white_1000"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/progressSlider"
tools:ignore="RtlHardcoded,RtlSymmetry"
tools:text="00:00" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/songCurrentProgress"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_alignParentLeft="true"
android:fontFamily="sans-serif-medium"
<com.google.android.material.textview.MaterialTextView
android:id="@+id/songTotalTime"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_alignParentRight="true"
android:layout_marginTop="8dp"
android:layout_marginEnd="16dp"
android:gravity="center_vertical|right|end"
android:singleLine="true"
android:textColor="@color/md_white_1000"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/progressSlider"
tools:ignore="RtlHardcoded,RtlSymmetry"
tools:text="00:00" />
android:gravity="center_vertical|left|end"
android:paddingLeft="8dp"
android:singleLine="true"
android:textColor="@color/md_white_1000"
android:textSize="12sp"
tools:ignore="RtlHardcoded,RtlSymmetry"
tools:text="00:00" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/songTotalTime"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_alignParentRight="true"
android:fontFamily="sans-serif-medium"
android:gravity="center_vertical|right|end"
android:paddingRight="8dp"
android:singleLine="true"
android:textColor="@color/md_white_1000"
android:textSize="12sp"
tools:ignore="RtlHardcoded,RtlSymmetry"
tools:text="00:00" />
<androidx.appcompat.widget.AppCompatSeekBar
android:id="@+id/progressSlider"
style="@style/Widget.MaterialProgressBar.ProgressBar.Horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toLeftOf="@id/songTotalTime"
android:layout_toRightOf="@id/songCurrentProgress"
android:maxHeight="3dp"
android:progressDrawable="@drawable/color_progress_seek"
android:splitTrack="false"
tools:ignore="RtlHardcoded,UnusedAttribute"
tools:progress="20" />
</RelativeLayout>
<androidx.constraintlayout.widget.ConstraintLayout
<androidx.appcompat.widget.AppCompatSeekBar
android:id="@+id/progressSlider"
style="@style/Widget.MaterialProgressBar.ProgressBar.Horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="96dp"
tools:ignore="ContentDescription,UnusedAttribute">
<androidx.appcompat.widget.AppCompatImageButton
android:id="@+id/repeatButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="?attr/roundSelector"
android:padding="16dp"
android:scaleType="fitCenter"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/previousButton"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/ic_repeat_white_24dp"
tools:ignore="MissingPrefix" />
<androidx.appcompat.widget.AppCompatImageButton
android:id="@+id/previousButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="?attr/roundSelector"
android:padding="16dp"
android:scaleType="fitCenter"
app:layout_constraintBottom_toBottomOf="@+id/repeatButton"
app:layout_constraintEnd_toStartOf="@+id/playPauseButton"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@+id/repeatButton"
app:layout_constraintTop_toTopOf="@+id/repeatButton"
app:srcCompat="@drawable/ic_skip_previous_white_24dp"
tools:ignore="MissingPrefix" />
android:layout_centerVertical="true"
android:layout_marginTop="16dp"
android:layout_toLeftOf="@id/songTotalTime"
android:layout_toRightOf="@id/songCurrentProgress"
android:maxHeight="3dp"
android:progressDrawable="@drawable/color_progress_seek"
android:splitTrack="false"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/text"
tools:ignore="RtlHardcoded,UnusedAttribute"
tools:progress="20" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/playPauseButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="16dp"
app:layout_constraintBottom_toBottomOf="@+id/previousButton"
app:layout_constraintEnd_toStartOf="@+id/nextButton"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@+id/previousButton"
app:layout_constraintTop_toTopOf="@+id/previousButton" />
<androidx.appcompat.widget.AppCompatImageButton
android:id="@+id/repeatButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="?attr/roundSelector"
android:padding="16dp"
android:scaleType="fitCenter"
app:layout_constraintBottom_toBottomOf="@+id/previousButton"
app:layout_constraintEnd_toStartOf="@+id/previousButton"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/previousButton"
app:srcCompat="@drawable/ic_repeat_white_24dp"
tools:ignore="MissingPrefix"
tools:tint="@color/md_black_1000" />
<androidx.appcompat.widget.AppCompatImageButton
android:id="@+id/nextButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="?attr/roundSelector"
android:padding="16dp"
android:scaleType="fitCenter"
app:layout_constraintBottom_toBottomOf="@+id/playPauseButton"
app:layout_constraintEnd_toStartOf="@+id/shuffleButton"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@+id/playPauseButton"
app:layout_constraintTop_toTopOf="@+id/playPauseButton"
app:srcCompat="@drawable/ic_skip_next_white_24dp"
tools:ignore="MissingPrefix" />
<androidx.appcompat.widget.AppCompatImageButton
android:id="@+id/previousButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="?attr/roundSelector"
android:padding="16dp"
android:scaleType="fitCenter"
app:layout_constraintBottom_toBottomOf="@+id/playPauseButton"
app:layout_constraintEnd_toStartOf="@+id/playPauseButton"
app:layout_constraintStart_toEndOf="@+id/repeatButton"
app:layout_constraintTop_toTopOf="@+id/playPauseButton"
app:srcCompat="@drawable/ic_skip_previous_white_24dp"
tools:ignore="MissingPrefix"
tools:tint="@color/md_black_1000" />
<androidx.appcompat.widget.AppCompatImageButton
android:id="@+id/shuffleButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="?attr/roundSelector"
android:padding="16dp"
android:scaleType="fitCenter"
app:layout_constraintBottom_toBottomOf="@+id/nextButton"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/nextButton"
app:layout_constraintTop_toTopOf="@+id/nextButton"
app:srcCompat="@drawable/ic_shuffle_white_24dp"
tools:ignore="MissingPrefix" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/playPauseButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:layout_marginBottom="16dp"
android:background="?attr/roundSelector"
app:fabCustomSize="64dp"
app:layout_constraintBottom_toTopOf="@+id/volumeFragmentContainer"
app:layout_constraintEnd_toStartOf="@+id/nextButton"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@+id/previousButton"
app:layout_constraintTop_toBottomOf="@+id/songCurrentProgress"
app:srcCompat="@drawable/ic_pause_white_64dp"
tools:tint="@color/md_black_1000" />
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.appcompat.widget.AppCompatImageButton
android:id="@+id/nextButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="?attr/roundSelector"
android:padding="16dp"
android:scaleType="fitCenter"
app:layout_constraintBottom_toBottomOf="@+id/playPauseButton"
app:layout_constraintEnd_toStartOf="@+id/shuffleButton"
app:layout_constraintStart_toEndOf="@+id/playPauseButton"
app:layout_constraintTop_toTopOf="@+id/playPauseButton"
app:srcCompat="@drawable/ic_skip_next_white_24dp"
tools:ignore="MissingPrefix"
tools:tint="@color/md_black_1000" />
<androidx.appcompat.widget.AppCompatImageButton
android:id="@+id/shuffleButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="?attr/roundSelector"
android:padding="16dp"
android:scaleType="fitCenter"
app:layout_constraintBottom_toBottomOf="@+id/nextButton"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/nextButton"
app:layout_constraintTop_toTopOf="@+id/nextButton"
app:srcCompat="@drawable/ic_shuffle_white_24dp"
tools:ignore="MissingPrefix"
tools:tint="@color/md_black_1000" />
<FrameLayout
android:id="@+id/volumeFragmentContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0" />
</LinearLayout>
android:layout_marginBottom="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toBottomOf="@+id/playPauseButton"
tools:background="@color/md_red_400"
tools:layout_height="52dp" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -1,216 +1,191 @@
<?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"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/playback_controls"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingTop="8dp"
tools:ignore="MissingPrefix">
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/playback_controls"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_vertical"
android:orientation="vertical"
tools:ignore="MissingPrefix">
<RelativeLayout
android:id="@+id/progressContainer"
android:layout_width="match_parent"
android:layout_height="28dp"
android:paddingStart="12dp"
android:paddingEnd="12dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<RelativeLayout
android:id="@+id/progressContainer"
android:layout_width="match_parent"
android:layout_height="28dp"
android:paddingStart="12dp"
android:paddingEnd="12dp"
app:layout_constraintBottom_toTopOf="@+id/titleContainer"
app:layout_constraintTop_toTopOf="parent">
<com.google.android.material.textview.MaterialTextView
android:id="@+id/songCurrentProgress"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_alignParentLeft="true"
android:gravity="center_vertical|left|end"
android:paddingLeft="8dp"
android:singleLine="true"
android:textColor="?android:attr/textColorSecondary"
android:textSize="12sp"
tools:ignore="RtlHardcoded,RtlSymmetry"
tools:text="00:22" />
<androidx.appcompat.widget.AppCompatSeekBar
android:id="@+id/progressSlider"
style="@style/Widget.MaterialProgressBar.ProgressBar.Horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_toLeftOf="@id/songTotalTime"
android:layout_toRightOf="@id/songCurrentProgress"
android:maxHeight="3dp"
android:progressDrawable="@drawable/color_progress_seek"
android:splitTrack="false"
android:thumb="@drawable/switch_thumb_material"
tools:ignore="RtlHardcoded,UnusedAttribute"
tools:progress="20" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/songTotalTime"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_alignParentRight="true"
android:gravity="center_vertical|right|end"
android:paddingRight="8dp"
android:singleLine="true"
android:textColor="?android:attr/textColorSecondary"
android:textSize="12sp"
tools:ignore="RtlHardcoded,RtlSymmetry"
tools:text="00:22" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/songTotalTime"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_alignParentRight="true"
android:gravity="center_vertical|right|end"
android:paddingRight="8dp"
android:singleLine="true"
android:textColor="?android:attr/textColorSecondary"
android:textSize="12sp"
tools:ignore="RtlHardcoded,RtlSymmetry"
tools:text="00:22" />
<androidx.appcompat.widget.AppCompatSeekBar
android:id="@+id/progressSlider"
style="@style/Widget.MaterialProgressBar.ProgressBar.Horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toLeftOf="@id/songTotalTime"
android:layout_toRightOf="@id/songCurrentProgress"
android:maxHeight="2dp"
android:progressDrawable="@drawable/color_progress_seek"
android:splitTrack="false"
tools:ignore="RtlHardcoded,UnusedAttribute"
tools:progress="20" />
</RelativeLayout>
<com.google.android.material.textview.MaterialTextView
android:id="@+id/songCurrentProgress"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_alignParentLeft="true"
android:gravity="center_vertical|left|end"
android:paddingLeft="8dp"
android:singleLine="true"
android:textColor="?android:attr/textColorSecondary"
android:textSize="12sp"
tools:ignore="RtlHardcoded,RtlSymmetry"
tools:text="00:22" />
</RelativeLayout>
<LinearLayout
android:id="@+id/titleContainer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fadingEdge="horizontal"
app:layout_constraintBottom_toTopOf="@+id/text"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/progressContainer">
<LinearLayout
android:id="@+id/titleContainer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toTopOf="@+id/text"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/progressContainer">
<com.google.android.material.textview.MaterialTextView
android:id="@+id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:ellipsize="marquee"
android:focusable="true"
android:focusableInTouchMode="true"
android:freezesText="true"
android:gravity="center"
android:marqueeRepeatLimit="marquee_forever"
android:paddingStart="16dp"
android:paddingEnd="16dp"
android:scrollHorizontally="true"
android:singleLine="true"
android:textAppearance="@style/TextViewHeadline6"
android:textColor="?android:attr/textColorPrimary"
android:textStyle="bold"
app:layout_constraintBottom_toTopOf="@+id/text"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/progressContainer"
tools:text="@tools:sample/lorem/random" />
</LinearLayout>
<com.google.android.material.textview.MaterialTextView
android:id="@+id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:ellipsize="marquee"
android:focusable="true"
android:focusableInTouchMode="true"
android:freezesText="true"
android:gravity="center"
android:marqueeRepeatLimit="marquee_forever"
android:paddingStart="16dp"
android:paddingEnd="16dp"
android:scrollHorizontally="true"
android:singleLine="true"
android:textAppearance="@style/TextViewHeadline6"
android:textColor="?android:attr/textColorPrimary"
android:textStyle="bold"
tools:text="@tools:sample/lorem/random" />
</LinearLayout>
<com.google.android.material.textview.MaterialTextView
android:id="@+id/text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:ellipsize="end"
android:gravity="center"
android:maxLines="2"
android:paddingStart="16dp"
android:paddingEnd="16dp"
android:textAppearance="@style/TextViewBody1"
android:textColor="?android:attr/textColorSecondary"
app:layout_constraintBottom_toTopOf="@+id/playerMediaControllerContainer"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/titleContainer"
tools:text="@tools:sample/lorem/random" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:ellipsize="end"
android:gravity="center"
android:maxLines="2"
android:paddingStart="16dp"
android:paddingEnd="16dp"
android:textAppearance="@style/TextViewBody1"
android:textColor="?android:attr/textColorSecondary"
app:layout_constraintBottom_toTopOf="@+id/playPauseButton"
app:layout_constraintTop_toBottomOf="@+id/titleContainer"
tools:text="@tools:sample/lorem/random" />
<androidx.appcompat.widget.AppCompatImageButton
android:id="@+id/repeatButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="?attr/roundSelector"
android:padding="16dp"
android:scaleType="fitCenter"
app:layout_constraintBottom_toBottomOf="@+id/previousButton"
app:layout_constraintEnd_toStartOf="@+id/previousButton"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/previousButton"
app:srcCompat="@drawable/ic_repeat_white_24dp"
tools:ignore="MissingPrefix"
tools:tint="@color/md_black_1000" />
<RelativeLayout
android:id="@+id/playerMediaControllerContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layoutDirection="ltr"
android:paddingStart="4dp"
android:paddingEnd="4dp"
app:layout_constraintBottom_toTopOf="@+id/volumeFragmentContainer"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/text"
tools:ignore="ContentDescription,UnusedAttribute"
tools:showIn="@layout/fragment_player_playback_controls">
<androidx.appcompat.widget.AppCompatImageButton
android:id="@+id/previousButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="?attr/roundSelector"
android:padding="16dp"
android:scaleType="fitCenter"
app:layout_constraintBottom_toBottomOf="@+id/playPauseButton"
app:layout_constraintEnd_toStartOf="@+id/playPauseButton"
app:layout_constraintStart_toEndOf="@+id/repeatButton"
app:layout_constraintTop_toTopOf="@+id/playPauseButton"
app:srcCompat="@drawable/ic_skip_previous_white_24dp"
tools:ignore="MissingPrefix"
tools:tint="@color/md_black_1000" />
<androidx.appcompat.widget.AppCompatImageButton
android:id="@+id/previousButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginEnd="8dp"
android:layout_toStartOf="@+id/dummy_fab"
android:background="?attr/roundSelector"
android:padding="16dp"
android:scaleType="fitCenter"
app:srcCompat="@drawable/ic_skip_previous_white_24dp"
tools:ignore="MissingPrefix"
tools:tint="@color/md_black_1000" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/playPauseButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="?attr/roundSelector"
app:layout_constraintBottom_toTopOf="@+id/volumeFragmentContainer"
app:layout_constraintEnd_toStartOf="@+id/nextButton"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@+id/previousButton"
app:layout_constraintTop_toBottomOf="@+id/text"
app:srcCompat="@drawable/ic_pause_white_64dp"
tools:layout_editor_absoluteX="178dp"
tools:tint="@color/md_black_1000" />
<androidx.appcompat.widget.AppCompatImageButton
android:id="@+id/nextButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginStart="8dp"
android:layout_toEndOf="@+id/dummy_fab"
android:background="?attr/roundSelector"
android:padding="16dp"
android:scaleType="fitCenter"
app:srcCompat="@drawable/ic_skip_next_white_24dp"
tools:ignore="MissingPrefix"
tools:tint="@color/md_black_1000" />
<androidx.appcompat.widget.AppCompatImageButton
android:id="@+id/nextButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="?attr/roundSelector"
android:padding="16dp"
android:scaleType="fitCenter"
app:layout_constraintBottom_toBottomOf="@+id/playPauseButton"
app:layout_constraintEnd_toStartOf="@+id/shuffleButton"
app:layout_constraintStart_toEndOf="@+id/playPauseButton"
app:layout_constraintTop_toTopOf="@+id/playPauseButton"
app:srcCompat="@drawable/ic_skip_next_white_24dp"
tools:ignore="MissingPrefix"
tools:tint="@color/md_black_1000" />
<androidx.appcompat.widget.AppCompatImageButton
android:id="@+id/repeatButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
android:background="?attr/roundSelector"
android:padding="16dp"
android:scaleType="fitCenter"
app:srcCompat="@drawable/ic_repeat_white_24dp"
tools:ignore="MissingPrefix"
tools:tint="@color/md_black_1000" />
<androidx.appcompat.widget.AppCompatImageButton
android:id="@+id/shuffleButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="?attr/roundSelector"
android:padding="16dp"
android:scaleType="fitCenter"
app:layout_constraintBottom_toBottomOf="@+id/nextButton"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/nextButton"
app:layout_constraintTop_toTopOf="@+id/nextButton"
app:srcCompat="@drawable/ic_shuffle_white_24dp"
tools:ignore="MissingPrefix"
tools:tint="@color/md_black_1000" />
<androidx.appcompat.widget.AppCompatImageButton
android:id="@+id/shuffleButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:background="?attr/roundSelector"
android:padding="16dp"
android:scaleType="fitCenter"
app:srcCompat="@drawable/ic_shuffle_white_24dp"
tools:ignore="MissingPrefix"
tools:tint="@color/md_black_1000" />
<Space
android:id="@+id/dummy_fab"
android:layout_width="56dp"
android:layout_height="56dp"
android:layout_centerInParent="true" />
<androidx.appcompat.widget.AppCompatImageButton
android:id="@+id/playPauseButton"
android:layout_width="52dp"
android:layout_height="52dp"
android:layout_centerInParent="true"
android:background="@drawable/color_circle_gradient"
android:elevation="4dp"
android:padding="16dp"
app:srcCompat="@drawable/ic_play_arrow_white_32dp" />
</RelativeLayout>
<FrameLayout
android:id="@+id/volumeFragmentContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingStart="8dp"
android:paddingEnd="8dp"
app:layout_constraintBottom_toBottomOf="parent"
tools:backgroundTint="@color/md_red_400"
tools:layout_height="52dp" />
</androidx.constraintlayout.widget.ConstraintLayout>
<FrameLayout
android:id="@+id/volumeFragmentContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toBottomOf="@+id/playPauseButton"
tools:background="@color/md_red_400"
tools:layout_height="52dp" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -16,6 +16,7 @@
android:paddingStart="12dp"
android:paddingEnd="12dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
@ -102,98 +103,90 @@
android:paddingStart="16dp"
android:paddingEnd="16dp"
android:textAppearance="@style/TextViewBody1"
app:layout_constraintBottom_toTopOf="@+id/playerMediaControllerContainer"
app:layout_constraintBottom_toTopOf="@+id/playPauseButton"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/titleContainer"
tools:text="@tools:sample/lorem/random" />
<RelativeLayout
android:id="@+id/playerMediaControllerContainer"
android:layout_width="match_parent"
<androidx.appcompat.widget.AppCompatImageButton
android:id="@+id/repeatButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layoutDirection="ltr"
android:paddingStart="4dp"
android:paddingEnd="4dp"
app:layout_constraintBottom_toTopOf="@+id/volumeFragmentContainer"
app:layout_constraintEnd_toEndOf="parent"
android:background="?attr/roundSelector"
android:padding="16dp"
android:scaleType="fitCenter"
app:layout_constraintBottom_toBottomOf="@+id/previousButton"
app:layout_constraintEnd_toStartOf="@+id/previousButton"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/previousButton"
app:srcCompat="@drawable/ic_repeat_white_24dp"
tools:ignore="MissingPrefix"
tools:tint="@color/md_black_1000" />
<androidx.appcompat.widget.AppCompatImageButton
android:id="@+id/previousButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="?attr/roundSelector"
android:padding="16dp"
android:scaleType="fitCenter"
app:layout_constraintBottom_toBottomOf="@+id/playPauseButton"
app:layout_constraintEnd_toStartOf="@+id/playPauseButton"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@+id/repeatButton"
app:layout_constraintTop_toTopOf="@+id/playPauseButton"
app:srcCompat="@drawable/ic_skip_previous_white_24dp"
tools:ignore="MissingPrefix"
tools:tint="@color/md_black_1000" />
<androidx.appcompat.widget.AppCompatImageButton
android:id="@+id/playPauseButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="?attr/roundSelector"
app:layout_constraintBottom_toTopOf="@+id/volumeFragmentContainer"
app:layout_constraintEnd_toStartOf="@+id/nextButton"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@+id/previousButton"
app:layout_constraintTop_toBottomOf="@+id/text"
tools:ignore="ContentDescription,UnusedAttribute"
tools:showIn="@layout/fragment_player_playback_controls">
app:srcCompat="@drawable/ic_pause_white_64dp"
tools:tint="@color/md_black_1000" />
<androidx.appcompat.widget.AppCompatImageButton
android:id="@+id/previousButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginEnd="8dp"
android:layout_toStartOf="@+id/dummy_fab"
android:background="?attr/roundSelector"
android:padding="16dp"
android:scaleType="fitCenter"
app:srcCompat="@drawable/ic_skip_previous_white_24dp"
tools:ignore="MissingPrefix"
tools:tint="@color/md_black_1000" />
<androidx.appcompat.widget.AppCompatImageButton
android:id="@+id/nextButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="?attr/roundSelector"
android:padding="16dp"
android:scaleType="fitCenter"
app:layout_constraintBottom_toBottomOf="@+id/playPauseButton"
app:layout_constraintEnd_toStartOf="@+id/shuffleButton"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@+id/playPauseButton"
app:layout_constraintTop_toTopOf="@+id/playPauseButton"
app:srcCompat="@drawable/ic_skip_next_white_24dp"
tools:ignore="MissingPrefix"
tools:tint="@color/md_black_1000" />
<androidx.appcompat.widget.AppCompatImageButton
android:id="@+id/nextButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginStart="8dp"
android:layout_toEndOf="@+id/dummy_fab"
android:background="?attr/roundSelector"
android:padding="16dp"
android:scaleType="fitCenter"
app:srcCompat="@drawable/ic_skip_next_white_24dp"
tools:ignore="MissingPrefix"
tools:tint="@color/md_black_1000" />
<androidx.appcompat.widget.AppCompatImageButton
android:id="@+id/shuffleButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="?attr/roundSelector"
android:padding="16dp"
android:scaleType="fitCenter"
app:layout_constraintBottom_toBottomOf="@+id/nextButton"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/nextButton"
app:layout_constraintTop_toTopOf="@+id/nextButton"
app:srcCompat="@drawable/ic_shuffle_white_24dp"
tools:ignore="MissingPrefix"
tools:tint="@color/md_black_1000" />
<androidx.appcompat.widget.AppCompatImageButton
android:id="@+id/repeatButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
android:background="?attr/roundSelector"
android:padding="16dp"
android:scaleType="fitCenter"
app:srcCompat="@drawable/ic_repeat_white_24dp"
tools:ignore="MissingPrefix"
tools:tint="@color/md_black_1000" />
<androidx.appcompat.widget.AppCompatImageButton
android:id="@+id/shuffleButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:background="?attr/roundSelector"
android:padding="16dp"
android:scaleType="fitCenter"
app:srcCompat="@drawable/ic_shuffle_white_24dp"
tools:ignore="MissingPrefix"
tools:tint="@color/md_black_1000" />
<Space
android:id="@+id/dummy_fab"
android:layout_width="56dp"
android:layout_height="56dp"
android:layout_centerInParent="true" />
<androidx.appcompat.widget.AppCompatImageButton
android:id="@+id/playPauseButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:background="?attr/roundSelector"
app:srcCompat="@drawable/ic_pause_white_64dp"
tools:tint="@color/md_black_1000" />
</RelativeLayout>
<FrameLayout
android:id="@+id/volumeFragmentContainer"

View File

@ -35,8 +35,6 @@
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_alignParentLeft="true"
android:gravity="center_vertical|left|end"
android:paddingLeft="8dp"
android:singleLine="true"
@ -50,8 +48,6 @@
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_alignParentRight="true"
android:gravity="center_vertical|right|end"
android:paddingRight="8dp"
android:singleLine="true"

View File

@ -14,6 +14,7 @@
android:paddingStart="12dp"
android:paddingEnd="12dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
@ -58,92 +59,78 @@
tools:progress="20" />
</RelativeLayout>
<RelativeLayout
android:id="@+id/playerMediaControllerContainer"
android:layout_width="match_parent"
<androidx.appcompat.widget.AppCompatImageButton
android:id="@+id/repeatButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layoutDirection="ltr"
android:paddingStart="4dp"
android:paddingEnd="4dp"
app:layout_constraintBottom_toTopOf="@+id/volumeFragmentContainer"
app:layout_constraintEnd_toEndOf="parent"
android:background="?attr/roundSelector"
android:padding="16dp"
app:layout_constraintBottom_toBottomOf="@+id/previousButton"
app:layout_constraintEnd_toStartOf="@+id/previousButton"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/previousButton"
app:srcCompat="@drawable/ic_repeat_white_24dp"
tools:ignore="MissingPrefix"
tools:tint="@color/md_black_1000" />
<androidx.appcompat.widget.AppCompatImageButton
android:id="@+id/previousButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="?attr/roundSelector"
android:padding="16dp"
app:layout_constraintBottom_toBottomOf="@+id/playPauseButton"
app:layout_constraintEnd_toStartOf="@+id/playPauseButton"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@+id/repeatButton"
app:layout_constraintTop_toTopOf="@+id/playPauseButton"
app:srcCompat="@drawable/ic_skip_previous_white_24dp"
tools:ignore="MissingPrefix"
tools:tint="@color/md_black_1000" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/playPauseButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="16dp"
app:layout_constraintBottom_toTopOf="@+id/volumeFragmentContainer"
app:layout_constraintEnd_toStartOf="@+id/nextButton"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@+id/previousButton"
app:layout_constraintTop_toBottomOf="@+id/progressContainer"
tools:ignore="ContentDescription,UnusedAttribute"
tools:showIn="@layout/fragment_player_playback_controls">
tools:backgroundTint="@color/md_green_500"
tools:srcCompat="@drawable/ic_play_arrow_white_32dp" />
<androidx.appcompat.widget.AppCompatImageButton
android:id="@+id/previousButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginEnd="8dp"
android:layout_toStartOf="@+id/dummy_fab"
android:background="?attr/roundSelector"
android:padding="16dp"
android:scaleType="fitCenter"
app:srcCompat="@drawable/ic_skip_previous_white_24dp"
tools:ignore="MissingPrefix"
tools:tint="@color/md_black_1000" />
<androidx.appcompat.widget.AppCompatImageButton
android:id="@+id/nextButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="?attr/roundSelector"
android:padding="16dp"
app:layout_constraintBottom_toBottomOf="@+id/playPauseButton"
app:layout_constraintEnd_toStartOf="@+id/shuffleButton"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@+id/playPauseButton"
app:layout_constraintTop_toTopOf="@+id/playPauseButton"
app:srcCompat="@drawable/ic_skip_next_white_24dp"
tools:ignore="MissingPrefix"
tools:tint="@color/md_black_1000" />
<androidx.appcompat.widget.AppCompatImageButton
android:id="@+id/nextButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginStart="8dp"
android:layout_toEndOf="@+id/dummy_fab"
android:background="?attr/roundSelector"
android:padding="16dp"
android:scaleType="fitCenter"
app:srcCompat="@drawable/ic_skip_next_white_24dp"
tools:ignore="MissingPrefix"
tools:tint="@color/md_black_1000" />
<androidx.appcompat.widget.AppCompatImageButton
android:id="@+id/repeatButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
android:background="?attr/roundSelector"
android:padding="16dp"
android:scaleType="fitCenter"
app:srcCompat="@drawable/ic_repeat_white_24dp"
tools:ignore="MissingPrefix"
tools:tint="@color/md_black_1000" />
<androidx.appcompat.widget.AppCompatImageButton
android:id="@+id/shuffleButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:background="?attr/roundSelector"
android:padding="16dp"
android:scaleType="fitCenter"
app:srcCompat="@drawable/ic_shuffle_white_24dp"
tools:ignore="MissingPrefix"
tools:tint="@color/md_black_1000" />
<Space
android:id="@+id/dummy_fab"
android:layout_width="56dp"
android:layout_height="56dp"
android:layout_centerInParent="true" />
<androidx.appcompat.widget.AppCompatImageButton
android:id="@+id/playPauseButton"
android:layout_width="52dp"
android:layout_height="52dp"
android:layout_centerInParent="true"
android:background="@drawable/color_circle_gradient"
android:elevation="4dp"
android:padding="16dp"
app:srcCompat="@drawable/ic_play_arrow_white_32dp" />
</RelativeLayout>
<androidx.appcompat.widget.AppCompatImageButton
android:id="@+id/shuffleButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="?attr/roundSelector"
android:padding="16dp"
app:layout_constraintBottom_toBottomOf="@+id/nextButton"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/nextButton"
app:layout_constraintTop_toTopOf="@+id/nextButton"
app:srcCompat="@drawable/ic_shuffle_white_24dp"
tools:ignore="MissingPrefix"
tools:tint="@color/md_black_1000" />
<FrameLayout
android:id="@+id/volumeFragmentContainer"
@ -155,4 +142,6 @@
app:layout_constraintBottom_toBottomOf="parent"
tools:backgroundTint="@color/md_red_400"
tools:layout_height="52dp" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -15,8 +15,6 @@
android:layout_height="28dp"
android:paddingStart="12dp"
android:paddingEnd="12dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<androidx.appcompat.widget.AppCompatSeekBar
@ -39,7 +37,6 @@
android:layout_height="match_parent"
android:layout_alignParentRight="true"
android:gravity="center_vertical|right|end"
android:paddingRight="8dp"
android:singleLine="true"
@ -53,8 +50,6 @@
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_alignParentLeft="true"
android:gravity="center_vertical|left|end"
android:paddingLeft="8dp"
android:singleLine="true"
@ -70,7 +65,6 @@
android:layout_height="wrap_content"
app:layout_constraintBottom_toTopOf="@+id/text"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/progressContainer">
@ -95,7 +89,6 @@
tools:text="@tools:sample/lorem/random" />
</LinearLayout>
<com.google.android.material.textview.MaterialTextView
android:id="@+id/text"
android:layout_width="match_parent"
@ -108,99 +101,83 @@
android:paddingEnd="16dp"
android:textAppearance="@style/TextViewBody1"
android:textColor="?android:attr/textColorSecondary"
app:layout_constraintBottom_toTopOf="@+id/playerMediaControllerContainer"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toTopOf="@+id/playPauseButton"
app:layout_constraintTop_toBottomOf="@+id/titleContainer"
tools:text="@tools:sample/lorem/random" />
<RelativeLayout
android:id="@+id/playerMediaControllerContainer"
android:layout_width="match_parent"
<androidx.appcompat.widget.AppCompatImageButton
android:id="@+id/repeatButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layoutDirection="ltr"
android:paddingStart="4dp"
android:paddingEnd="4dp"
app:layout_constraintBottom_toTopOf="@+id/volumeFragmentContainer"
app:layout_constraintEnd_toEndOf="parent"
android:background="?attr/roundSelector"
android:padding="16dp"
android:scaleType="fitCenter"
app:layout_constraintBottom_toBottomOf="@+id/previousButton"
app:layout_constraintEnd_toStartOf="@+id/previousButton"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/previousButton"
app:srcCompat="@drawable/ic_repeat_white_24dp"
tools:ignore="MissingPrefix"
tools:tint="@color/md_black_1000" />
<androidx.appcompat.widget.AppCompatImageButton
android:id="@+id/previousButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="?attr/roundSelector"
android:padding="16dp"
android:scaleType="fitCenter"
app:layout_constraintBottom_toBottomOf="@+id/playPauseButton"
app:layout_constraintEnd_toStartOf="@+id/playPauseButton"
app:layout_constraintStart_toEndOf="@+id/repeatButton"
app:layout_constraintTop_toTopOf="@+id/playPauseButton"
app:srcCompat="@drawable/ic_skip_previous_white_24dp"
tools:ignore="MissingPrefix"
tools:tint="@color/md_black_1000" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/playPauseButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="?attr/roundSelector"
app:layout_constraintBottom_toTopOf="@+id/volumeFragmentContainer"
app:layout_constraintEnd_toStartOf="@+id/nextButton"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@+id/previousButton"
app:layout_constraintTop_toBottomOf="@+id/text"
tools:ignore="ContentDescription,UnusedAttribute"
tools:showIn="@layout/fragment_player_playback_controls">
app:srcCompat="@drawable/ic_pause_white_64dp"
tools:tint="@color/md_black_1000" />
<androidx.appcompat.widget.AppCompatImageButton
android:id="@+id/previousButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginEnd="8dp"
android:layout_toStartOf="@+id/dummy_fab"
android:background="?attr/roundSelector"
android:padding="16dp"
android:scaleType="fitCenter"
app:srcCompat="@drawable/ic_skip_previous_white_24dp"
tools:ignore="MissingPrefix"
tools:tint="@color/md_black_1000" />
<androidx.appcompat.widget.AppCompatImageButton
android:id="@+id/nextButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="?attr/roundSelector"
android:padding="16dp"
android:scaleType="fitCenter"
app:layout_constraintBottom_toBottomOf="@+id/playPauseButton"
app:layout_constraintEnd_toStartOf="@+id/shuffleButton"
app:layout_constraintStart_toEndOf="@+id/playPauseButton"
app:layout_constraintTop_toTopOf="@+id/playPauseButton"
app:srcCompat="@drawable/ic_skip_next_white_24dp"
tools:ignore="MissingPrefix"
tools:tint="@color/md_black_1000" />
<androidx.appcompat.widget.AppCompatImageButton
android:id="@+id/nextButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginStart="8dp"
android:layout_toEndOf="@+id/dummy_fab"
android:background="?attr/roundSelector"
android:padding="16dp"
android:scaleType="fitCenter"
app:srcCompat="@drawable/ic_skip_next_white_24dp"
tools:ignore="MissingPrefix"
tools:tint="@color/md_black_1000" />
<androidx.appcompat.widget.AppCompatImageButton
android:id="@+id/repeatButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
android:background="?attr/roundSelector"
android:padding="16dp"
android:scaleType="fitCenter"
app:srcCompat="@drawable/ic_repeat_white_24dp"
tools:ignore="MissingPrefix"
tools:tint="@color/md_black_1000" />
<androidx.appcompat.widget.AppCompatImageButton
android:id="@+id/shuffleButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:background="?attr/roundSelector"
android:padding="16dp"
android:scaleType="fitCenter"
app:srcCompat="@drawable/ic_shuffle_white_24dp"
tools:ignore="MissingPrefix"
tools:tint="@color/md_black_1000" />
<Space
android:id="@+id/dummy_fab"
android:layout_width="56dp"
android:layout_height="56dp"
android:layout_centerInParent="true" />
<androidx.appcompat.widget.AppCompatImageButton
android:id="@+id/playPauseButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:background="@drawable/color_circle_gradient"
android:padding="16dp"
app:srcCompat="@drawable/ic_play_arrow_white_32dp" />
</RelativeLayout>
<androidx.appcompat.widget.AppCompatImageButton
android:id="@+id/shuffleButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="?attr/roundSelector"
android:padding="16dp"
android:scaleType="fitCenter"
app:layout_constraintBottom_toBottomOf="@+id/nextButton"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/nextButton"
app:layout_constraintTop_toTopOf="@+id/nextButton"
app:srcCompat="@drawable/ic_shuffle_white_24dp"
tools:ignore="MissingPrefix"
tools:tint="@color/md_black_1000" />
<FrameLayout
android:id="@+id/volumeFragmentContainer"

View File

@ -1,8 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_height="match_parent"
android:orientation="vertical"
tools:ignore="ContentDescription">
@ -11,17 +12,23 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="8dp"
android:gravity="center"
android:padding="16dp"
android:padding="8dp"
android:textAppearance="@style/TextViewHeadline6"
tools:text="Card layout" />
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="@tools:sample/full_names" />
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/image"
android:layout_width="match_parent"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="1"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/title"
tools:src="@tools:sample/backgrounds/scenic" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -814,4 +814,5 @@
<string name="pref_header_blacklist">Blacklist</string>
<string name="no_playing_queue">No songs playing</string>
<string name="nothing_to_see">Nothing to see</string>
</resources>

View File

@ -17,7 +17,6 @@ import android.widget.RadioButton;
import android.widget.SeekBar;
import android.widget.Switch;
import android.widget.TextView;
import androidx.annotation.CheckResult;
import androidx.annotation.ColorInt;
import androidx.annotation.DrawableRes;
@ -27,386 +26,15 @@ import androidx.appcompat.widget.AppCompatEditText;
import androidx.appcompat.widget.SwitchCompat;
import androidx.core.content.ContextCompat;
import androidx.core.graphics.drawable.DrawableCompat;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import java.lang.reflect.Field;
import code.name.monkey.appthemehelper.R;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import java.lang.reflect.Field;
/**
* @author afollestad, plusCubed
*/
public final class TintHelper {
@SuppressLint("PrivateResource")
@ColorInt
private static int getDefaultRippleColor(@NonNull Context context, boolean useDarkRipple) {
// Light ripple is actually translucent black, and vice versa
return ContextCompat.getColor(context, useDarkRipple ?
R.color.ripple_material_light : R.color.ripple_material_dark);
}
@NonNull
private static ColorStateList getDisabledColorStateList(@ColorInt int normal, @ColorInt int disabled) {
return new ColorStateList(new int[][]{
new int[]{-android.R.attr.state_enabled},
new int[]{android.R.attr.state_enabled}
}, new int[]{
disabled,
normal
});
}
@SuppressWarnings("deprecation")
public static void setTintSelector(@NonNull View view, @ColorInt final int color, final boolean darker, final boolean useDarkTheme) {
final boolean isColorLight = ColorUtil.INSTANCE.isColorLight(color);
final int disabled = ContextCompat.getColor(view.getContext(), useDarkTheme ? R.color.ate_button_disabled_dark : R.color.ate_button_disabled_light);
final int pressed = ColorUtil.INSTANCE.shiftColor(color, darker ? 0.9f : 1.1f);
final int activated = ColorUtil.INSTANCE.shiftColor(color, darker ? 1.1f : 0.9f);
final int rippleColor = getDefaultRippleColor(view.getContext(), isColorLight);
final int textColor = ContextCompat.getColor(view.getContext(), isColorLight ? R.color.ate_primary_text_light : R.color.ate_primary_text_dark);
final ColorStateList sl;
if (view instanceof Button) {
sl = getDisabledColorStateList(color, disabled);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP &&
view.getBackground() instanceof RippleDrawable) {
RippleDrawable rd = (RippleDrawable) view.getBackground();
rd.setColor(ColorStateList.valueOf(rippleColor));
}
// Disabled text color state for buttons, may get overridden later by ATE tags
final Button button = (Button) view;
button.setTextColor(getDisabledColorStateList(textColor, ContextCompat.getColor(view.getContext(), useDarkTheme ? R.color.ate_button_text_disabled_dark : R.color.ate_button_text_disabled_light)));
} else if (view instanceof FloatingActionButton) {
// FloatingActionButton doesn't support disabled state?
sl = new ColorStateList(new int[][]{
new int[]{-android.R.attr.state_pressed},
new int[]{android.R.attr.state_pressed}
}, new int[]{
color,
pressed
});
final FloatingActionButton fab = (FloatingActionButton) view;
fab.setRippleColor(rippleColor);
fab.setBackgroundTintList(sl);
if (fab.getDrawable() != null)
fab.setImageDrawable(createTintedDrawable(fab.getDrawable(), textColor));
return;
} else {
sl = new ColorStateList(
new int[][]{
new int[]{-android.R.attr.state_enabled},
new int[]{android.R.attr.state_enabled},
new int[]{android.R.attr.state_enabled, android.R.attr.state_pressed},
new int[]{android.R.attr.state_enabled, android.R.attr.state_activated},
new int[]{android.R.attr.state_enabled, android.R.attr.state_checked}
},
new int[]{
disabled,
color,
pressed,
activated,
activated
}
);
}
Drawable drawable = view.getBackground();
if (drawable != null) {
drawable = createTintedDrawable(drawable, sl);
ViewUtil.INSTANCE.setBackgroundCompat(view, drawable);
}
if (view instanceof TextView && !(view instanceof Button)) {
final TextView tv = (TextView) view;
tv.setTextColor(getDisabledColorStateList(textColor, ContextCompat.getColor(view.getContext(), isColorLight ? R.color.ate_text_disabled_light : R.color.ate_text_disabled_dark)));
}
}
public static void setTintAuto(final @NonNull View view, final @ColorInt int color,
boolean background) {
setTintAuto(view, color, background, ATHUtil.INSTANCE.isWindowBackgroundDark(view.getContext()));
}
@SuppressWarnings("deprecation")
public static void setTintAuto(final @NonNull View view, final @ColorInt int color,
boolean background, final boolean isDark) {
if (!background) {
if (view instanceof RadioButton)
setTint((RadioButton) view, color, isDark);
else if (view instanceof SeekBar)
setTint((SeekBar) view, color, isDark);
else if (view instanceof ProgressBar)
setTint((ProgressBar) view, color);
else if (view instanceof EditText)
setTint((EditText) view, color, isDark);
else if (view instanceof CheckBox)
setTint((CheckBox) view, color, isDark);
else if (view instanceof ImageView)
setTint((ImageView) view, color);
else if (view instanceof Switch)
setTint((Switch) view, color, isDark);
else if (view instanceof SwitchCompat)
setTint((SwitchCompat) view, color, isDark);
else background = true;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP &&
!background && view.getBackground() instanceof RippleDrawable) {
// Ripples for the above views (e.g. when you tap and hold a switch or checkbox)
RippleDrawable rd = (RippleDrawable) view.getBackground();
@SuppressLint("PrivateResource") final int unchecked = ContextCompat.getColor(view.getContext(),
isDark ? R.color.ripple_material_dark : R.color.ripple_material_light);
final int checked = ColorUtil.INSTANCE.adjustAlpha(color, 0.4f);
final ColorStateList sl = new ColorStateList(
new int[][]{
new int[]{-android.R.attr.state_activated, -android.R.attr.state_checked},
new int[]{android.R.attr.state_activated},
new int[]{android.R.attr.state_checked}
},
new int[]{
unchecked,
checked,
checked
}
);
rd.setColor(sl);
}
}
if (background) {
// Need to tint the background of a view
if (view instanceof FloatingActionButton || view instanceof Button) {
setTintSelector(view, color, false, isDark);
} else if (view.getBackground() != null) {
Drawable drawable = view.getBackground();
if (drawable != null) {
drawable = createTintedDrawable(drawable, color);
ViewUtil.INSTANCE.setBackgroundCompat(view, drawable);
}
}
}
}
public static void setTint(@NonNull RadioButton radioButton, @ColorInt int color, boolean useDarker) {
ColorStateList sl = new ColorStateList(new int[][]{
new int[]{-android.R.attr.state_enabled},
new int[]{android.R.attr.state_enabled, -android.R.attr.state_checked},
new int[]{android.R.attr.state_enabled, android.R.attr.state_checked}
}, new int[]{
// Rdio button includes own alpha for disabled state
ColorUtil.INSTANCE.stripAlpha(ContextCompat.getColor(radioButton.getContext(), useDarker ? R.color.ate_control_disabled_dark : R.color.ate_control_disabled_light)),
ContextCompat.getColor(radioButton.getContext(), useDarker ? R.color.ate_control_normal_dark : R.color.ate_control_normal_light),
color
});
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
radioButton.setButtonTintList(sl);
} else {
Drawable d = createTintedDrawable(ContextCompat.getDrawable(radioButton.getContext(), R.drawable.abc_btn_radio_material), sl);
radioButton.setButtonDrawable(d);
}
}
public static void setTint(@NonNull SeekBar seekBar, @ColorInt int color, boolean useDarker) {
final ColorStateList s1 = getDisabledColorStateList(color, ContextCompat.getColor(seekBar.getContext(), useDarker ? R.color.ate_control_disabled_dark : R.color.ate_control_disabled_light));
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
seekBar.setThumbTintList(s1);
seekBar.setProgressTintList(s1);
} else if (Build.VERSION.SDK_INT > Build.VERSION_CODES.GINGERBREAD_MR1) {
Drawable progressDrawable = createTintedDrawable(seekBar.getProgressDrawable(), s1);
seekBar.setProgressDrawable(progressDrawable);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
Drawable thumbDrawable = createTintedDrawable(seekBar.getThumb(), s1);
seekBar.setThumb(thumbDrawable);
}
} else {
PorterDuff.Mode mode = PorterDuff.Mode.SRC_IN;
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.GINGERBREAD_MR1) {
mode = PorterDuff.Mode.MULTIPLY;
}
if (seekBar.getIndeterminateDrawable() != null)
seekBar.getIndeterminateDrawable().setColorFilter(color, mode);
if (seekBar.getProgressDrawable() != null)
seekBar.getProgressDrawable().setColorFilter(color, mode);
}
}
public static void setTint(@NonNull ProgressBar progressBar, @ColorInt int color) {
setTint(progressBar, color, false);
}
public static void setTint(@NonNull ProgressBar progressBar, @ColorInt int color, boolean skipIndeterminate) {
ColorStateList sl = ColorStateList.valueOf(color);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
progressBar.setProgressTintList(sl);
progressBar.setSecondaryProgressTintList(sl);
if (!skipIndeterminate)
progressBar.setIndeterminateTintList(sl);
} else {
PorterDuff.Mode mode = PorterDuff.Mode.SRC_IN;
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.GINGERBREAD_MR1) {
mode = PorterDuff.Mode.MULTIPLY;
}
if (!skipIndeterminate && progressBar.getIndeterminateDrawable() != null)
progressBar.getIndeterminateDrawable().setColorFilter(color, mode);
if (progressBar.getProgressDrawable() != null)
progressBar.getProgressDrawable().setColorFilter(color, mode);
}
}
public static void setTint(@NonNull EditText editText, @ColorInt int color, boolean useDarker) {
final ColorStateList editTextColorStateList = new ColorStateList(new int[][]{
new int[]{-android.R.attr.state_enabled},
new int[]{android.R.attr.state_enabled, -android.R.attr.state_pressed, -android.R.attr.state_focused},
new int[]{}
}, new int[]{
ContextCompat.getColor(editText.getContext(), useDarker ? R.color.ate_text_disabled_dark : R.color.ate_text_disabled_light),
ContextCompat.getColor(editText.getContext(), useDarker ? R.color.ate_control_normal_dark : R.color.ate_control_normal_light),
color
});
if (editText instanceof AppCompatEditText) {
((AppCompatEditText) editText).setSupportBackgroundTintList(editTextColorStateList);
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
editText.setBackgroundTintList(editTextColorStateList);
}
setCursorTint(editText, color);
}
public static void setTint(@NonNull CheckBox box, @ColorInt int color, boolean useDarker) {
ColorStateList sl = new ColorStateList(new int[][]{
new int[]{-android.R.attr.state_enabled},
new int[]{android.R.attr.state_enabled, -android.R.attr.state_checked},
new int[]{android.R.attr.state_enabled, android.R.attr.state_checked}
}, new int[]{
ContextCompat.getColor(box.getContext(), useDarker ? R.color.ate_control_disabled_dark : R.color.ate_control_disabled_light),
ContextCompat.getColor(box.getContext(), useDarker ? R.color.ate_control_normal_dark : R.color.ate_control_normal_light),
color
});
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
box.setButtonTintList(sl);
} else {
Drawable drawable = createTintedDrawable(ContextCompat.getDrawable(box.getContext(), R.drawable.abc_btn_check_material), sl);
box.setButtonDrawable(drawable);
}
}
public static void setTint(@NonNull ImageView image, @ColorInt int color) {
image.setColorFilter(color, PorterDuff.Mode.SRC_ATOP);
}
private static Drawable modifySwitchDrawable(@NonNull Context context, @NonNull Drawable from, @ColorInt int tint, boolean thumb, boolean compatSwitch, boolean useDarker) {
if (useDarker) {
tint = ColorUtil.INSTANCE.shiftColor(tint, 1.1f);
}
tint = ColorUtil.INSTANCE.adjustAlpha(tint, (compatSwitch && !thumb) ? 0.5f : 1.0f);
int disabled;
int normal;
if (thumb) {
disabled = ContextCompat.getColor(context, useDarker ? R.color.ate_switch_thumb_disabled_dark : R.color.ate_switch_thumb_disabled_light);
normal = ContextCompat.getColor(context, useDarker ? R.color.ate_switch_thumb_normal_dark : R.color.ate_switch_thumb_normal_light);
} else {
disabled = ContextCompat.getColor(context, useDarker ? R.color.ate_switch_track_disabled_dark : R.color.ate_switch_track_disabled_light);
normal = ContextCompat.getColor(context, useDarker ? R.color.ate_switch_track_normal_dark : R.color.ate_switch_track_normal_light);
}
// Stock switch includes its own alpha
if (!compatSwitch) {
normal = ColorUtil.INSTANCE.stripAlpha(normal);
}
final ColorStateList sl = new ColorStateList(
new int[][]{
new int[]{-android.R.attr.state_enabled},
new int[]{android.R.attr.state_enabled, -android.R.attr.state_activated, -android.R.attr.state_checked},
new int[]{android.R.attr.state_enabled, android.R.attr.state_activated},
new int[]{android.R.attr.state_enabled, android.R.attr.state_checked}
},
new int[]{
disabled,
normal,
tint,
tint
}
);
return createTintedDrawable(from, sl);
}
public static void setTint(@NonNull Switch switchView, @ColorInt int color, boolean useDarker) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) return;
if (switchView.getTrackDrawable() != null) {
switchView.setTrackDrawable(modifySwitchDrawable(switchView.getContext(),
switchView.getTrackDrawable(), color, false, false, useDarker));
}
if (switchView.getThumbDrawable() != null) {
switchView.setThumbDrawable(modifySwitchDrawable(switchView.getContext(),
switchView.getThumbDrawable(), color, true, false, useDarker));
}
}
public static void setTint(@NonNull SwitchCompat switchView, @ColorInt int color, boolean useDarker) {
if (switchView.getTrackDrawable() != null) {
switchView.setTrackDrawable(modifySwitchDrawable(switchView.getContext(),
switchView.getTrackDrawable(), color, false, true, useDarker));
}
if (switchView.getThumbDrawable() != null) {
switchView.setThumbDrawable(modifySwitchDrawable(switchView.getContext(),
switchView.getThumbDrawable(), color, true, true, useDarker));
}
}
@CheckResult
@Nullable
public static Drawable createTintedDrawable(Context context,
@DrawableRes int res, @ColorInt int color) {
Drawable drawable = ContextCompat.getDrawable(context, res);
return createTintedDrawable(drawable, color);
}
// This returns a NEW Drawable because of the mutate() call. The mutate() call is necessary because Drawables with the same resource have shared states otherwise.
@CheckResult
@Nullable
public static Drawable createTintedDrawable(@Nullable Drawable drawable, @ColorInt int color) {
if (drawable == null) return null;
drawable = DrawableCompat.wrap(drawable.mutate());
DrawableCompat.setTintMode(drawable, PorterDuff.Mode.SRC_IN);
DrawableCompat.setTint(drawable, color);
return drawable;
}
// This returns a NEW Drawable because of the mutate() call. The mutate() call is necessary because Drawables with the same resource have shared states otherwise.
@CheckResult
@Nullable
public static Drawable createTintedDrawable(@Nullable Drawable drawable, @NonNull ColorStateList sl) {
if (drawable == null) return null;
drawable = DrawableCompat.wrap(drawable.mutate());
DrawableCompat.setTintList(drawable, sl);
return drawable;
}
public static void setCursorTint(@NonNull EditText editText, @ColorInt int color) {
try {
Field fCursorDrawableRes = TextView.class.getDeclaredField("mCursorDrawableRes");
fCursorDrawableRes.setAccessible(true);
int mCursorDrawableRes = fCursorDrawableRes.getInt(editText);
Field fEditor = TextView.class.getDeclaredField("mEditor");
fEditor.setAccessible(true);
Object editor = fEditor.get(editText);
Class<?> clazz = editor.getClass();
Field fCursorDrawable = clazz.getDeclaredField("mCursorDrawable");
fCursorDrawable.setAccessible(true);
Drawable[] drawables = new Drawable[2];
drawables[0] = ContextCompat.getDrawable(editText.getContext(), mCursorDrawableRes);
drawables[0] = createTintedDrawable(drawables[0], color);
drawables[1] = ContextCompat.getDrawable(editText.getContext(), mCursorDrawableRes);
drawables[1] = createTintedDrawable(drawables[1], color);
fCursorDrawable.set(editor, drawables);
} catch (Exception e) {
e.printStackTrace();
}
}
@SuppressWarnings("JavaReflectionMemberAccess")
public static void colorHandles(@NonNull TextView view, int color) {
try {
@ -448,4 +76,411 @@ public final class TintHelper {
e.printStackTrace();
}
}
@CheckResult
@Nullable
public static Drawable createTintedDrawable(Context context,
@DrawableRes int res, @ColorInt int color) {
Drawable drawable = ContextCompat.getDrawable(context, res);
return createTintedDrawable(drawable, color);
}
// This returns a NEW Drawable because of the mutate() call. The mutate() call is necessary because Drawables with the same resource have shared states otherwise.
@CheckResult
@Nullable
public static Drawable createTintedDrawable(@Nullable Drawable drawable, @ColorInt int color) {
if (drawable == null) {
return null;
}
drawable = DrawableCompat.wrap(drawable.mutate());
DrawableCompat.setTintMode(drawable, PorterDuff.Mode.SRC_IN);
DrawableCompat.setTint(drawable, color);
return drawable;
}
// This returns a NEW Drawable because of the mutate() call. The mutate() call is necessary because Drawables with the same resource have shared states otherwise.
@CheckResult
@Nullable
public static Drawable createTintedDrawable(@Nullable Drawable drawable, @NonNull ColorStateList sl) {
if (drawable == null) {
return null;
}
drawable = DrawableCompat.wrap(drawable.mutate());
DrawableCompat.setTintList(drawable, sl);
return drawable;
}
public static void setCursorTint(@NonNull EditText editText, @ColorInt int color) {
try {
Field fCursorDrawableRes = TextView.class.getDeclaredField("mCursorDrawableRes");
fCursorDrawableRes.setAccessible(true);
int mCursorDrawableRes = fCursorDrawableRes.getInt(editText);
Field fEditor = TextView.class.getDeclaredField("mEditor");
fEditor.setAccessible(true);
Object editor = fEditor.get(editText);
Class<?> clazz = editor.getClass();
Field fCursorDrawable = clazz.getDeclaredField("mCursorDrawable");
fCursorDrawable.setAccessible(true);
Drawable[] drawables = new Drawable[2];
drawables[0] = ContextCompat.getDrawable(editText.getContext(), mCursorDrawableRes);
drawables[0] = createTintedDrawable(drawables[0], color);
drawables[1] = ContextCompat.getDrawable(editText.getContext(), mCursorDrawableRes);
drawables[1] = createTintedDrawable(drawables[1], color);
fCursorDrawable.set(editor, drawables);
} catch (Exception e) {
e.printStackTrace();
}
}
public static void setTint(@NonNull RadioButton radioButton, @ColorInt int color, boolean useDarker) {
ColorStateList sl = new ColorStateList(new int[][]{
new int[]{-android.R.attr.state_enabled},
new int[]{android.R.attr.state_enabled, -android.R.attr.state_checked},
new int[]{android.R.attr.state_enabled, android.R.attr.state_checked}
}, new int[]{
// Rdio button includes own alpha for disabled state
ColorUtil.INSTANCE.stripAlpha(ContextCompat.getColor(radioButton.getContext(),
useDarker ? R.color.ate_control_disabled_dark : R.color.ate_control_disabled_light)),
ContextCompat.getColor(radioButton.getContext(),
useDarker ? R.color.ate_control_normal_dark : R.color.ate_control_normal_light),
color
});
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
radioButton.setButtonTintList(sl);
} else {
Drawable d = createTintedDrawable(
ContextCompat.getDrawable(radioButton.getContext(), R.drawable.abc_btn_radio_material), sl);
radioButton.setButtonDrawable(d);
}
}
public static void setTint(@NonNull SeekBar seekBar, @ColorInt int color, boolean useDarker) {
final ColorStateList s1 = getDisabledColorStateList(color, ContextCompat.getColor(seekBar.getContext(),
useDarker ? R.color.ate_control_disabled_dark : R.color.ate_control_disabled_light));
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
seekBar.setThumbTintList(s1);
seekBar.setProgressTintList(s1);
} else if (Build.VERSION.SDK_INT > Build.VERSION_CODES.GINGERBREAD_MR1) {
Drawable progressDrawable = createTintedDrawable(seekBar.getProgressDrawable(), s1);
seekBar.setProgressDrawable(progressDrawable);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
Drawable thumbDrawable = createTintedDrawable(seekBar.getThumb(), s1);
seekBar.setThumb(thumbDrawable);
}
} else {
PorterDuff.Mode mode = PorterDuff.Mode.SRC_IN;
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.GINGERBREAD_MR1) {
mode = PorterDuff.Mode.MULTIPLY;
}
if (seekBar.getIndeterminateDrawable() != null) {
seekBar.getIndeterminateDrawable().setColorFilter(color, mode);
}
if (seekBar.getProgressDrawable() != null) {
seekBar.getProgressDrawable().setColorFilter(color, mode);
}
}
}
public static void setTint(@NonNull ProgressBar progressBar, @ColorInt int color) {
setTint(progressBar, color, false);
}
public static void setTint(@NonNull ProgressBar progressBar, @ColorInt int color, boolean skipIndeterminate) {
ColorStateList sl = ColorStateList.valueOf(color);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
progressBar.setProgressTintList(sl);
progressBar.setSecondaryProgressTintList(sl);
if (!skipIndeterminate) {
progressBar.setIndeterminateTintList(sl);
}
} else {
PorterDuff.Mode mode = PorterDuff.Mode.SRC_IN;
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.GINGERBREAD_MR1) {
mode = PorterDuff.Mode.MULTIPLY;
}
if (!skipIndeterminate && progressBar.getIndeterminateDrawable() != null) {
progressBar.getIndeterminateDrawable().setColorFilter(color, mode);
}
if (progressBar.getProgressDrawable() != null) {
progressBar.getProgressDrawable().setColorFilter(color, mode);
}
}
}
public static void setTint(@NonNull EditText editText, @ColorInt int color, boolean useDarker) {
final ColorStateList editTextColorStateList = new ColorStateList(new int[][]{
new int[]{-android.R.attr.state_enabled},
new int[]{android.R.attr.state_enabled, -android.R.attr.state_pressed, -android.R.attr.state_focused},
new int[]{}
}, new int[]{
ContextCompat.getColor(editText.getContext(),
useDarker ? R.color.ate_text_disabled_dark : R.color.ate_text_disabled_light),
ContextCompat.getColor(editText.getContext(),
useDarker ? R.color.ate_control_normal_dark : R.color.ate_control_normal_light),
color
});
if (editText instanceof AppCompatEditText) {
((AppCompatEditText) editText).setSupportBackgroundTintList(editTextColorStateList);
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
editText.setBackgroundTintList(editTextColorStateList);
}
setCursorTint(editText, color);
}
public static void setTint(@NonNull CheckBox box, @ColorInt int color, boolean useDarker) {
ColorStateList sl = new ColorStateList(new int[][]{
new int[]{-android.R.attr.state_enabled},
new int[]{android.R.attr.state_enabled, -android.R.attr.state_checked},
new int[]{android.R.attr.state_enabled, android.R.attr.state_checked}
}, new int[]{
ContextCompat.getColor(box.getContext(),
useDarker ? R.color.ate_control_disabled_dark : R.color.ate_control_disabled_light),
ContextCompat.getColor(box.getContext(),
useDarker ? R.color.ate_control_normal_dark : R.color.ate_control_normal_light),
color
});
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
box.setButtonTintList(sl);
} else {
Drawable drawable = createTintedDrawable(
ContextCompat.getDrawable(box.getContext(), R.drawable.abc_btn_check_material), sl);
box.setButtonDrawable(drawable);
}
}
public static void setTint(@NonNull ImageView image, @ColorInt int color) {
image.setColorFilter(color, PorterDuff.Mode.SRC_ATOP);
}
public static void setTint(@NonNull Switch switchView, @ColorInt int color, boolean useDarker) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
return;
}
if (switchView.getTrackDrawable() != null) {
switchView.setTrackDrawable(modifySwitchDrawable(switchView.getContext(),
switchView.getTrackDrawable(), color, false, false, useDarker));
}
if (switchView.getThumbDrawable() != null) {
switchView.setThumbDrawable(modifySwitchDrawable(switchView.getContext(),
switchView.getThumbDrawable(), color, true, false, useDarker));
}
}
public static void setTint(@NonNull SwitchCompat switchView, @ColorInt int color, boolean useDarker) {
if (switchView.getTrackDrawable() != null) {
switchView.setTrackDrawable(modifySwitchDrawable(switchView.getContext(),
switchView.getTrackDrawable(), color, false, true, useDarker));
}
if (switchView.getThumbDrawable() != null) {
switchView.setThumbDrawable(modifySwitchDrawable(switchView.getContext(),
switchView.getThumbDrawable(), color, true, true, useDarker));
}
}
public static void setTintAuto(final @NonNull View view, final @ColorInt int color,
boolean background) {
setTintAuto(view, color, background, ATHUtil.INSTANCE.isWindowBackgroundDark(view.getContext()));
}
@SuppressWarnings("deprecation")
public static void setTintAuto(final @NonNull View view, final @ColorInt int color,
boolean background, final boolean isDark) {
if (!background) {
if (view instanceof FloatingActionButton) {
setTint((FloatingActionButton) view, color, isDark);
} else if (view instanceof RadioButton) {
setTint((RadioButton) view, color, isDark);
} else if (view instanceof SeekBar) {
setTint((SeekBar) view, color, isDark);
} else if (view instanceof ProgressBar) {
setTint((ProgressBar) view, color);
} else if (view instanceof EditText) {
setTint((EditText) view, color, isDark);
} else if (view instanceof CheckBox) {
setTint((CheckBox) view, color, isDark);
} else if (view instanceof ImageView) {
setTint((ImageView) view, color);
} else if (view instanceof Switch) {
setTint((Switch) view, color, isDark);
} else if (view instanceof SwitchCompat) {
setTint((SwitchCompat) view, color, isDark);
} else {
background = true;
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP &&
!background && view.getBackground() instanceof RippleDrawable) {
// Ripples for the above views (e.g. when you tap and hold a switch or checkbox)
RippleDrawable rd = (RippleDrawable) view.getBackground();
@SuppressLint("PrivateResource") final int unchecked = ContextCompat.getColor(view.getContext(),
isDark ? R.color.ripple_material_dark : R.color.ripple_material_light);
final int checked = ColorUtil.INSTANCE.adjustAlpha(color, 0.4f);
final ColorStateList sl = new ColorStateList(
new int[][]{
new int[]{-android.R.attr.state_activated, -android.R.attr.state_checked},
new int[]{android.R.attr.state_activated},
new int[]{android.R.attr.state_checked}
},
new int[]{
unchecked,
checked,
checked
}
);
rd.setColor(sl);
}
}
if (background) {
// Need to tint the background of a view
if (view instanceof FloatingActionButton || view instanceof Button) {
setTintSelector(view, color, false, isDark);
} else if (view.getBackground() != null) {
Drawable drawable = view.getBackground();
if (drawable != null) {
drawable = createTintedDrawable(drawable, color);
ViewUtil.INSTANCE.setBackgroundCompat(view, drawable);
}
}
}
}
@SuppressWarnings("deprecation")
public static void setTintSelector(@NonNull View view, @ColorInt final int color, final boolean darker,
final boolean useDarkTheme) {
final boolean isColorLight = ColorUtil.INSTANCE.isColorLight(color);
final int disabled = ContextCompat.getColor(view.getContext(),
useDarkTheme ? R.color.ate_button_disabled_dark : R.color.ate_button_disabled_light);
final int pressed = ColorUtil.INSTANCE.shiftColor(color, darker ? 0.9f : 1.1f);
final int activated = ColorUtil.INSTANCE.shiftColor(color, darker ? 1.1f : 0.9f);
final int rippleColor = getDefaultRippleColor(view.getContext(), isColorLight);
final int textColor = ContextCompat.getColor(view.getContext(),
isColorLight ? R.color.ate_primary_text_light : R.color.ate_primary_text_dark);
final ColorStateList sl;
if (view instanceof Button) {
sl = getDisabledColorStateList(color, disabled);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP &&
view.getBackground() instanceof RippleDrawable) {
RippleDrawable rd = (RippleDrawable) view.getBackground();
rd.setColor(ColorStateList.valueOf(rippleColor));
}
// Disabled text color state for buttons, may get overridden later by ATE tags
final Button button = (Button) view;
button.setTextColor(getDisabledColorStateList(textColor, ContextCompat.getColor(view.getContext(),
useDarkTheme ? R.color.ate_button_text_disabled_dark : R.color.ate_button_text_disabled_light)));
} else if (view instanceof FloatingActionButton) {
// FloatingActionButton doesn't support disabled state?
sl = new ColorStateList(new int[][]{
new int[]{-android.R.attr.state_pressed},
new int[]{android.R.attr.state_pressed}
}, new int[]{
color,
pressed
});
final FloatingActionButton fab = (FloatingActionButton) view;
fab.setRippleColor(rippleColor);
fab.setBackgroundTintList(sl);
if (fab.getDrawable() != null) {
fab.setImageDrawable(createTintedDrawable(fab.getDrawable(), textColor));
}
return;
} else {
sl = new ColorStateList(
new int[][]{
new int[]{-android.R.attr.state_enabled},
new int[]{android.R.attr.state_enabled},
new int[]{android.R.attr.state_enabled, android.R.attr.state_pressed},
new int[]{android.R.attr.state_enabled, android.R.attr.state_activated},
new int[]{android.R.attr.state_enabled, android.R.attr.state_checked}
},
new int[]{
disabled,
color,
pressed,
activated,
activated
}
);
}
Drawable drawable = view.getBackground();
if (drawable != null) {
drawable = createTintedDrawable(drawable, sl);
ViewUtil.INSTANCE.setBackgroundCompat(view, drawable);
}
if (view instanceof TextView && !(view instanceof Button)) {
final TextView tv = (TextView) view;
tv.setTextColor(getDisabledColorStateList(textColor, ContextCompat.getColor(view.getContext(),
isColorLight ? R.color.ate_text_disabled_light : R.color.ate_text_disabled_dark)));
}
}
@SuppressLint("PrivateResource")
@ColorInt
private static int getDefaultRippleColor(@NonNull Context context, boolean useDarkRipple) {
// Light ripple is actually translucent black, and vice versa
return ContextCompat.getColor(context, useDarkRipple ?
R.color.ripple_material_light : R.color.ripple_material_dark);
}
@NonNull
private static ColorStateList getDisabledColorStateList(@ColorInt int normal, @ColorInt int disabled) {
return new ColorStateList(new int[][]{
new int[]{-android.R.attr.state_enabled},
new int[]{android.R.attr.state_enabled}
}, new int[]{
disabled,
normal
});
}
private static Drawable modifySwitchDrawable(@NonNull Context context, @NonNull Drawable from, @ColorInt int tint,
boolean thumb, boolean compatSwitch, boolean useDarker) {
if (useDarker) {
tint = ColorUtil.INSTANCE.shiftColor(tint, 1.1f);
}
tint = ColorUtil.INSTANCE.adjustAlpha(tint, (compatSwitch && !thumb) ? 0.5f : 1.0f);
int disabled;
int normal;
if (thumb) {
disabled = ContextCompat.getColor(context,
useDarker ? R.color.ate_switch_thumb_disabled_dark : R.color.ate_switch_thumb_disabled_light);
normal = ContextCompat.getColor(context,
useDarker ? R.color.ate_switch_thumb_normal_dark : R.color.ate_switch_thumb_normal_light);
} else {
disabled = ContextCompat.getColor(context,
useDarker ? R.color.ate_switch_track_disabled_dark : R.color.ate_switch_track_disabled_light);
normal = ContextCompat.getColor(context,
useDarker ? R.color.ate_switch_track_normal_dark : R.color.ate_switch_track_normal_light);
}
// Stock switch includes its own alpha
if (!compatSwitch) {
normal = ColorUtil.INSTANCE.stripAlpha(normal);
}
final ColorStateList sl = new ColorStateList(
new int[][]{
new int[]{-android.R.attr.state_enabled},
new int[]{android.R.attr.state_enabled, -android.R.attr.state_activated,
-android.R.attr.state_checked},
new int[]{android.R.attr.state_enabled, android.R.attr.state_activated},
new int[]{android.R.attr.state_enabled, android.R.attr.state_checked}
},
new int[]{
disabled,
normal,
tint,
tint
}
);
return createTintedDrawable(from, sl);
}
private static void setTint(final FloatingActionButton view, final int color, final boolean isDark) {
view.setImageTintList(ColorStateList.valueOf(color));
}
}