Improving material design

This commit is contained in:
h4h13 2020-05-06 03:23:31 +05:30
parent c8837f13ef
commit 83cb1353d8
9 changed files with 260 additions and 82 deletions

View file

@ -109,6 +109,7 @@ class AlbumCoverPagerAdapter(
NowPlayingScreen.FIT, NowPlayingScreen.FIT,
NowPlayingScreen.TINY, NowPlayingScreen.TINY,
NowPlayingScreen.CLASSIC, NowPlayingScreen.CLASSIC,
NowPlayingScreen.MATERIAL,
NowPlayingScreen.FULL -> R.layout.fragment_album_full_cover NowPlayingScreen.FULL -> R.layout.fragment_album_full_cover
else -> { else -> {
if (PreferenceUtil.getInstance(requireContext()) if (PreferenceUtil.getInstance(requireContext())

View file

@ -62,11 +62,9 @@ abstract class AbsPlayerControlsFragment : AbsMusicServiceFragment(),
private fun hideVolumeIfAvailable() { private fun hideVolumeIfAvailable() {
if (PreferenceUtil.getInstance(requireContext()).volumeToggle) { if (PreferenceUtil.getInstance(requireContext()).volumeToggle) {
childFragmentManager.beginTransaction() childFragmentManager.beginTransaction().replace(R.id.volumeFragmentContainer, VolumeFragment()).commit()
.replace(R.id.volumeFragmentContainer, VolumeFragment()).commit()
childFragmentManager.executePendingTransactions() childFragmentManager.executePendingTransactions()
volumeFragment = volumeFragment = childFragmentManager.findFragmentById(R.id.volumeFragmentContainer) as VolumeFragment?
childFragmentManager.findFragmentById(R.id.volumeFragmentContainer) as VolumeFragment?
} }
} }

View file

@ -117,6 +117,11 @@ class ClassicPlayerFragment : AbsPlayerFragment(), View.OnLayoutChangeListener,
} }
} }
override fun onDestroyView() {
super.onDestroyView()
getQueuePanel().removeBottomSheetCallback(bottomSheetCallbackList)
}
private fun updateSong() { private fun updateSong() {
val song = MusicPlayerRemote.currentSong val song = MusicPlayerRemote.currentSong
title.text = song.title title.text = song.title

View file

@ -6,7 +6,6 @@ import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import code.name.monkey.appthemehelper.util.ATHUtil import code.name.monkey.appthemehelper.util.ATHUtil
import code.name.monkey.appthemehelper.util.ColorUtil
import code.name.monkey.appthemehelper.util.MaterialValueHelper import code.name.monkey.appthemehelper.util.MaterialValueHelper
import code.name.monkey.retromusic.R import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.extensions.hide import code.name.monkey.retromusic.extensions.hide
@ -99,24 +98,22 @@ class MaterialControlsFragment : AbsPlayerControlsFragment() {
} }
override fun setDark(color: Int) { override fun setDark(color: Int) {
val colorBg = ATHUtil.resolveColor(requireContext(), R.attr.colorSurface) if (ATHUtil.isWindowBackgroundDark(requireContext())) {
if (ColorUtil.isColorLight(colorBg)) {
lastPlaybackControlsColor =
MaterialValueHelper.getSecondaryTextColor(requireContext(), true)
lastDisabledPlaybackControlsColor =
MaterialValueHelper.getSecondaryDisabledTextColor(requireContext(), true)
} else {
lastPlaybackControlsColor = lastPlaybackControlsColor =
MaterialValueHelper.getPrimaryTextColor(requireContext(), false) MaterialValueHelper.getPrimaryTextColor(requireContext(), false)
lastDisabledPlaybackControlsColor = lastDisabledPlaybackControlsColor =
MaterialValueHelper.getPrimaryDisabledTextColor(requireContext(), false) MaterialValueHelper.getPrimaryDisabledTextColor(requireContext(), false)
}else{
lastPlaybackControlsColor =
MaterialValueHelper.getSecondaryTextColor(requireContext(), true)
lastDisabledPlaybackControlsColor =
MaterialValueHelper.getSecondaryDisabledTextColor(requireContext(), true)
} }
updateRepeatState() updateRepeatState()
updateShuffleState() updateShuffleState()
val colorFinal = if (PreferenceUtil.getInstance(requireContext()).adaptiveColor) { val colorFinal = if (PreferenceUtil.getInstance(requireContext()).adaptiveColor) {
color lastPlaybackControlsColor
} else { } else {
textColorSecondary(requireContext()) textColorSecondary(requireContext())
}.ripAlpha() }.ripAlpha()
@ -126,12 +123,14 @@ class MaterialControlsFragment : AbsPlayerControlsFragment() {
volumeFragment?.setTintable(colorFinal) volumeFragment?.setTintable(colorFinal)
updatePlayPauseColor(colorFinal) updateRepeatState()
updatePrevNextColor(colorFinal) updateShuffleState()
updatePlayPauseColor()
updatePrevNextColor()
} }
private fun updatePlayPauseColor(color: Int) { private fun updatePlayPauseColor() {
playPauseButton.setColorFilter(color, PorterDuff.Mode.SRC_IN) playPauseButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
} }
private fun setUpPlayPauseFab() { private fun setUpPlayPauseFab() {
@ -155,14 +154,14 @@ class MaterialControlsFragment : AbsPlayerControlsFragment() {
} }
private fun setUpPrevNext() { private fun setUpPrevNext() {
updatePrevNextColor(textColorSecondary(requireContext())) updatePrevNextColor()
nextButton.setOnClickListener { MusicPlayerRemote.playNextSong() } nextButton.setOnClickListener { MusicPlayerRemote.playNextSong() }
previousButton.setOnClickListener { MusicPlayerRemote.back() } previousButton.setOnClickListener { MusicPlayerRemote.back() }
} }
private fun updatePrevNextColor(color: Int) { private fun updatePrevNextColor() {
nextButton.setColorFilter(color, PorterDuff.Mode.SRC_IN) nextButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
previousButton.setColorFilter(color, PorterDuff.Mode.SRC_IN) previousButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
} }
private fun setUpShuffleButton() { private fun setUpShuffleButton() {

View file

@ -4,22 +4,57 @@ import android.os.Bundle
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.FrameLayout
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.Toolbar import androidx.appcompat.widget.Toolbar
import androidx.core.view.ViewCompat
import androidx.recyclerview.widget.LinearLayoutManager
import code.name.monkey.appthemehelper.util.ATHUtil import code.name.monkey.appthemehelper.util.ATHUtil
import code.name.monkey.appthemehelper.util.ColorUtil
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
import code.name.monkey.retromusic.CustomBottomSheetBehavior
import code.name.monkey.retromusic.R import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.activities.base.AbsSlidingMusicPanelActivity
import code.name.monkey.retromusic.adapter.song.PlayingQueueAdapter
import code.name.monkey.retromusic.fragments.base.AbsPlayerFragment import code.name.monkey.retromusic.fragments.base.AbsPlayerFragment
import code.name.monkey.retromusic.fragments.player.PlayerAlbumCoverFragment import code.name.monkey.retromusic.fragments.player.PlayerAlbumCoverFragment
import code.name.monkey.retromusic.fragments.player.normal.PlayerFragment import code.name.monkey.retromusic.fragments.player.normal.PlayerFragment
import code.name.monkey.retromusic.helper.MusicPlayerRemote import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.model.Song import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.util.color.MediaNotificationProcessor import code.name.monkey.retromusic.util.color.MediaNotificationProcessor
import com.google.android.material.bottomsheet.BottomSheetBehavior
import kotlinx.android.synthetic.main.fragment_material.* import kotlinx.android.synthetic.main.fragment_material.*
import kotlinx.android.synthetic.main.status_bar.*
/** /**
* @author Hemanth S (h4h13). * @author Hemanth S (h4h13).
*/ */
class MaterialFragment : AbsPlayerFragment() { class MaterialFragment : AbsPlayerFragment(), View.OnLayoutChangeListener {
private lateinit var queueAdapter: PlayingQueueAdapter
private val bottomSheetCallbackList = object : BottomSheetBehavior.BottomSheetCallback() {
override fun onSlide(bottomSheet: View, slideOffset: Float) {
(requireActivity() as AbsSlidingMusicPanelActivity).getBottomSheetBehavior()
.setAllowDragging(false)
sheetContent.setPadding(
sheetContent.paddingLeft,
(slideOffset * status_bar.height).toInt(),
sheetContent.paddingRight,
sheetContent.paddingBottom
)
playerControlsContainer.layoutParams.height = playerContainer.width
}
override fun onStateChanged(bottomSheet: View, newState: Int) {
val activity = requireActivity() as AbsSlidingMusicPanelActivity
if (newState == BottomSheetBehavior.STATE_EXPANDED || newState == BottomSheetBehavior.STATE_DRAGGING) {
activity.getBottomSheetBehavior().setAllowDragging(false)
} else {
activity.getBottomSheetBehavior().setAllowDragging(true)
}
}
}
override fun playerToolbar(): Toolbar { override fun playerToolbar(): Toolbar {
return playerToolbar return playerToolbar
@ -50,6 +85,9 @@ class MaterialFragment : AbsPlayerFragment() {
} }
override fun onColorChanged(color: MediaNotificationProcessor) { override fun onColorChanged(color: MediaNotificationProcessor) {
val darkColor = ColorUtil.darkenColorTheme(color.backgroundColor)
playerContainer?.setBackgroundColor(ColorUtil.darkenColorTheme(color.backgroundColor))
upComing?.setBackgroundColor(ColorUtil.darkenColorTheme(darkColor))
playbackControlsFragment.setDark(color.backgroundColor) playbackControlsFragment.setDark(color.backgroundColor)
lastColor = color.backgroundColor lastColor = color.backgroundColor
callbacks?.onPaletteColorChanged() callbacks?.onPaletteColorChanged()
@ -83,6 +121,40 @@ class MaterialFragment : AbsPlayerFragment() {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
setUpSubFragments() setUpSubFragments()
setUpPlayerToolbar() setUpPlayerToolbar()
setupPanel()
setUpQueue()
getQueuePanel().addBottomSheetCallback(bottomSheetCallbackList)
playerQueueSheet.setOnTouchListener { _, _ ->
(requireActivity() as AbsSlidingMusicPanelActivity).getBottomSheetBehavior()
.setAllowDragging(false)
getQueuePanel().setAllowDragging(true)
return@setOnTouchListener false
}
}
private fun setUpQueue() {
queueAdapter = PlayingQueueAdapter(
requireActivity() as AppCompatActivity, mutableListOf(),
MusicPlayerRemote.position,
R.layout.item_queue
)
recyclerView.apply {
adapter = queueAdapter
layoutManager = LinearLayoutManager(requireContext())
}
}
private fun setupPanel() {
if (!ViewCompat.isLaidOut(playerContainer) || playerContainer.isLayoutRequested) {
playerContainer.addOnLayoutChangeListener(this)
return
}
val height = playerContainer?.height ?: 0
val width = playerContainer?.width ?: 0
val finalHeight = height - (playerControlsContainer.height - width)
val panel = getQueuePanel()
panel.peekHeight = finalHeight
} }
private fun setUpSubFragments() { private fun setUpSubFragments() {
@ -108,6 +180,7 @@ class MaterialFragment : AbsPlayerFragment() {
override fun onServiceConnected() { override fun onServiceConnected() {
updateIsFavorite() updateIsFavorite()
queueAdapter.swapDataSet(MusicPlayerRemote.playingQueue)
} }
override fun onPlayingMetaChanged() { override fun onPlayingMetaChanged() {
@ -120,4 +193,32 @@ class MaterialFragment : AbsPlayerFragment() {
return PlayerFragment() return PlayerFragment()
} }
} }
private fun getQueuePanel(): CustomBottomSheetBehavior<FrameLayout> {
return CustomBottomSheetBehavior.from(playerQueueSheet) as CustomBottomSheetBehavior<FrameLayout>
}
override fun onDestroyView() {
super.onDestroyView()
getQueuePanel().removeBottomSheetCallback(bottomSheetCallbackList)
}
override fun onLayoutChange(
v: View?,
left: Int,
top: Int,
right: Int,
bottom: Int,
oldLeft: Int,
oldTop: Int,
oldRight: Int,
oldBottom: Int
) {
val height = playerContainer?.height ?: 0
val width = playerContainer?.width ?: 0
val finalHeight = height - width
playerControlsContainer.layoutParams.height = height - width
val panel = getQueuePanel()
panel.peekHeight = finalHeight
}
} }

View file

@ -5,7 +5,7 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">
<LinearLayout <FrameLayout
android:id="@+id/playerContainer" android:id="@+id/playerContainer"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
@ -43,7 +43,7 @@
app:navigationIcon="@drawable/ic_keyboard_arrow_down_black_24dp" /> app:navigationIcon="@drawable/ic_keyboard_arrow_down_black_24dp" />
</LinearLayout> </LinearLayout>
</code.name.monkey.retromusic.views.WidthFitSquareLayout> </code.name.monkey.retromusic.views.WidthFitSquareLayout>
</LinearLayout> </FrameLayout>
<com.google.android.material.card.MaterialCardView <com.google.android.material.card.MaterialCardView
android:id="@+id/playerQueueSheet" android:id="@+id/playerQueueSheet"
@ -51,7 +51,6 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:gravity="bottom" android:gravity="bottom"
android:orientation="vertical" android:orientation="vertical"
android:tag="nested_bottom_sheet"
app:behavior_hideable="false" app:behavior_hideable="false"
app:cardCornerRadius="0dp" app:cardCornerRadius="0dp"
app:layout_behavior="code.name.monkey.retromusic.CustomBottomSheetBehavior"> app:layout_behavior="code.name.monkey.retromusic.CustomBottomSheetBehavior">
@ -92,7 +91,6 @@
android:background="?attr/colorSurface" android:background="?attr/colorSurface"
tools:listitem="@layout/item_list" /> tools:listitem="@layout/item_list" />
</LinearLayout> </LinearLayout>
</LinearLayout> </LinearLayout>
</com.google.android.material.card.MaterialCardView> </com.google.android.material.card.MaterialCardView>
</androidx.coordinatorlayout.widget.CoordinatorLayout> </androidx.coordinatorlayout.widget.CoordinatorLayout>

View file

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" <androidx.coordinatorlayout.widget.CoordinatorLayout 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:layout_width="match_parent" android:layout_width="match_parent"
@ -7,25 +7,14 @@
android:clickable="true" android:clickable="true"
android:focusable="true"> android:focusable="true">
<View
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?attr/colorSurface" />
<include layout="@layout/shadow_statusbar_toolbar" /> <include layout="@layout/shadow_statusbar_toolbar" />
<LinearLayout <LinearLayout
android:id="@+id/playerContainer"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:orientation="vertical"> android:orientation="vertical">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<include layout="@layout/status_bar" />
</FrameLayout>
<code.name.monkey.retromusic.views.WidthFitSquareLayout <code.name.monkey.retromusic.views.WidthFitSquareLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content"> android:layout_height="wrap_content">
@ -35,20 +24,13 @@
android:name="code.name.monkey.retromusic.fragments.player.PlayerAlbumCoverFragment" android:name="code.name.monkey.retromusic.fragments.player.PlayerAlbumCoverFragment"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
tools:layout="@layout/fragment_album_cover" /> tools:layout="@layout/fragment_album_full_cover" />
</code.name.monkey.retromusic.views.WidthFitSquareLayout>
<FrameLayout <FrameLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="wrap_content">
android:layout_weight="1">
<fragment <include layout="@layout/status_bar" />
android:id="@+id/playbackControlsFragment"
android:name="code.name.monkey.retromusic.fragments.player.material.MaterialControlsFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:layout="@layout/fragment_material_playback_controls" />
</FrameLayout> </FrameLayout>
<FrameLayout <FrameLayout
@ -63,5 +45,80 @@
android:navigationIcon="@drawable/ic_keyboard_arrow_down_black_24dp" android:navigationIcon="@drawable/ic_keyboard_arrow_down_black_24dp"
app:navigationIcon="@drawable/ic_keyboard_arrow_down_black_24dp" /> app:navigationIcon="@drawable/ic_keyboard_arrow_down_black_24dp" />
</FrameLayout> </FrameLayout>
</code.name.monkey.retromusic.views.WidthFitSquareLayout>
</LinearLayout> </LinearLayout>
</FrameLayout>
<FrameLayout
android:id="@+id/playerQueueSheet"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="bottom"
app:behavior_hideable="false"
app:layout_behavior="code.name.monkey.retromusic.CustomBottomSheetBehavior">
<LinearLayout
android:id="@+id/sheetContent"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorSurface"
android:orientation="vertical">
<LinearLayout
android:id="@+id/playerControlsContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<fragment
android:id="@+id/playbackControlsFragment"
android:name="code.name.monkey.retromusic.fragments.player.material.MaterialControlsFragment"
android:layout_width="match_parent"
android:layout_weight="1"
android:layout_height="match_parent"
tools:layout="@layout/fragment_material_playback_controls" />
<LinearLayout
android:layout_weight="0"
android:id="@+id/upComing"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="end"
android:orientation="horizontal">
<androidx.appcompat.widget.AppCompatImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="16dp"
app:srcCompat="@drawable/ic_shuffle_sharp_white_24dp" />
</LinearLayout>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<com.google.android.material.textview.MaterialTextView
android:id="@+id/player_queue_sub_header"
android:layout_width="match_parent"
android:layout_height="?attr/listPreferredItemHeightSmall"
android:background="?attr/colorSurface"
android:gravity="center_vertical"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:text="@string/up_next"
android:textAppearance="@style/TextAppearance.AppCompat.Body2"
android:textColor="?android:attr/textColorSecondary" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?attr/colorSurface"
tools:listitem="@layout/item_list" />
</LinearLayout>
</LinearLayout>
</FrameLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View file

@ -30,9 +30,10 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="8dp" android:layout_marginTop="8dp"
app:labelBehavior="gone" app:labelBehavior="gone"
app:layout_constraintBottom_toTopOf="@id/playPauseButton"
app:layout_constraintEnd_toStartOf="@id/songTotalTime" app:layout_constraintEnd_toStartOf="@id/songTotalTime"
app:layout_constraintStart_toEndOf="@id/songCurrentProgress" app:layout_constraintStart_toEndOf="@id/songCurrentProgress"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toBottomOf="@id/songInfo"
app:thumbRadius="@dimen/slider_thumb_radius" app:thumbRadius="@dimen/slider_thumb_radius"
app:trackHeight="@dimen/slider_track_height" app:trackHeight="@dimen/slider_track_height"
tools:ignore="RtlHardcoded,UnusedAttribute" tools:ignore="RtlHardcoded,UnusedAttribute"
@ -61,7 +62,7 @@
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/progressSlider"> app:layout_constraintTop_toTopOf="parent">
<com.google.android.material.textview.MaterialTextView <com.google.android.material.textview.MaterialTextView
android:id="@+id/title" android:id="@+id/title"
@ -114,7 +115,10 @@
android:paddingEnd="16dp" android:paddingEnd="16dp"
android:textColor="?android:attr/textColorSecondary" android:textColor="?android:attr/textColorSecondary"
android:textSize="12sp" android:textSize="12sp"
app:layout_constraintBottom_toTopOf="@+id/playPauseButton" app:layout_constraintBottom_toTopOf="@+id/progressSlider"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/text" app:layout_constraintTop_toBottomOf="@+id/text"
tools:text="@tools:sample/lorem/random" /> tools:text="@tools:sample/lorem/random" />
@ -155,11 +159,11 @@
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"
app:layout_constraintBottom_toTopOf="@+id/volumeFragmentContainer" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/nextButton" app:layout_constraintEnd_toStartOf="@+id/nextButton"
app:layout_constraintHorizontal_bias="0.5" app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@+id/previousButton" app:layout_constraintStart_toEndOf="@+id/previousButton"
app:layout_constraintTop_toBottomOf="@+id/songInfo" app:layout_constraintTop_toBottomOf="@+id/progressSlider"
app:srcCompat="@drawable/ic_pause_sharp_white_64dp" app:srcCompat="@drawable/ic_pause_sharp_white_64dp"
tools:tint="@color/md_black_1000" /> tools:tint="@color/md_black_1000" />
@ -194,15 +198,12 @@
tools:ignore="MissingPrefix" tools:ignore="MissingPrefix"
tools:tint="@color/md_black_1000" /> tools:tint="@color/md_black_1000" />
<FrameLayout <FrameLayout
android:id="@+id/volumeFragmentContainer" android:id="@+id/volumeFragmentContainer"
android:layout_width="match_parent" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="0dp"
android:layout_weight="0" android:visibility="gone"
android:paddingStart="8dp"
android:paddingEnd="8dp"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
tools:backgroundTint="@color/md_red_400" app:layout_constraintStart_toStartOf="parent" />
tools:layout_height="52dp" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -33,13 +33,19 @@ object ColorUtil {
return shiftColor(color, 0.9f) return shiftColor(color, 0.9f)
} }
@ColorInt
fun darkenColorTheme(@ColorInt color: Int): Int {
return shiftColor(color, 0.8f)
}
@ColorInt @ColorInt
fun lightenColor(@ColorInt color: Int): Int { fun lightenColor(@ColorInt color: Int): Int {
return shiftColor(color, 1.1f) return shiftColor(color, 1.1f)
} }
fun isColorLight(@ColorInt color: Int): Boolean { fun isColorLight(@ColorInt color: Int): Boolean {
val darkness = 1 - (0.299 * Color.red(color) + 0.587 * Color.green(color) + 0.114 * Color.blue(color)) / 255 val darkness =
1 - (0.299 * Color.red(color) + 0.587 * Color.green(color) + 0.114 * Color.blue(color)) / 255
return darkness < 0.4 return darkness < 0.4
} }
@ -94,8 +100,14 @@ object ColorUtil {
} }
fun isColorSaturated(@ColorInt color: Int): Boolean { fun isColorSaturated(@ColorInt color: Int): Boolean {
val max = Math.max(0.299 * Color.red(color), Math.max(0.587 * Color.green(color), 0.114 * Color.blue(color))) val max = Math.max(
val min = Math.min(0.299 * Color.red(color), Math.min(0.587 * Color.green(color), 0.114 * Color.blue(color))) 0.299 * Color.red(color),
Math.max(0.587 * Color.green(color), 0.114 * Color.blue(color))
)
val min = Math.min(
0.299 * Color.red(color),
Math.min(0.587 * Color.green(color), 0.114 * Color.blue(color))
)
val diff = Math.abs(max - min) val diff = Math.abs(max - min)
return diff > 20 return diff > 20
} }
@ -122,12 +134,17 @@ object ColorUtil {
} }
@ColorInt @ColorInt
fun getReadableText(@ColorInt textColor: Int, @ColorInt backgroundColor: Int, difference: Int): Int { fun getReadableText(
@ColorInt textColor: Int,
@ColorInt backgroundColor: Int,
difference: Int
): Int {
var textColorFinal = textColor var textColorFinal = textColor
val isLight = isColorLight(backgroundColor) val isLight = isColorLight(backgroundColor)
var i = 0 var i = 0
while (getDifference(textColorFinal, backgroundColor) < difference && i < 100) { while (getDifference(textColorFinal, backgroundColor) < difference && i < 100) {
textColorFinal = getMixedColor(textColorFinal, if (isLight) Color.BLACK else Color.WHITE) textColorFinal =
getMixedColor(textColorFinal, if (isLight) Color.BLACK else Color.WHITE)
i++ i++
} }
@ -137,7 +154,8 @@ object ColorUtil {
@ColorInt @ColorInt
fun getContrastColor(@ColorInt color: Int): Int { fun getContrastColor(@ColorInt color: Int): Int {
// Counting the perceptive luminance - human eye favors green color... // Counting the perceptive luminance - human eye favors green color...
val a = 1 - (0.299 * Color.red(color) + 0.587 * Color.green(color) + 0.114 * Color.blue(color)) / 255 val a =
1 - (0.299 * Color.red(color) + 0.587 * Color.green(color) + 0.114 * Color.blue(color)) / 255
return if (a < 0.5) Color.BLACK else Color.WHITE return if (a < 0.5) Color.BLACK else Color.WHITE
} }
} }