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 androidx.annotation.StringRes
import code.name.monkey.retromusic.R 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), ADAPTIVE(R.string.adaptive, R.drawable.np_adaptive, 10),
BLUR(R.string.blur, R.drawable.np_blur, 4), BLUR(R.string.blur, R.drawable.np_blur, 4),
BLUR_CARD(R.string.blur_card, R.drawable.np_blur_card, 9), BLUR_CARD(R.string.blur_card, R.drawable.np_blur_card, 9),
CARD(R.string.card, R.drawable.np_card, 6), CARD(R.string.card, R.drawable.np_card, 6),
COLOR(R.string.color, R.drawable.np_color, 5), 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), FULL(R.string.full, R.drawable.np_full, 2),
MATERIAL(R.string.material, R.drawable.np_material, 11), 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), 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), 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.songTotalTime
import kotlinx.android.synthetic.main.fragment_color_player_playback_controls.text 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_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() { class ColorPlaybackControlsFragment : AbsPlayerControlsFragment() {
@ -91,7 +94,6 @@ class ColorPlaybackControlsFragment : AbsPlayerControlsFragment() {
updateShuffleState() updateShuffleState()
} }
fun setDark(textColor: Int, background: Int) { fun setDark(textColor: Int, background: Int) {
setDark(textColor) setDark(textColor)
TintHelper.setTintAuto(playPauseButton, background, false) TintHelper.setTintAuto(playPauseButton, background, false)
@ -123,15 +125,13 @@ class ColorPlaybackControlsFragment : AbsPlayerControlsFragment() {
playPauseButton.setOnClickListener(PlayPauseButtonOnClickHandler()) playPauseButton.setOnClickListener(PlayPauseButtonOnClickHandler())
} }
private fun updatePlayPauseDrawableState() { private fun updatePlayPauseDrawableState() {
when { when {
MusicPlayerRemote.isPlaying -> playPauseButton.setImageResource(R.drawable.ic_pause_white_24dp) 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() { private fun setUpMusicControllers() {
setUpPlayPauseFab() setUpPlayPauseFab()
setUpPrevNext() setUpPrevNext()
@ -157,7 +157,10 @@ class ColorPlaybackControlsFragment : AbsPlayerControlsFragment() {
override fun updateShuffleState() { override fun updateShuffleState() {
when (MusicPlayerRemote.shuffleMode) { 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) else -> shuffleButton.setColorFilter(lastDisabledPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
} }
} }
@ -183,14 +186,13 @@ class ColorPlaybackControlsFragment : AbsPlayerControlsFragment() {
} }
} }
public override fun show() { public override fun show() {
playPauseButton!!.animate() playPauseButton!!.animate()
.scaleX(1f) .scaleX(1f)
.scaleY(1f) .scaleY(1f)
.rotation(360f) .rotation(360f)
.setInterpolator(DecelerateInterpolator()) .setInterpolator(DecelerateInterpolator())
.start() .start()
} }
public override fun hide() { 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.text
import kotlinx.android.synthetic.main.fragment_player_playback_controls.title import kotlinx.android.synthetic.main.fragment_player_playback_controls.title
class PlayerPlaybackControlsFragment : AbsPlayerControlsFragment() { class PlayerPlaybackControlsFragment : AbsPlayerControlsFragment() {
private var lastPlaybackControlsColor: Int = 0 private var lastPlaybackControlsColor: Int = 0
@ -48,8 +47,10 @@ class PlayerPlaybackControlsFragment : AbsPlayerControlsFragment() {
progressViewUpdateHelper = MusicProgressViewUpdateHelper(this) progressViewUpdateHelper = MusicProgressViewUpdateHelper(this)
} }
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, override fun onCreateView(
savedInstanceState: Bundle?): View? { inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment_player_playback_controls, container, false) 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) val colorBg = ATHUtil.resolveColor(requireContext(), android.R.attr.colorBackground)
if (ColorUtil.isColorLight(colorBg)) { if (ColorUtil.isColorLight(colorBg)) {
lastPlaybackControlsColor = MaterialValueHelper.getSecondaryTextColor(requireContext(), true) lastPlaybackControlsColor = MaterialValueHelper.getSecondaryTextColor(requireContext(), true)
lastDisabledPlaybackControlsColor = MaterialValueHelper.getSecondaryDisabledTextColor(requireContext(), true) lastDisabledPlaybackControlsColor =
MaterialValueHelper.getSecondaryDisabledTextColor(requireContext(), true)
} else { } else {
lastPlaybackControlsColor = MaterialValueHelper.getPrimaryTextColor(requireContext(), false) lastPlaybackControlsColor = MaterialValueHelper.getPrimaryTextColor(requireContext(), false)
lastDisabledPlaybackControlsColor = MaterialValueHelper.getPrimaryDisabledTextColor(requireContext(), false) lastDisabledPlaybackControlsColor =
MaterialValueHelper.getPrimaryDisabledTextColor(requireContext(), false)
} }
val colorFinal = if (PreferenceUtil.getInstance(requireContext()).adaptiveColor) { val colorFinal = if (PreferenceUtil.getInstance(requireContext()).adaptiveColor) {
@ -84,7 +87,11 @@ class PlayerPlaybackControlsFragment : AbsPlayerControlsFragment() {
ThemeStore.accentColor(requireContext()) ThemeStore.accentColor(requireContext())
}.ripAlpha() }.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) TintHelper.setTintAuto(playPauseButton, colorFinal, true)
ViewUtil.setProgressDrawable(progressSlider, colorFinal, false) ViewUtil.setProgressDrawable(progressSlider, colorFinal, false)
@ -173,7 +180,10 @@ class PlayerPlaybackControlsFragment : AbsPlayerControlsFragment() {
override fun updateShuffleState() { override fun updateShuffleState() {
when (MusicPlayerRemote.shuffleMode) { 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) else -> shuffleButton.setColorFilter(lastDisabledPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
} }
} }
@ -201,11 +211,11 @@ class PlayerPlaybackControlsFragment : AbsPlayerControlsFragment() {
public override fun show() { public override fun show() {
playPauseButton!!.animate() playPauseButton!!.animate()
.scaleX(1f) .scaleX(1f)
.scaleY(1f) .scaleY(1f)
.rotation(360f) .rotation(360f)
.setInterpolator(DecelerateInterpolator()) .setInterpolator(DecelerateInterpolator())
.start() .start()
} }
public override fun hide() { public override fun hide() {
@ -223,8 +233,10 @@ class PlayerPlaybackControlsFragment : AbsPlayerControlsFragment() {
override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) { override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) {
if (fromUser) { if (fromUser) {
MusicPlayerRemote.seekTo(progress) MusicPlayerRemote.seekTo(progress)
onUpdateProgressViews(MusicPlayerRemote.songProgressMillis, onUpdateProgressViews(
MusicPlayerRemote.songDurationMillis) MusicPlayerRemote.songProgressMillis,
MusicPlayerRemote.songDurationMillis
)
} }
} }
}) })
@ -241,5 +253,4 @@ class PlayerPlaybackControlsFragment : AbsPlayerControlsFragment() {
songTotalTime.text = MusicUtil.getReadableDurationString(total.toLong()) songTotalTime.text = MusicUtil.getReadableDurationString(total.toLong())
songCurrentProgress.text = MusicUtil.getReadableDurationString(progress.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.MusicUtil
import code.name.monkey.retromusic.util.PreferenceUtil import code.name.monkey.retromusic.util.PreferenceUtil
import code.name.monkey.retromusic.util.ViewUtil import code.name.monkey.retromusic.util.ViewUtil
import kotlinx.android.synthetic.main.fragment_plain_controls_fragment.* import kotlinx.android.synthetic.main.fragment_plain_controls_fragment.nextButton
import kotlinx.android.synthetic.main.media_button.playPauseButton import kotlinx.android.synthetic.main.fragment_plain_controls_fragment.playPauseButton
import kotlinx.android.synthetic.main.media_button.repeatButton import kotlinx.android.synthetic.main.fragment_plain_controls_fragment.previousButton
import kotlinx.android.synthetic.main.media_button.shuffleButton 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). * @author Hemanth S (h4h13).
@ -41,7 +45,6 @@ class PlainPlaybackControlsFragment : AbsPlayerControlsFragment() {
private var lastDisabledPlaybackControlsColor: Int = 0 private var lastDisabledPlaybackControlsColor: Int = 0
private lateinit var progressViewUpdateHelper: MusicProgressViewUpdateHelper private lateinit var progressViewUpdateHelper: MusicProgressViewUpdateHelper
override fun onPlayStateChanged() { override fun onPlayStateChanged() {
updatePlayPauseDrawableState() updatePlayPauseDrawableState()
} }
@ -70,7 +73,6 @@ class PlainPlaybackControlsFragment : AbsPlayerControlsFragment() {
return inflater.inflate(R.layout.fragment_plain_controls_fragment, container, false) return inflater.inflate(R.layout.fragment_plain_controls_fragment, container, false)
} }
override fun onResume() { override fun onResume() {
super.onResume() super.onResume()
progressViewUpdateHelper.start() progressViewUpdateHelper.start()
@ -118,7 +120,6 @@ class PlainPlaybackControlsFragment : AbsPlayerControlsFragment() {
previousButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN) previousButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
} }
override fun setDark(color: Int) { override fun setDark(color: Int) {
val colorBg = ATHUtil.resolveColor(context!!, android.R.attr.colorBackground) val colorBg = ATHUtil.resolveColor(context!!, android.R.attr.colorBackground)
if (ColorUtil.isColorLight(colorBg)) { if (ColorUtil.isColorLight(colorBg)) {
@ -136,7 +137,11 @@ class PlainPlaybackControlsFragment : AbsPlayerControlsFragment() {
} }
volumeFragment?.setTintable(colorFinal) 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) TintHelper.setTintAuto(playPauseButton, colorFinal, true)
ViewUtil.setProgressDrawable(progressSlider, colorFinal.ripAlpha(), true) ViewUtil.setProgressDrawable(progressSlider, colorFinal.ripAlpha(), true)
@ -152,7 +157,10 @@ class PlainPlaybackControlsFragment : AbsPlayerControlsFragment() {
override fun updateShuffleState() { override fun updateShuffleState() {
when (MusicPlayerRemote.shuffleMode) { 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) else -> shuffleButton.setColorFilter(lastDisabledPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
} }
} }
@ -180,11 +188,11 @@ class PlainPlaybackControlsFragment : AbsPlayerControlsFragment() {
public override fun show() { public override fun show() {
playPauseButton!!.animate() playPauseButton!!.animate()
.scaleX(1f) .scaleX(1f)
.scaleY(1f) .scaleY(1f)
.rotation(360f) .rotation(360f)
.setInterpolator(DecelerateInterpolator()) .setInterpolator(DecelerateInterpolator())
.start() .start()
} }
public override fun hide() { public override fun hide() {
@ -202,8 +210,10 @@ class PlainPlaybackControlsFragment : AbsPlayerControlsFragment() {
override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) { override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) {
if (fromUser) { if (fromUser) {
MusicPlayerRemote.seekTo(progress) MusicPlayerRemote.seekTo(progress)
onUpdateProgressViews(MusicPlayerRemote.songProgressMillis, onUpdateProgressViews(
MusicPlayerRemote.songDurationMillis) MusicPlayerRemote.songProgressMillis,
MusicPlayerRemote.songDurationMillis
)
} }
} }
}) })
@ -219,16 +229,16 @@ class PlainPlaybackControlsFragment : AbsPlayerControlsFragment() {
pivotY = (height / 2).toFloat() pivotY = (height / 2).toFloat()
animate().setDuration(200) animate().setDuration(200)
.setInterpolator(DecelerateInterpolator()) .setInterpolator(DecelerateInterpolator())
.scaleX(1.1f) .scaleX(1.1f)
.scaleY(1.1f) .scaleY(1.1f)
.withEndAction { .withEndAction {
animate().setDuration(200) animate().setDuration(200)
.setInterpolator(AccelerateInterpolator()) .setInterpolator(AccelerateInterpolator())
.scaleX(1f) .scaleX(1f)
.scaleY(1f) .scaleY(1f)
.alpha(1f).start() .alpha(1f).start()
}.start() }.start()
} }
} }
@ -251,5 +261,4 @@ class PlainPlaybackControlsFragment : AbsPlayerControlsFragment() {
songTotalTime.text = MusicUtil.getReadableDurationString(total.toLong()) songTotalTime.text = MusicUtil.getReadableDurationString(total.toLong())
songCurrentProgress.text = MusicUtil.getReadableDurationString(progress.toLong()) songCurrentProgress.text = MusicUtil.getReadableDurationString(progress.toLong())
} }
} }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,8 +1,9 @@
<?xml version="1.0" encoding="utf-8"?> <?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" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="match_parent"
android:orientation="vertical" android:orientation="vertical"
tools:ignore="ContentDescription"> tools:ignore="ContentDescription">
@ -11,17 +12,23 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center" android:layout_gravity="center"
android:layout_marginTop="8dp"
android:gravity="center" android:gravity="center"
android:padding="16dp" android:padding="8dp"
android:textAppearance="@style/TextViewHeadline6" 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 <androidx.appcompat.widget.AppCompatImageView
android:id="@+id/image" android:id="@+id/image"
android:layout_width="match_parent" android:layout_width="0dp"
android:layout_height="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" /> 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="pref_header_blacklist">Blacklist</string>
<string name="no_playing_queue">No songs playing</string> <string name="no_playing_queue">No songs playing</string>
<string name="nothing_to_see">Nothing to see</string> <string name="nothing_to_see">Nothing to see</string>
</resources> </resources>

View File

@ -17,7 +17,6 @@ import android.widget.RadioButton;
import android.widget.SeekBar; import android.widget.SeekBar;
import android.widget.Switch; import android.widget.Switch;
import android.widget.TextView; import android.widget.TextView;
import androidx.annotation.CheckResult; import androidx.annotation.CheckResult;
import androidx.annotation.ColorInt; import androidx.annotation.ColorInt;
import androidx.annotation.DrawableRes; import androidx.annotation.DrawableRes;
@ -27,386 +26,15 @@ import androidx.appcompat.widget.AppCompatEditText;
import androidx.appcompat.widget.SwitchCompat; import androidx.appcompat.widget.SwitchCompat;
import androidx.core.content.ContextCompat; import androidx.core.content.ContextCompat;
import androidx.core.graphics.drawable.DrawableCompat; 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 code.name.monkey.appthemehelper.R;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import java.lang.reflect.Field;
/** /**
* @author afollestad, plusCubed * @author afollestad, plusCubed
*/ */
public final class TintHelper { 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") @SuppressWarnings("JavaReflectionMemberAccess")
public static void colorHandles(@NonNull TextView view, int color) { public static void colorHandles(@NonNull TextView view, int color) {
try { try {
@ -448,4 +76,411 @@ public final class TintHelper {
e.printStackTrace(); 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));
}
} }