Fix queue changing

main
h4h13 2020-05-04 00:54:11 +05:30
parent 69c76556a2
commit 891f1bce34
34 changed files with 1007 additions and 132 deletions

View File

@ -197,4 +197,6 @@ dependencies {
kapt "androidx.lifecycle:lifecycle-compiler:$lifecycle_version" kapt "androidx.lifecycle:lifecycle-compiler:$lifecycle_version"
implementation 'com.google.android.play:core:1.7.2' implementation 'com.google.android.play:core:1.7.2'
implementation 'me.jorgecastillo:androidcolorx:0.2.0'
debugImplementation 'com.amitshekhar.android:debug-db:1.0.4'
} }

View File

@ -56,7 +56,7 @@ public class LicenseActivity extends AbsBaseActivity {
WebView webView = findViewById(R.id.license); WebView webView = findViewById(R.id.license);
try { try {
StringBuilder buf = new StringBuilder(); StringBuilder buf = new StringBuilder();
InputStream json = getAssets().open("index.html"); InputStream json = getAssets().open("oldindex.html");
BufferedReader in = new BufferedReader(new InputStreamReader(json, StandardCharsets.UTF_8)); BufferedReader in = new BufferedReader(new InputStreamReader(json, StandardCharsets.UTF_8));
String str; String str;
while ((str = in.readLine()) != null) { while ((str = in.readLine()) != null) {

View File

@ -121,8 +121,7 @@ public class MainActivity extends AbsSlidingMusicPanelActivity
} }
}; };
private final IntentFilter mIntentFilter = new IntentFilter(Intent.ACTION_SCREEN_OFF); private final IntentFilter mIntentFilter = new IntentFilter(Intent.ACTION_SCREEN_OFF);
@Nullable private MainActivityFragmentCallbacks currentFragment;
MainActivityFragmentCallbacks currentFragment;
private boolean blockRequestPermissions = false; private boolean blockRequestPermissions = false;
private MaterialCab cab; private MaterialCab cab;
private AppBarLayout mAppBarLayout; private AppBarLayout mAppBarLayout;
@ -231,12 +230,10 @@ public class MainActivity extends AbsSlidingMusicPanelActivity
registerReceiver(mBroadcastReceiver, mIntentFilter); registerReceiver(mBroadcastReceiver, mIntentFilter);
PreferenceUtil.getInstance(this).registerOnSharedPreferenceChangedListener(this); PreferenceUtil.getInstance(this).registerOnSharedPreferenceChangedListener(this);
if (getIntent().hasExtra(EXPAND_PANEL) && PreferenceUtil.getInstance(this).isExpandPanel()) { if (getIntent().hasExtra(EXPAND_PANEL) && getIntent().getBooleanExtra(EXPAND_PANEL, false) && PreferenceUtil.getInstance(this).isExpandPanel()) {
if (getIntent().getBooleanExtra(EXPAND_PANEL, false)) {
expandPanel(); expandPanel();
getIntent().putExtra(EXPAND_PANEL, false); getIntent().putExtra(EXPAND_PANEL, false);
} }
}
appUpdateManager.getAppUpdateInfo() appUpdateManager.getAppUpdateInfo()
.addOnSuccessListener(appUpdateInfo -> { .addOnSuccessListener(appUpdateInfo -> {
if (appUpdateInfo.installStatus() == InstallStatus.DOWNLOADED) { if (appUpdateInfo.installStatus() == InstallStatus.DOWNLOADED) {

View File

@ -32,12 +32,6 @@ import code.name.monkey.retromusic.util.PreferenceUtil;
public class WhatsNewActivity extends AbsBaseActivity { public class WhatsNewActivity extends AbsBaseActivity {
AppBarLayout appBarLayout;
Toolbar toolbar;
WebView webView;
private static String colorToCSS(int color) { private static String colorToCSS(int color) {
return String.format(Locale.getDefault(), "rgba(%d, %d, %d, %d)", Color.red(color), Color.green(color), return String.format(Locale.getDefault(), "rgba(%d, %d, %d, %d)", Color.red(color), Color.green(color),
Color.blue(color), Color.alpha(color)); // on API 29, WebView doesn't load with hex colors Color.blue(color), Color.alpha(color)); // on API 29, WebView doesn't load with hex colors
@ -62,9 +56,9 @@ public class WhatsNewActivity extends AbsBaseActivity {
setNavigationbarColorAuto(); setNavigationbarColorAuto();
setTaskDescriptionColorAuto(); setTaskDescriptionColorAuto();
webView = findViewById(R.id.webView); WebView webView = findViewById(R.id.webView);
toolbar = findViewById(R.id.toolbar); Toolbar toolbar = findViewById(R.id.toolbar);
appBarLayout = findViewById(R.id.appBarLayout); AppBarLayout appBarLayout = findViewById(R.id.appBarLayout);
toolbar.setBackgroundColor(ATHUtil.INSTANCE.resolveColor(this, R.attr.colorSurface)); toolbar.setBackgroundColor(ATHUtil.INSTANCE.resolveColor(this, R.attr.colorSurface));
//setSupportActionBar(toolbar); //setSupportActionBar(toolbar);

View File

@ -18,6 +18,7 @@ import code.name.monkey.retromusic.fragments.MiniPlayerFragment
import code.name.monkey.retromusic.fragments.NowPlayingScreen import code.name.monkey.retromusic.fragments.NowPlayingScreen
import code.name.monkey.retromusic.fragments.NowPlayingScreen.* import code.name.monkey.retromusic.fragments.NowPlayingScreen.*
import code.name.monkey.retromusic.fragments.base.AbsPlayerFragment import code.name.monkey.retromusic.fragments.base.AbsPlayerFragment
import code.name.monkey.retromusic.fragments.player.TestPlayerFragment
import code.name.monkey.retromusic.fragments.player.adaptive.AdaptiveFragment import code.name.monkey.retromusic.fragments.player.adaptive.AdaptiveFragment
import code.name.monkey.retromusic.fragments.player.blur.BlurPlayerFragment import code.name.monkey.retromusic.fragments.player.blur.BlurPlayerFragment
import code.name.monkey.retromusic.fragments.player.card.CardFragment import code.name.monkey.retromusic.fragments.player.card.CardFragment
@ -241,6 +242,7 @@ abstract class AbsSlidingMusicPanelActivity : AbsMusicServiceActivity(),
TINY -> TinyPlayerFragment() TINY -> TinyPlayerFragment()
PEAK -> PeakPlayerFragment() PEAK -> PeakPlayerFragment()
CIRCLE -> CirclePlayerFragment() CIRCLE -> CirclePlayerFragment()
EXAMPLE -> TestPlayerFragment()
else -> PlayerFragment() else -> PlayerFragment()
} // must implement AbsPlayerFragment } // must implement AbsPlayerFragment
supportFragmentManager.beginTransaction().replace(R.id.playerFragmentContainer, fragment) supportFragmentManager.beginTransaction().replace(R.id.playerFragmentContainer, fragment)

View File

@ -122,12 +122,9 @@ public class CategoryInfoAdapter extends RecyclerView.Adapter<CategoryInfoAdapte
} }
static class ViewHolder extends RecyclerView.ViewHolder { static class ViewHolder extends RecyclerView.ViewHolder {
private MaterialCheckBox checkBox;
MaterialCheckBox checkBox; private View dragView;
private TextView title;
View dragView;
TextView title;
ViewHolder(View view) { ViewHolder(View view) {
super(view); super(view);

View File

@ -17,7 +17,7 @@ import code.name.monkey.retromusic.R;
import code.name.monkey.retromusic.interfaces.CabHolder; import code.name.monkey.retromusic.interfaces.CabHolder;
public abstract class AbsMultiSelectAdapter<VH extends RecyclerView.ViewHolder, I> extends RecyclerView.Adapter<VH> public abstract class AbsMultiSelectAdapter<V extends RecyclerView.ViewHolder, I> extends RecyclerView.Adapter<V>
implements MaterialCab.Callback { implements MaterialCab.Callback {
@Nullable @Nullable

View File

@ -0,0 +1,73 @@
package code.name.monkey.retromusic.extensions
import androidx.annotation.ColorInt
import androidx.core.graphics.ColorUtils
import androidx.palette.graphics.Palette
fun getSuitableColorFor(palette: Palette, i: Int, i2: Int): Int {
val dominantSwatch = palette.dominantSwatch
if (dominantSwatch != null) {
if (hasEnoughContrast(i, dominantSwatch.rgb)) {
return dominantSwatch.rgb
}
}
val vibrantSwatch = palette.vibrantSwatch
if (vibrantSwatch != null) {
if (hasEnoughContrast(i, vibrantSwatch.rgb)) {
return vibrantSwatch.rgb
}
}
val darkVibrantSwatch = palette.darkVibrantSwatch
if (darkVibrantSwatch != null) {
if (hasEnoughContrast(i, darkVibrantSwatch.rgb)) {
return darkVibrantSwatch.rgb
}
}
val lightVibrantSwatch = palette.lightVibrantSwatch
if (lightVibrantSwatch != null) {
if (hasEnoughContrast(i, lightVibrantSwatch.rgb)) {
return lightVibrantSwatch.rgb
}
}
val darkMutedSwatch = palette.darkMutedSwatch
if (darkMutedSwatch != null) {
if (hasEnoughContrast(i, darkMutedSwatch.rgb)) {
return darkMutedSwatch.rgb
}
}
val lightMutedSwatch = palette.lightMutedSwatch
if (lightMutedSwatch != null) {
if (hasEnoughContrast(i, lightMutedSwatch.rgb)) {
return lightMutedSwatch.rgb
}
}
val mutedSwatch = palette.mutedSwatch
if (mutedSwatch != null) {
if (hasEnoughContrast(i, mutedSwatch.rgb)) {
return mutedSwatch.rgb
}
}
return i2
}
fun hasEnoughContrast(i: Int, i2: Int): Boolean {
return ColorUtils.calculateContrast(i2, i) >= 2.toDouble()
}
fun hasEnoughLuminance(i: Int): Boolean {
return ColorUtils.calculateLuminance(i) >= 0.4f.toDouble()
}
fun isBlack(fArr: FloatArray): Boolean {
return fArr[2] <= 0.035f
}
fun isNearRedLine(fArr: FloatArray): Boolean {
val f = fArr[0]
return f >= 10.0f && f <= 37.0f && fArr[1] <= 0.82f
}
fun isDark(@ColorInt i: Int): Boolean {
return ColorUtils.calculateLuminance(i) < 0.5
}

View File

@ -26,4 +26,5 @@ enum class NowPlayingScreen constructor(
PLAIN(R.string.plain, R.drawable.np_plain, 3), PLAIN(R.string.plain, R.drawable.np_plain, 3),
SIMPLE(R.string.simple, R.drawable.np_simple, 8), SIMPLE(R.string.simple, R.drawable.np_simple, 8),
TINY(R.string.tiny, R.drawable.np_tiny, 7), TINY(R.string.tiny, R.drawable.np_tiny, 7),
EXAMPLE(R.string.tiny, R.drawable.np_tiny, 16),
} }

View File

@ -92,7 +92,8 @@ public class FoldersFragment extends AbsMainActivityFragment implements
private SongFileAdapter adapter; private SongFileAdapter adapter;
private BreadCrumbLayout breadCrumbs; private BreadCrumbLayout breadCrumbs;
private MaterialCab cab; private MaterialCab cab;
private View coordinatorLayout, empty; private View coordinatorLayout;
private View empty;
private TextView emojiText; private TextView emojiText;
private Comparator<File> fileComparator = (lhs, rhs) -> { private Comparator<File> fileComparator = (lhs, rhs) -> {
if (lhs.isDirectory() && !rhs.isDirectory()) { if (lhs.isDirectory() && !rhs.isDirectory()) {

View File

@ -0,0 +1,386 @@
package code.name.monkey.retromusic.fragments.player
import android.animation.ObjectAnimator
import android.graphics.PorterDuff
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.animation.LinearInterpolator
import android.widget.SeekBar
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.Toolbar
import androidx.core.view.ViewCompat
import androidx.recyclerview.widget.LinearLayoutManager
import code.name.monkey.appthemehelper.ThemeStore
import code.name.monkey.appthemehelper.util.*
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.adapter.song.PlayingQueueAdapter
import code.name.monkey.retromusic.extensions.hide
import code.name.monkey.retromusic.extensions.ripAlpha
import code.name.monkey.retromusic.extensions.show
import code.name.monkey.retromusic.fragments.VolumeFragment
import code.name.monkey.retromusic.fragments.base.AbsPlayerControlsFragment
import code.name.monkey.retromusic.fragments.base.AbsPlayerFragment
import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.helper.MusicProgressViewUpdateHelper
import code.name.monkey.retromusic.helper.PlayPauseButtonOnClickHandler
import code.name.monkey.retromusic.misc.SimpleOnSeekbarChangeListener
import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.service.MusicService
import code.name.monkey.retromusic.util.MusicUtil
import code.name.monkey.retromusic.util.PreferenceUtil
import code.name.monkey.retromusic.util.ViewUtil
import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.android.material.card.MaterialCardView
import kotlinx.android.synthetic.main.fragment_full_player.*
import kotlinx.android.synthetic.main.fragment_layout_test.*
class TestPlayerFragment : AbsPlayerFragment(), View.OnLayoutChangeListener,
MusicProgressViewUpdateHelper.Callback {
private var lastColor: Int = 0
private var lastPlaybackControlsColor: Int = 0
private var lastDisabledPlaybackControlsColor: Int = 0
private lateinit var progressViewUpdateHelper: MusicProgressViewUpdateHelper
private lateinit var queueAdapter: PlayingQueueAdapter
private var volumeFragment: VolumeFragment? = null
private val bottomSheetCallbackList = object : BottomSheetBehavior.BottomSheetCallback() {
override fun onSlide(bottomSheet: View, slideOffset: Float) {
handle.alpha = 1 - slideOffset
}
override fun onStateChanged(bottomSheet: View, newState: Int) {
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
progressViewUpdateHelper = MusicProgressViewUpdateHelper(this)
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment_full_player, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
setupPanel()
setUpMusicControllers()
setUpPlayerToolbar()
hideVolumeIfAvailable()
setUpQueue()
val coverFragment =
childFragmentManager.findFragmentById(R.id.playerAlbumCoverFragment) as PlayerAlbumCoverFragment
coverFragment.setCallbacks(this)
getQueuePanel().addBottomSheetCallback(bottomSheetCallbackList)
}
private fun hideVolumeIfAvailable() {
if (PreferenceUtil.getInstance(requireContext()).volumeToggle) {
childFragmentManager.beginTransaction()
.replace(R.id.volumeFragmentContainer, VolumeFragment.newInstance())
.commit()
childFragmentManager.executePendingTransactions()
volumeFragment =
childFragmentManager.findFragmentById(R.id.volumeFragmentContainer) as VolumeFragment?
}
}
private fun updateSong() {
val song = MusicPlayerRemote.currentSong
title.text = song.title
text.text = song.artistName
if (PreferenceUtil.getInstance(requireContext()).isSongInfo) {
songInfo.text = getSongInfo(song)
songInfo.show()
} else {
songInfo.hide()
}
}
override fun onResume() {
super.onResume()
progressViewUpdateHelper.start()
}
override fun onPause() {
super.onPause()
progressViewUpdateHelper.stop()
}
private fun getQueuePanel(): BottomSheetBehavior<MaterialCardView> {
playerQueueSheet as MaterialCardView
return BottomSheetBehavior.from(playerQueueSheet)
}
private fun setupPanel() {
if (!ViewCompat.isLaidOut(playerContainer) || playerContainer.isLayoutRequested) {
playerContainer.addOnLayoutChangeListener(this)
return
}
val height = playerContainer.height
val width = playerContainer.width
val finalHeight = height - (playerControlsContainer.height + width)
val panel = getQueuePanel()
panel.peekHeight = finalHeight
}
private fun setUpPlayerToolbar() {
playerToolbar.inflateMenu(R.menu.menu_player)
playerToolbar.setNavigationOnClickListener { requireActivity().onBackPressed() }
playerToolbar.setOnMenuItemClickListener(this)
ToolbarContentTintHelper.colorizeToolbar(
playerToolbar,
ATHUtil.resolveColor(requireContext(), R.attr.colorControlNormal),
requireActivity()
)
}
private fun setUpQueue() {
queueAdapter = PlayingQueueAdapter(
requireActivity() as AppCompatActivity, mutableListOf(),
MusicPlayerRemote.position,
R.layout.item_queue
)
playerQueueRecyclerView.apply {
adapter = queueAdapter
layoutManager = LinearLayoutManager(requireContext())
}
}
override fun onServiceConnected() {
super.onServiceConnected()
updateSong()
queueAdapter.swapDataSet(MusicPlayerRemote.playingQueue)
}
override fun onPlayingMetaChanged() {
super.onPlayingMetaChanged()
updateSong()
}
override fun onQueueChanged() {
super.onQueueChanged()
queueAdapter.swapDataSet(MusicPlayerRemote.playingQueue)
}
override fun playerToolbar(): Toolbar? {
return playerToolbar
}
override fun onShow() {
}
override fun onHide() {
}
override fun onBackPressed(): Boolean {
if (getQueuePanel().state == BottomSheetBehavior.STATE_EXPANDED) {
getQueuePanel().state = BottomSheetBehavior.STATE_COLLAPSED
}
return false
}
override fun toolbarIconColor(): Int {
return ATHUtil.resolveColor(requireContext(), R.attr.colorControlNormal)
}
override val paletteColor: Int
get() = lastColor
override fun onColorChanged(color: Int) {
playerContainer.setBackgroundColor(color)
val colorBg = ATHUtil.resolveColor(requireContext(), color)
if (ColorUtil.isColorLight(colorBg)) {
lastPlaybackControlsColor =
MaterialValueHelper.getSecondaryTextColor(requireContext(), true)
lastDisabledPlaybackControlsColor =
MaterialValueHelper.getSecondaryDisabledTextColor(requireContext(), true)
} else {
lastPlaybackControlsColor =
MaterialValueHelper.getPrimaryTextColor(requireContext(), false)
lastDisabledPlaybackControlsColor =
MaterialValueHelper.getPrimaryDisabledTextColor(requireContext(), false)
}
val colorFinal = if (PreferenceUtil.getInstance(requireContext()).adaptiveColor) {
color
} else {
ThemeStore.accentColor(requireContext())
}.ripAlpha()
TintHelper.setTintAuto(
playPauseButton,
MaterialValueHelper.getPrimaryTextColor(
requireContext(),
ColorUtil.isColorLight(colorFinal)
),
false
)
title.setTextColor(lastPlaybackControlsColor)
text.setTextColor(lastDisabledPlaybackControlsColor)
songInfo.setTextColor(lastDisabledPlaybackControlsColor)
songCurrentProgress.setTextColor(lastPlaybackControlsColor)
songTotalTime.setTextColor(lastPlaybackControlsColor)
volumeFragment?.setTintableColor(lastPlaybackControlsColor)
TintHelper.setTintAuto(playPauseButton, colorFinal, true)
ViewUtil.setProgressDrawable(progressSlider, colorFinal, true)
updateRepeatState()
updateShuffleState()
updatePrevNextColor()
}
override fun toggleFavorite(song: Song) {
super.toggleFavorite(song)
if (song.id == MusicPlayerRemote.currentSong.id) {
updateIsFavorite()
}
}
override fun onFavoriteToggled() {
toggleFavorite(MusicPlayerRemote.currentSong)
}
override fun onUpdateProgressViews(progress: Int, total: Int) {
progressSlider.max = total
val animator = ObjectAnimator.ofInt(progressSlider, "progress", progress)
animator.duration = AbsPlayerControlsFragment.SLIDER_ANIMATION_TIME
animator.interpolator = LinearInterpolator()
animator.start()
songTotalTime.text = MusicUtil.getReadableDurationString(total.toLong())
songCurrentProgress.text = MusicUtil.getReadableDurationString(progress.toLong())
}
override fun onPlayStateChanged() {
updatePlayPauseDrawableState()
}
override fun onRepeatModeChanged() {
updateRepeatState()
}
override fun onShuffleModeChanged() {
updateShuffleState()
}
private fun setUpPlayPauseFab() {
playPauseButton.setOnClickListener(PlayPauseButtonOnClickHandler())
}
private fun updatePlayPauseDrawableState() {
if (MusicPlayerRemote.isPlaying) {
playPauseButton.setImageResource(R.drawable.ic_pause_white_24dp)
} else {
playPauseButton.setImageResource(R.drawable.ic_play_arrow_white_24dp)
}
}
private fun setUpMusicControllers() {
setUpPlayPauseFab()
setUpPrevNext()
setUpRepeatButton()
setUpShuffleButton()
setUpProgressSlider()
}
fun setUpProgressSlider() {
progressSlider.setOnSeekBarChangeListener(object : SimpleOnSeekbarChangeListener() {
override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) {
if (fromUser) {
MusicPlayerRemote.seekTo(progress)
onUpdateProgressViews(
MusicPlayerRemote.songProgressMillis,
MusicPlayerRemote.songDurationMillis
)
}
}
})
}
private fun setUpPrevNext() {
updatePrevNextColor()
nextButton.setOnClickListener { MusicPlayerRemote.playNextSong() }
previousButton.setOnClickListener { MusicPlayerRemote.back() }
}
private fun updatePrevNextColor() {
nextButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
previousButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
}
private fun setUpShuffleButton() {
shuffleButton.setOnClickListener { MusicPlayerRemote.toggleShuffleMode() }
}
fun updateShuffleState() {
when (MusicPlayerRemote.shuffleMode) {
MusicService.SHUFFLE_MODE_SHUFFLE -> shuffleButton.setColorFilter(
lastPlaybackControlsColor,
PorterDuff.Mode.SRC_IN
)
else -> shuffleButton.setColorFilter(
lastDisabledPlaybackControlsColor,
PorterDuff.Mode.SRC_IN
)
}
}
private fun setUpRepeatButton() {
repeatButton.setOnClickListener { MusicPlayerRemote.cycleRepeatMode() }
}
fun updateRepeatState() {
when (MusicPlayerRemote.repeatMode) {
MusicService.REPEAT_MODE_NONE -> {
repeatButton.setImageResource(R.drawable.ic_repeat_white_24dp)
repeatButton.setColorFilter(
lastDisabledPlaybackControlsColor,
PorterDuff.Mode.SRC_IN
)
}
MusicService.REPEAT_MODE_ALL -> {
repeatButton.setImageResource(R.drawable.ic_repeat_white_24dp)
repeatButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
}
MusicService.REPEAT_MODE_THIS -> {
repeatButton.setImageResource(R.drawable.ic_repeat_one_white_24dp)
repeatButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
}
}
}
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
val width = playerContainer.width
val finalHeight = height - (playerControlsContainer.height + width)
val panel = getQueuePanel()
panel.peekHeight = finalHeight
}
}

View File

@ -1,6 +1,7 @@
package code.name.monkey.retromusic.fragments.player.color package code.name.monkey.retromusic.fragments.player.color
import android.animation.ValueAnimator import android.animation.ValueAnimator
import android.graphics.Color
import android.graphics.drawable.Drawable import android.graphics.drawable.Drawable
import android.os.Bundle import android.os.Bundle
import android.view.LayoutInflater import android.view.LayoutInflater
@ -12,6 +13,7 @@ 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.appthemehelper.util.ToolbarContentTintHelper import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
import code.name.monkey.retromusic.R import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.extensions.getSuitableColorFor
import code.name.monkey.retromusic.fragments.base.AbsPlayerFragment import code.name.monkey.retromusic.fragments.base.AbsPlayerFragment
import code.name.monkey.retromusic.glide.RetroMusicColoredTarget import code.name.monkey.retromusic.glide.RetroMusicColoredTarget
import code.name.monkey.retromusic.glide.SongGlideRequest.Builder import code.name.monkey.retromusic.glide.SongGlideRequest.Builder
@ -143,7 +145,14 @@ class ColorFragment : AbsPlayerFragment() {
val swatch = RetroColorUtil.getSwatch(palette) val swatch = RetroColorUtil.getSwatch(palette)
val textColor = RetroColorUtil.getTextColor(palette) val textColor = RetroColorUtil.getTextColor(palette)
val backgroundColor = swatch.rgb val backgroundColor = getSuitableColorFor(
palette,
ATHUtil.resolveColor(requireContext(), R.attr.colorSurface),
Color.BLACK
)
if (ATHUtil.isWindowBackgroundDark(requireContext())) {
ColorUtil.desaturateColor(backgroundColor, 0.5f)
}
setColors(backgroundColor, textColor) setColors(backgroundColor, textColor)
} }

View File

@ -68,8 +68,8 @@ public class ArtistGlideRequest {
final Artist artist; final Artist artist;
final RequestManager requestManager; final RequestManager requestManager;
boolean forceDownload; private boolean forceDownload;
boolean noCustomImage; private boolean noCustomImage;
private Builder(@NonNull RequestManager requestManager, Artist artist) { private Builder(@NonNull RequestManager requestManager, Artist artist) {
this.requestManager = requestManager; this.requestManager = requestManager;

View File

@ -17,29 +17,48 @@ import android.os.Parcelable
import androidx.room.ColumnInfo import androidx.room.ColumnInfo
import androidx.room.Entity import androidx.room.Entity
import androidx.room.PrimaryKey import androidx.room.PrimaryKey
import code.name.monkey.retromusic.BuildConfig
import code.name.monkey.retromusic.room.SongEntity import code.name.monkey.retromusic.room.SongEntity
import code.name.monkey.retromusic.room.SongQueueEntity
import kotlinx.android.parcel.Parcelize import kotlinx.android.parcel.Parcelize
@Parcelize @Parcelize
@Entity(tableName = "playing_queue")
open class Song( open class Song(
@PrimaryKey val id: Int, val id: Int,
@ColumnInfo(name = "title") val title: String, val title: String,
@ColumnInfo(name = "track_number") val trackNumber: Int, val trackNumber: Int,
@ColumnInfo(name = "year") val year: Int, val year: Int,
@ColumnInfo(name = "duration") val duration: Long, val duration: Long,
@ColumnInfo(name = "data") val data: String, val data: String,
@ColumnInfo(name = "date_modified") val dateModified: Long, val dateModified: Long,
@ColumnInfo(name = "album_id") val albumId: Int, val albumId: Int,
@ColumnInfo(name = "album_name") val albumName: String, val albumName: String,
@ColumnInfo(name = "artist_id") val artistId: Int, val artistId: Int,
@ColumnInfo(name = "artist_name") val artistName: String, val artistName: String,
@ColumnInfo(name = "composer") val composer: String? val composer: String?
) : Parcelable { ) : Parcelable {
companion object { companion object {
fun toSongEntity(song: Song): SongEntity { fun toSongEntity(song: Song): SongQueueEntity {
return SongQueueEntity(
song.id,
song.title,
song.trackNumber,
song.year,
song.duration,
song.data,
song.dateModified,
song.albumId,
song.albumName,
song.artistId,
song.artistName,
song.composer
)
}
fun toSongQueueEntity(song: Song): SongEntity {
return SongEntity( return SongEntity(
song.id, song.id,
song.title, song.title,

View File

@ -48,10 +48,8 @@ class SynchronizedLyricsLRC extends AbsSynchronizedLyrics {
try { try {
String attr = attrMatcher.group(1).toLowerCase().trim(); String attr = attrMatcher.group(1).toLowerCase().trim();
String value = attrMatcher.group(2).toLowerCase().trim(); String value = attrMatcher.group(2).toLowerCase().trim();
switch (attr) { if ("offset".equals(attr)) {
case "offset":
this.offset = Integer.parseInt(value); this.offset = Integer.parseInt(value);
break;
} }
} catch (Exception ex) { } catch (Exception ex) {
ex.printStackTrace(); ex.printStackTrace();

View File

@ -4,9 +4,10 @@ import android.content.Context
import androidx.room.Database import androidx.room.Database
import androidx.room.Room import androidx.room.Room
import androidx.room.RoomDatabase import androidx.room.RoomDatabase
import code.name.monkey.retromusic.BuildConfig
import code.name.monkey.retromusic.model.Song import code.name.monkey.retromusic.model.Song
@Database(entities = [Song::class, SongEntity::class], version = 3, exportSchema = false) @Database(entities = [SongQueueEntity::class, SongEntity::class], version = 8, exportSchema = false)
abstract class MusicPlaybackQueueStoreDatabase : RoomDatabase() { abstract class MusicPlaybackQueueStoreDatabase : RoomDatabase() {
abstract fun queueDao(): QueueDao abstract fun queueDao(): QueueDao

View File

@ -1,18 +1,33 @@
package code.name.monkey.retromusic.room package code.name.monkey.retromusic.room
import androidx.room.Transaction
import code.name.monkey.retromusic.model.Song import code.name.monkey.retromusic.model.Song
class MusicQueueRepository(private val queueDao: QueueDao) { class MusicQueueRepository(private val queueDao: QueueDao) {
fun getQueue(): List<Song> = queueDao.getQueue() fun getQueue(): List<Song> =
queueDao.getQueue().map { SongQueueEntity.toSong(it) }
fun getOriginalQueue(): List<SongEntity> = queueDao.getOriginalQueue() fun getOriginalQueue(): List<Song> =
queueDao.getOriginalQueue().map { SongEntity.toSong(it) }
suspend fun insertQueue(queue: List<Song>) { suspend fun insertQueue(queue: List<Song>) {
queueDao.saveQueue(queue) deleteAndSave(queue)
} }
suspend fun insertOriginalQueue(queue: List<SongEntity>) { @Transaction
queueDao.saveOriginalQueue(queue) private suspend fun deleteAndSave(queue: List<Song>) {
queueDao.deleteQueue()
queueDao.saveQueue(queue.map { Song.toSongEntity(it) })
}
suspend fun insertOriginalQueue(queue: List<Song>) {
deleteAndSaveOriginalQueue(queue)
}
@Transaction
private suspend fun deleteAndSaveOriginalQueue(queue: List<Song>) {
queueDao.deleteOriginalQueue()
queueDao.saveOriginalQueue(queue.map { Song.toSongQueueEntity(it) })
} }
} }

View File

@ -17,7 +17,7 @@ class NowPlayingQueue(context: Context) {
} }
fun saveOriginalQueue(songs: List<Song>) = GlobalScope.launch(Dispatchers.Default) { fun saveOriginalQueue(songs: List<Song>) = GlobalScope.launch(Dispatchers.Default) {
musicQueueRepository.insertOriginalQueue(songs.map { Song.toSongEntity(it) }) musicQueueRepository.insertOriginalQueue(songs)
} }
fun getQueue(): List<Song> { fun getQueue(): List<Song> {
@ -25,6 +25,6 @@ class NowPlayingQueue(context: Context) {
} }
fun getOriginalQueue(): List<Song> { fun getOriginalQueue(): List<Song> {
return musicQueueRepository.getOriginalQueue().map { SongEntity.toSong(it) } return musicQueueRepository.getOriginalQueue()
} }
} }

View File

@ -4,6 +4,7 @@ import androidx.room.Dao
import androidx.room.Insert import androidx.room.Insert
import androidx.room.OnConflictStrategy import androidx.room.OnConflictStrategy
import androidx.room.Query import androidx.room.Query
import code.name.monkey.retromusic.BuildConfig
import code.name.monkey.retromusic.model.Song import code.name.monkey.retromusic.model.Song
/** /**
@ -13,15 +14,21 @@ import code.name.monkey.retromusic.model.Song
interface QueueDao { interface QueueDao {
@Insert(onConflict = OnConflictStrategy.REPLACE) @Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun saveQueue(playingQueue: List<Song>) suspend fun saveQueue(playingQueue: List<SongQueueEntity>)
@Insert(onConflict = OnConflictStrategy.REPLACE) @Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun saveOriginalQueue(playingQueue: List<SongEntity>) suspend fun saveOriginalQueue(playingQueue: List<SongEntity>)
@Query("SELECT * FROM playing_queue") @Query("SELECT * FROM playing_queue_${BuildConfig.FLAVOR}")
fun getQueue(): List<Song> fun getQueue(): List<SongQueueEntity>
@Query("SELECT * FROM original_playing_queue") @Query("SELECT * FROM original_playing_queue_${BuildConfig.FLAVOR}")
fun getOriginalQueue(): List<SongEntity> fun getOriginalQueue(): List<SongEntity>
@Query("DELETE FROM playing_queue_${BuildConfig.FLAVOR}")
suspend fun deleteQueue()
@Query("DELETE FROM original_playing_queue_${BuildConfig.FLAVOR}")
suspend fun deleteOriginalQueue()
} }

View File

@ -3,11 +3,12 @@ package code.name.monkey.retromusic.room
import androidx.room.ColumnInfo import androidx.room.ColumnInfo
import androidx.room.Entity import androidx.room.Entity
import androidx.room.PrimaryKey import androidx.room.PrimaryKey
import code.name.monkey.retromusic.BuildConfig
import code.name.monkey.retromusic.model.Song import code.name.monkey.retromusic.model.Song
@Entity(tableName = "original_playing_queue") @Entity(tableName = "original_playing_queue_${BuildConfig.FLAVOR}")
class SongEntity( data class SongEntity(
@PrimaryKey val id: Int, @ColumnInfo(name = "id") val id: Int,
@ColumnInfo(name = "title") val title: String, @ColumnInfo(name = "title") val title: String,
@ColumnInfo(name = "track_number") val trackNumber: Int, @ColumnInfo(name = "track_number") val trackNumber: Int,
@ColumnInfo(name = "year") val year: Int, @ColumnInfo(name = "year") val year: Int,
@ -20,6 +21,10 @@ class SongEntity(
@ColumnInfo(name = "artist_name") val artistName: String, @ColumnInfo(name = "artist_name") val artistName: String,
@ColumnInfo(name = "composer") val composer: String? @ColumnInfo(name = "composer") val composer: String?
) { ) {
@PrimaryKey(autoGenerate = true)
@ColumnInfo(name = "primary_id")
var primaryId: Int? = null
companion object { companion object {
fun toSong(song: SongEntity): Song { fun toSong(song: SongEntity): Song {
return Song( return Song(

View File

@ -0,0 +1,46 @@
package code.name.monkey.retromusic.room
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey
import code.name.monkey.retromusic.BuildConfig
import code.name.monkey.retromusic.model.Song
@Entity(tableName = "playing_queue_${BuildConfig.FLAVOR}")
data class SongQueueEntity(
@ColumnInfo(name = "id") var id: Int,
@ColumnInfo(name = "title") var title: String,
@ColumnInfo(name = "track_number") var trackNumber: Int,
@ColumnInfo(name = "year") var year: Int,
@ColumnInfo(name = "duration") var duration: Long,
@ColumnInfo(name = "data") var data: String,
@ColumnInfo(name = "date_modified") var dateModified: Long,
@ColumnInfo(name = "album_id") var albumId: Int,
@ColumnInfo(name = "album_name") var albumName: String,
@ColumnInfo(name = "artist_id") var artistId: Int,
@ColumnInfo(name = "artist_name") var artistName: String,
@ColumnInfo(name = "composer") var composer: String?
) {
@PrimaryKey(autoGenerate = true)
@ColumnInfo(name = "primary_id")
var primaryId: Int? = null
companion object {
fun toSong(song: SongQueueEntity): Song {
return Song(
song.id,
song.title,
song.trackNumber,
song.year,
song.duration,
song.data,
song.dateModified,
song.albumId,
song.albumName,
song.artistId,
song.artistName,
song.composer
)
}
}
}

View File

@ -331,7 +331,7 @@ public class MultiPlayer implements Playback, MediaPlayer.OnErrorListener, Media
*/ */
@Override @Override
public void onCompletion(final MediaPlayer mp) { public void onCompletion(final MediaPlayer mp) {
if (mp == mCurrentMediaPlayer && mNextMediaPlayer != null) { if (mp.equals(mCurrentMediaPlayer) && mNextMediaPlayer != null) {
mIsInitialized = false; mIsInitialized = false;
mCurrentMediaPlayer.release(); mCurrentMediaPlayer.release();
mCurrentMediaPlayer = mNextMediaPlayer; mCurrentMediaPlayer = mNextMediaPlayer;

View File

@ -752,8 +752,7 @@ public class MusicService extends Service implements
@Override @Override
public int onStartCommand(@Nullable Intent intent, int flags, int startId) { public int onStartCommand(@Nullable Intent intent, int flags, int startId) {
if (intent != null) { if (intent != null && intent.getAction() != null) {
if (intent.getAction() != null) {
restoreQueuesAndPositionIfNecessary(); restoreQueuesAndPositionIfNecessary();
String action = intent.getAction(); String action = intent.getAction();
switch (action) { switch (action) {
@ -792,7 +791,6 @@ public class MusicService extends Service implements
break; break;
} }
} }
}
return START_NOT_STICKY; return START_NOT_STICKY;
} }

View File

@ -91,7 +91,7 @@ public class CalendarUtil {
year--; year--;
} }
elapsed += getDaysInMonth(year, month) * MS_PER_DAY; elapsed += getDaysInMonth(month) * MS_PER_DAY;
} }
return elapsed; return elapsed;
@ -109,7 +109,7 @@ public class CalendarUtil {
int month = calendar.get(Calendar.MONTH) - 1; int month = calendar.get(Calendar.MONTH) - 1;
int year = calendar.get(Calendar.YEAR); int year = calendar.get(Calendar.YEAR);
while (month > Calendar.JANUARY) { while (month > Calendar.JANUARY) {
elapsed += getDaysInMonth(year, month) * MS_PER_DAY; elapsed += getDaysInMonth(month) * MS_PER_DAY;
month--; month--;
} }
@ -120,11 +120,10 @@ public class CalendarUtil {
/** /**
* Gets the number of days for the given month in the given year. * Gets the number of days for the given month in the given year.
* *
* @param year The year.
* @param month The month (1 - 12). * @param month The month (1 - 12).
* @return The days in that month/year. * @return The days in that month/year.
*/ */
private int getDaysInMonth(int year, int month) { private int getDaysInMonth(int month) {
final Calendar monthCal = new GregorianCalendar(calendar.get(Calendar.YEAR), month, 1); final Calendar monthCal = new GregorianCalendar(calendar.get(Calendar.YEAR), month, 1);
return monthCal.getActualMaximum(Calendar.DAY_OF_MONTH); return monthCal.getActualMaximum(Calendar.DAY_OF_MONTH);
} }

View File

@ -373,8 +373,8 @@ public class MusicUtil {
if (artistName.equals(Artist.UNKNOWN_ARTIST_DISPLAY_NAME)) { if (artistName.equals(Artist.UNKNOWN_ARTIST_DISPLAY_NAME)) {
return true; return true;
} }
artistName = artistName.trim().toLowerCase(); String tempName = artistName.trim().toLowerCase();
return artistName.equals("unknown") || artistName.equals("<unknown>"); return tempName.equals("unknown") || tempName.equals("<unknown>");
} }
public static boolean isFavorite(@NonNull final Context context, @NonNull final Song song) { public static boolean isFavorite(@NonNull final Context context, @NonNull final Song song) {

View File

@ -194,10 +194,11 @@ public class RetroColorUtil {
@ColorInt @ColorInt
public static int shiftBackgroundColorForDarkText(@ColorInt int backgroundColor) { public static int shiftBackgroundColorForDarkText(@ColorInt int backgroundColor) {
int color = backgroundColor;
while (!ColorUtil.INSTANCE.isColorLight(backgroundColor)) { while (!ColorUtil.INSTANCE.isColorLight(backgroundColor)) {
backgroundColor = ColorUtil.INSTANCE.lightenColor(backgroundColor); color = ColorUtil.INSTANCE.lightenColor(backgroundColor);
} }
return backgroundColor; return color;
} }
private static class SwatchComparator implements Comparator<Palette.Swatch> { private static class SwatchComparator implements Comparator<Palette.Swatch> {

View File

@ -88,6 +88,16 @@ public class PopupBackground extends Drawable {
outline.setConvexPath(mPath); outline.setConvexPath(mPath);
} }
@Override
public void setAlpha(int alpha) {
}
@Override
public void setColorFilter(@Nullable ColorFilter colorFilter) {
}
@Override @Override
public boolean getPadding(@NonNull Rect padding) { public boolean getPadding(@NonNull Rect padding) {
if (needMirroring()) { if (needMirroring()) {
@ -109,13 +119,6 @@ public class PopupBackground extends Drawable {
return true; return true;
} }
@Override
public void setAlpha(int alpha) {
}
@Override
public void setColorFilter(@Nullable ColorFilter colorFilter) {
}
@Override @Override
protected void onBoundsChange(@NonNull Rect bounds) { protected void onBoundsChange(@NonNull Rect bounds) {

View File

@ -0,0 +1,97 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="@+id/playerContainer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?attr/colorSurface"
android:orientation="vertical">
<code.name.monkey.retromusic.views.WidthFitSquareLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.fragment.app.FragmentContainerView
android:id="@+id/playerAlbumCoverFragment"
android:name="code.name.monkey.retromusic.fragments.player.PlayerAlbumCoverFragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</code.name.monkey.retromusic.views.WidthFitSquareLayout>
<include
android:id="@+id/playerControlsContainer"
layout="@layout/fragment_layout_test"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
<com.google.android.material.card.MaterialCardView
android:id="@+id/playerQueueSheet"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="bottom"
android:orientation="vertical"
app:behavior_hideable="false"
app:cardCornerRadius="16dp"
app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<View
android:id="@+id/handle"
android:layout_width="56dp"
android:layout_height="4dp"
android:layout_gravity="center_horizontal"
android:layout_marginTop="12dp"
android:layout_marginBottom="12dp"
android:alpha="0.3"
android:background="@drawable/scroll_handler" />
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/playerToolbar"
style="@style/Toolbar"
android:layout_gravity="bottom"
android:navigationIcon="@drawable/ic_keyboard_arrow_down_black_24dp"
app:navigationIcon="@drawable/ic_keyboard_arrow_down_black_24dp" />
</FrameLayout>
<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/playerQueueRecyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?attr/colorSurface"
tools:listitem="@layout/item_list" />
</LinearLayout>
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@ -0,0 +1,214 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/playback_controls"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_vertical"
android:orientation="vertical"
android:paddingBottom="8dp"
tools:ignore="MissingPrefix">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/progressContainer"
android:layout_width="match_parent"
android:layout_height="@dimen/progress_container_height"
android:background="@color/twenty_percent_black_overlay"
app:layout_constraintTop_toTopOf="parent">
<com.google.android.material.textview.MaterialTextView
android:id="@+id/songCurrentProgress"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:gravity="center_vertical|left|end"
android:paddingStart="8dp"
android:singleLine="true"
android:textColor="?android:attr/textColorSecondary"
android:textSize="12sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="RtlHardcoded,RtlSymmetry"
tools:text="00:22" />
<androidx.appcompat.widget.AppCompatSeekBar
android:id="@+id/progressSlider"
style="@style/MusicProgressSlider"
android:layout_width="0dp"
android:layout_height="match_parent"
app:layout_constraintEnd_toStartOf="@id/songTotalTime"
app:layout_constraintStart_toEndOf="@id/songCurrentProgress"
tools:ignore="RtlHardcoded,UnusedAttribute" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/songTotalTime"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical|right|end"
android:paddingEnd="8dp"
android:singleLine="true"
android:textColor="?android:attr/textColorSecondary"
android:textSize="12sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="RtlHardcoded,RtlSymmetry"
tools:text="00:22" />
</androidx.constraintlayout.widget.ConstraintLayout>
<LinearLayout
android:id="@+id/titleContainer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toTopOf="@+id/text"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/progressContainer">
<com.google.android.material.textview.MaterialTextView
android:id="@+id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:ellipsize="marquee"
android:focusable="true"
android:focusableInTouchMode="true"
android:freezesText="true"
android:gravity="center"
android:marqueeRepeatLimit="marquee_forever"
android:paddingStart="16dp"
android:paddingTop="8dp"
android:paddingEnd="16dp"
android:paddingBottom="8dp"
android:scrollHorizontally="true"
android:singleLine="true"
android:textAppearance="@style/TextViewHeadline6"
android:textColor="?android:attr/textColorPrimary"
android:textStyle="bold"
tools:text="@tools:sample/lorem/random" />
</LinearLayout>
<com.google.android.material.textview.MaterialTextView
android:id="@+id/text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:ellipsize="end"
android:gravity="center"
android:maxLines="1"
android:paddingStart="16dp"
android:paddingTop="8dp"
android:paddingEnd="16dp"
android:paddingBottom="8dp"
android:textAppearance="@style/TextViewBody1"
android:textColor="?android:attr/textColorSecondary"
app:layout_constrainedWidth="true"
app:layout_constraintBottom_toTopOf="@+id/songInfo"
app:layout_constraintTop_toBottomOf="@+id/titleContainer"
tools:text="@tools:sample/lorem/random" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/songInfo"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:ellipsize="end"
android:gravity="center"
android:maxLines="2"
android:paddingStart="16dp"
android:paddingTop="8dp"
android:paddingEnd="16dp"
android:paddingBottom="8dp"
android:textColor="?android:attr/textColorSecondary"
android:textSize="12sp"
app:layout_constraintBottom_toTopOf="@+id/playPauseButton"
app:layout_constraintTop_toBottomOf="@+id/text"
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" />
<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/songInfo"
app:srcCompat="@drawable/ic_pause_white_24dp"
tools:tint="@color/md_black_1000" />
<androidx.appcompat.widget.AppCompatImageButton
android:id="@+id/nextButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="?attr/roundSelector"
android:padding="16dp"
android:scaleType="fitCenter"
app:layout_constraintBottom_toBottomOf="@+id/playPauseButton"
app:layout_constraintEnd_toStartOf="@+id/shuffleButton"
app:layout_constraintStart_toEndOf="@+id/playPauseButton"
app:layout_constraintTop_toTopOf="@+id/playPauseButton"
app:srcCompat="@drawable/ic_skip_next_white_24dp"
tools:ignore="MissingPrefix"
tools:tint="@color/md_black_1000" />
<androidx.appcompat.widget.AppCompatImageButton
android:id="@+id/shuffleButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="?attr/roundSelector"
android:padding="16dp"
android:scaleType="fitCenter"
app:layout_constraintBottom_toBottomOf="@+id/nextButton"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/nextButton"
app:layout_constraintTop_toTopOf="@+id/nextButton"
app:srcCompat="@drawable/ic_shuffle_white_24dp"
tools:ignore="MissingPrefix"
tools:tint="@color/md_black_1000" />
<FrameLayout
android:id="@+id/volumeFragmentContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0"
app:layout_constraintBottom_toBottomOf="parent"
tools:background="@color/md_red_400"
tools:layout_height="52dp" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -28,6 +28,7 @@
android:id="@+id/progressSlider" android:id="@+id/progressSlider"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
app:haloRadius="0dp"
app:labelBehavior="gone" app:labelBehavior="gone"
app:layout_constraintEnd_toStartOf="@id/songTotalTime" app:layout_constraintEnd_toStartOf="@id/songTotalTime"
app:layout_constraintStart_toEndOf="@id/songCurrentProgress" app:layout_constraintStart_toEndOf="@id/songCurrentProgress"
@ -74,7 +75,9 @@
android:gravity="center" android:gravity="center"
android:marqueeRepeatLimit="marquee_forever" android:marqueeRepeatLimit="marquee_forever"
android:paddingStart="16dp" android:paddingStart="16dp"
android:paddingTop="8dp"
android:paddingEnd="16dp" android:paddingEnd="16dp"
android:paddingBottom="8dp"
android:scrollHorizontally="true" android:scrollHorizontally="true"
android:singleLine="true" android:singleLine="true"
android:textAppearance="@style/TextViewHeadline6" android:textAppearance="@style/TextViewHeadline6"
@ -92,7 +95,9 @@
android:gravity="center" android:gravity="center"
android:maxLines="1" android:maxLines="1"
android:paddingStart="16dp" android:paddingStart="16dp"
android:paddingTop="8dp"
android:paddingEnd="16dp" android:paddingEnd="16dp"
android:paddingBottom="8dp"
android:textAppearance="@style/TextViewBody1" android:textAppearance="@style/TextViewBody1"
android:textColor="?android:attr/textColorSecondary" android:textColor="?android:attr/textColorSecondary"
app:layout_constrainedWidth="true" app:layout_constrainedWidth="true"

View File

@ -22,8 +22,7 @@
android:visibility="gone" android:visibility="gone"
app:srcCompat="@drawable/ic_drag_vertical_white_24dp" app:srcCompat="@drawable/ic_drag_vertical_white_24dp"
app:tint="?attr/colorControlNormal" app:tint="?attr/colorControlNormal"
tools:ignore="ContentDescription" tools:ignore="ContentDescription" />
tools:visibility="visible" />
<FrameLayout <FrameLayout
android:id="@+id/imageContainer" android:id="@+id/imageContainer"

View File

@ -18,12 +18,14 @@ package code.name.monkey.appthemehelper.common.prefs.supportv7.dialogs;
import android.app.Dialog; import android.app.Dialog;
import android.os.Bundle; import android.os.Bundle;
import android.view.Window; import android.view.Window;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.DialogFragment; import androidx.fragment.app.DialogFragment;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.preference.DialogPreference; import androidx.preference.DialogPreference;
import com.google.android.material.dialog.MaterialAlertDialogBuilder; import com.google.android.material.dialog.MaterialAlertDialogBuilder;
/** /**
@ -72,7 +74,7 @@ public class ATEPreferenceDialogFragment extends DialogFragment {
onDialogClosed(false); onDialogClosed(false);
}); });
this.onPrepareDialogBuilder(materialDialog); //this.onPrepareDialogBuilder(materialDialog);
AlertDialog dialog = materialDialog.create(); AlertDialog dialog = materialDialog.create();
if (this.needInputMethod()) { if (this.needInputMethod()) {
this.requestInputMethod(dialog); this.requestInputMethod(dialog);
@ -84,11 +86,11 @@ public class ATEPreferenceDialogFragment extends DialogFragment {
} }
protected boolean needInputMethod() { protected void onPrepareDialogBuilder(MaterialAlertDialogBuilder builder) {
return false;
} }
protected void onPrepareDialogBuilder(MaterialAlertDialogBuilder builder) { protected boolean needInputMethod() {
return false;
} }
private void requestInputMethod(Dialog dialog) { private void requestInputMethod(Dialog dialog) {

View File

@ -17,6 +17,7 @@ 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;
@ -26,10 +27,13 @@ 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 code.name.monkey.appthemehelper.R;
import com.google.android.material.floatingactionbutton.FloatingActionButton; import com.google.android.material.floatingactionbutton.FloatingActionButton;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import code.name.monkey.appthemehelper.R;
/** /**
* @author afollestad, plusCubed * @author afollestad, plusCubed
*/ */
@ -105,9 +109,9 @@ public final class TintHelper {
if (drawable == null) { if (drawable == null) {
return null; return null;
} }
drawable = DrawableCompat.wrap(drawable.mutate()); Drawable temp = DrawableCompat.wrap(drawable.mutate());
DrawableCompat.setTintList(drawable, sl); DrawableCompat.setTintList(temp, sl);
return drawable; return temp;
} }
public static void setCursorTint(@NonNull EditText editText, @ColorInt int color) { public static void setCursorTint(@NonNull EditText editText, @ColorInt int color) {