Fix queue changing
This commit is contained in:
parent
69c76556a2
commit
891f1bce34
34 changed files with 1007 additions and 132 deletions
|
@ -197,4 +197,6 @@ dependencies {
|
|||
kapt "androidx.lifecycle:lifecycle-compiler:$lifecycle_version"
|
||||
|
||||
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'
|
||||
}
|
|
@ -56,7 +56,7 @@ public class LicenseActivity extends AbsBaseActivity {
|
|||
WebView webView = findViewById(R.id.license);
|
||||
try {
|
||||
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));
|
||||
String str;
|
||||
while ((str = in.readLine()) != null) {
|
||||
|
|
|
@ -121,8 +121,7 @@ public class MainActivity extends AbsSlidingMusicPanelActivity
|
|||
}
|
||||
};
|
||||
private final IntentFilter mIntentFilter = new IntentFilter(Intent.ACTION_SCREEN_OFF);
|
||||
@Nullable
|
||||
MainActivityFragmentCallbacks currentFragment;
|
||||
private MainActivityFragmentCallbacks currentFragment;
|
||||
private boolean blockRequestPermissions = false;
|
||||
private MaterialCab cab;
|
||||
private AppBarLayout mAppBarLayout;
|
||||
|
@ -231,12 +230,10 @@ public class MainActivity extends AbsSlidingMusicPanelActivity
|
|||
registerReceiver(mBroadcastReceiver, mIntentFilter);
|
||||
PreferenceUtil.getInstance(this).registerOnSharedPreferenceChangedListener(this);
|
||||
|
||||
if (getIntent().hasExtra(EXPAND_PANEL) && PreferenceUtil.getInstance(this).isExpandPanel()) {
|
||||
if (getIntent().getBooleanExtra(EXPAND_PANEL, false)) {
|
||||
if (getIntent().hasExtra(EXPAND_PANEL) && getIntent().getBooleanExtra(EXPAND_PANEL, false) && PreferenceUtil.getInstance(this).isExpandPanel()) {
|
||||
expandPanel();
|
||||
getIntent().putExtra(EXPAND_PANEL, false);
|
||||
}
|
||||
}
|
||||
appUpdateManager.getAppUpdateInfo()
|
||||
.addOnSuccessListener(appUpdateInfo -> {
|
||||
if (appUpdateInfo.installStatus() == InstallStatus.DOWNLOADED) {
|
||||
|
|
|
@ -32,12 +32,6 @@ import code.name.monkey.retromusic.util.PreferenceUtil;
|
|||
|
||||
public class WhatsNewActivity extends AbsBaseActivity {
|
||||
|
||||
AppBarLayout appBarLayout;
|
||||
|
||||
Toolbar toolbar;
|
||||
|
||||
WebView webView;
|
||||
|
||||
private static String colorToCSS(int 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
|
||||
|
@ -62,9 +56,9 @@ public class WhatsNewActivity extends AbsBaseActivity {
|
|||
setNavigationbarColorAuto();
|
||||
setTaskDescriptionColorAuto();
|
||||
|
||||
webView = findViewById(R.id.webView);
|
||||
toolbar = findViewById(R.id.toolbar);
|
||||
appBarLayout = findViewById(R.id.appBarLayout);
|
||||
WebView webView = findViewById(R.id.webView);
|
||||
Toolbar toolbar = findViewById(R.id.toolbar);
|
||||
AppBarLayout appBarLayout = findViewById(R.id.appBarLayout);
|
||||
|
||||
toolbar.setBackgroundColor(ATHUtil.INSTANCE.resolveColor(this, R.attr.colorSurface));
|
||||
//setSupportActionBar(toolbar);
|
||||
|
|
|
@ -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.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.blur.BlurPlayerFragment
|
||||
import code.name.monkey.retromusic.fragments.player.card.CardFragment
|
||||
|
@ -241,6 +242,7 @@ abstract class AbsSlidingMusicPanelActivity : AbsMusicServiceActivity(),
|
|||
TINY -> TinyPlayerFragment()
|
||||
PEAK -> PeakPlayerFragment()
|
||||
CIRCLE -> CirclePlayerFragment()
|
||||
EXAMPLE -> TestPlayerFragment()
|
||||
else -> PlayerFragment()
|
||||
} // must implement AbsPlayerFragment
|
||||
supportFragmentManager.beginTransaction().replace(R.id.playerFragmentContainer, fragment)
|
||||
|
|
|
@ -122,12 +122,9 @@ public class CategoryInfoAdapter extends RecyclerView.Adapter<CategoryInfoAdapte
|
|||
}
|
||||
|
||||
static class ViewHolder extends RecyclerView.ViewHolder {
|
||||
|
||||
MaterialCheckBox checkBox;
|
||||
|
||||
View dragView;
|
||||
|
||||
TextView title;
|
||||
private MaterialCheckBox checkBox;
|
||||
private View dragView;
|
||||
private TextView title;
|
||||
|
||||
ViewHolder(View view) {
|
||||
super(view);
|
||||
|
|
|
@ -17,7 +17,7 @@ import code.name.monkey.retromusic.R;
|
|||
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 {
|
||||
|
||||
@Nullable
|
||||
|
|
|
@ -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
|
||||
}
|
|
@ -26,4 +26,5 @@ enum class NowPlayingScreen constructor(
|
|||
PLAIN(R.string.plain, R.drawable.np_plain, 3),
|
||||
SIMPLE(R.string.simple, R.drawable.np_simple, 8),
|
||||
TINY(R.string.tiny, R.drawable.np_tiny, 7),
|
||||
EXAMPLE(R.string.tiny, R.drawable.np_tiny, 16),
|
||||
}
|
||||
|
|
|
@ -92,7 +92,8 @@ public class FoldersFragment extends AbsMainActivityFragment implements
|
|||
private SongFileAdapter adapter;
|
||||
private BreadCrumbLayout breadCrumbs;
|
||||
private MaterialCab cab;
|
||||
private View coordinatorLayout, empty;
|
||||
private View coordinatorLayout;
|
||||
private View empty;
|
||||
private TextView emojiText;
|
||||
private Comparator<File> fileComparator = (lhs, rhs) -> {
|
||||
if (lhs.isDirectory() && !rhs.isDirectory()) {
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
package code.name.monkey.retromusic.fragments.player.color
|
||||
|
||||
import android.animation.ValueAnimator
|
||||
import android.graphics.Color
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.os.Bundle
|
||||
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.ToolbarContentTintHelper
|
||||
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.glide.RetroMusicColoredTarget
|
||||
import code.name.monkey.retromusic.glide.SongGlideRequest.Builder
|
||||
|
@ -143,7 +145,14 @@ class ColorFragment : AbsPlayerFragment() {
|
|||
val swatch = RetroColorUtil.getSwatch(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)
|
||||
}
|
||||
|
|
|
@ -68,8 +68,8 @@ public class ArtistGlideRequest {
|
|||
|
||||
final Artist artist;
|
||||
final RequestManager requestManager;
|
||||
boolean forceDownload;
|
||||
boolean noCustomImage;
|
||||
private boolean forceDownload;
|
||||
private boolean noCustomImage;
|
||||
|
||||
private Builder(@NonNull RequestManager requestManager, Artist artist) {
|
||||
this.requestManager = requestManager;
|
||||
|
|
|
@ -17,29 +17,48 @@ import android.os.Parcelable
|
|||
import androidx.room.ColumnInfo
|
||||
import androidx.room.Entity
|
||||
import androidx.room.PrimaryKey
|
||||
import code.name.monkey.retromusic.BuildConfig
|
||||
import code.name.monkey.retromusic.room.SongEntity
|
||||
import code.name.monkey.retromusic.room.SongQueueEntity
|
||||
import kotlinx.android.parcel.Parcelize
|
||||
|
||||
@Parcelize
|
||||
@Entity(tableName = "playing_queue")
|
||||
|
||||
open class Song(
|
||||
@PrimaryKey val id: Int,
|
||||
@ColumnInfo(name = "title") val title: String,
|
||||
@ColumnInfo(name = "track_number") val trackNumber: Int,
|
||||
@ColumnInfo(name = "year") val year: Int,
|
||||
@ColumnInfo(name = "duration") val duration: Long,
|
||||
@ColumnInfo(name = "data") val data: String,
|
||||
@ColumnInfo(name = "date_modified") val dateModified: Long,
|
||||
@ColumnInfo(name = "album_id") val albumId: Int,
|
||||
@ColumnInfo(name = "album_name") val albumName: String,
|
||||
@ColumnInfo(name = "artist_id") val artistId: Int,
|
||||
@ColumnInfo(name = "artist_name") val artistName: String,
|
||||
@ColumnInfo(name = "composer") val composer: String?
|
||||
val id: Int,
|
||||
val title: String,
|
||||
val trackNumber: Int,
|
||||
val year: Int,
|
||||
val duration: Long,
|
||||
val data: String,
|
||||
val dateModified: Long,
|
||||
val albumId: Int,
|
||||
val albumName: String,
|
||||
val artistId: Int,
|
||||
val artistName: String,
|
||||
val composer: String?
|
||||
) : Parcelable {
|
||||
|
||||
|
||||
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(
|
||||
song.id,
|
||||
song.title,
|
||||
|
|
|
@ -48,10 +48,8 @@ class SynchronizedLyricsLRC extends AbsSynchronizedLyrics {
|
|||
try {
|
||||
String attr = attrMatcher.group(1).toLowerCase().trim();
|
||||
String value = attrMatcher.group(2).toLowerCase().trim();
|
||||
switch (attr) {
|
||||
case "offset":
|
||||
if ("offset".equals(attr)) {
|
||||
this.offset = Integer.parseInt(value);
|
||||
break;
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
|
|
|
@ -4,9 +4,10 @@ import android.content.Context
|
|||
import androidx.room.Database
|
||||
import androidx.room.Room
|
||||
import androidx.room.RoomDatabase
|
||||
import code.name.monkey.retromusic.BuildConfig
|
||||
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 fun queueDao(): QueueDao
|
||||
|
|
|
@ -1,18 +1,33 @@
|
|||
package code.name.monkey.retromusic.room
|
||||
|
||||
import androidx.room.Transaction
|
||||
import code.name.monkey.retromusic.model.Song
|
||||
|
||||
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>) {
|
||||
queueDao.saveQueue(queue)
|
||||
deleteAndSave(queue)
|
||||
}
|
||||
|
||||
suspend fun insertOriginalQueue(queue: List<SongEntity>) {
|
||||
queueDao.saveOriginalQueue(queue)
|
||||
@Transaction
|
||||
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) })
|
||||
}
|
||||
}
|
|
@ -17,7 +17,7 @@ class NowPlayingQueue(context: Context) {
|
|||
}
|
||||
|
||||
fun saveOriginalQueue(songs: List<Song>) = GlobalScope.launch(Dispatchers.Default) {
|
||||
musicQueueRepository.insertOriginalQueue(songs.map { Song.toSongEntity(it) })
|
||||
musicQueueRepository.insertOriginalQueue(songs)
|
||||
}
|
||||
|
||||
fun getQueue(): List<Song> {
|
||||
|
@ -25,6 +25,6 @@ class NowPlayingQueue(context: Context) {
|
|||
}
|
||||
|
||||
fun getOriginalQueue(): List<Song> {
|
||||
return musicQueueRepository.getOriginalQueue().map { SongEntity.toSong(it) }
|
||||
return musicQueueRepository.getOriginalQueue()
|
||||
}
|
||||
}
|
|
@ -4,6 +4,7 @@ import androidx.room.Dao
|
|||
import androidx.room.Insert
|
||||
import androidx.room.OnConflictStrategy
|
||||
import androidx.room.Query
|
||||
import code.name.monkey.retromusic.BuildConfig
|
||||
import code.name.monkey.retromusic.model.Song
|
||||
|
||||
/**
|
||||
|
@ -13,15 +14,21 @@ import code.name.monkey.retromusic.model.Song
|
|||
interface QueueDao {
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
suspend fun saveQueue(playingQueue: List<Song>)
|
||||
suspend fun saveQueue(playingQueue: List<SongQueueEntity>)
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
suspend fun saveOriginalQueue(playingQueue: List<SongEntity>)
|
||||
|
||||
|
||||
@Query("SELECT * FROM playing_queue")
|
||||
fun getQueue(): List<Song>
|
||||
@Query("SELECT * FROM playing_queue_${BuildConfig.FLAVOR}")
|
||||
fun getQueue(): List<SongQueueEntity>
|
||||
|
||||
@Query("SELECT * FROM original_playing_queue")
|
||||
@Query("SELECT * FROM original_playing_queue_${BuildConfig.FLAVOR}")
|
||||
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()
|
||||
}
|
|
@ -3,11 +3,12 @@ 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 = "original_playing_queue")
|
||||
class SongEntity(
|
||||
@PrimaryKey val id: Int,
|
||||
@Entity(tableName = "original_playing_queue_${BuildConfig.FLAVOR}")
|
||||
data class SongEntity(
|
||||
@ColumnInfo(name = "id") val id: Int,
|
||||
@ColumnInfo(name = "title") val title: String,
|
||||
@ColumnInfo(name = "track_number") val trackNumber: Int,
|
||||
@ColumnInfo(name = "year") val year: Int,
|
||||
|
@ -20,6 +21,10 @@ class SongEntity(
|
|||
@ColumnInfo(name = "artist_name") val artistName: String,
|
||||
@ColumnInfo(name = "composer") val composer: String?
|
||||
) {
|
||||
@PrimaryKey(autoGenerate = true)
|
||||
@ColumnInfo(name = "primary_id")
|
||||
var primaryId: Int? = null
|
||||
|
||||
companion object {
|
||||
fun toSong(song: SongEntity): Song {
|
||||
return Song(
|
||||
|
|
|
@ -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
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -331,7 +331,7 @@ public class MultiPlayer implements Playback, MediaPlayer.OnErrorListener, Media
|
|||
*/
|
||||
@Override
|
||||
public void onCompletion(final MediaPlayer mp) {
|
||||
if (mp == mCurrentMediaPlayer && mNextMediaPlayer != null) {
|
||||
if (mp.equals(mCurrentMediaPlayer) && mNextMediaPlayer != null) {
|
||||
mIsInitialized = false;
|
||||
mCurrentMediaPlayer.release();
|
||||
mCurrentMediaPlayer = mNextMediaPlayer;
|
||||
|
|
|
@ -752,8 +752,7 @@ public class MusicService extends Service implements
|
|||
|
||||
@Override
|
||||
public int onStartCommand(@Nullable Intent intent, int flags, int startId) {
|
||||
if (intent != null) {
|
||||
if (intent.getAction() != null) {
|
||||
if (intent != null && intent.getAction() != null) {
|
||||
restoreQueuesAndPositionIfNecessary();
|
||||
String action = intent.getAction();
|
||||
switch (action) {
|
||||
|
@ -792,7 +791,6 @@ public class MusicService extends Service implements
|
|||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return START_NOT_STICKY;
|
||||
}
|
||||
|
|
|
@ -91,7 +91,7 @@ public class CalendarUtil {
|
|||
year--;
|
||||
}
|
||||
|
||||
elapsed += getDaysInMonth(year, month) * MS_PER_DAY;
|
||||
elapsed += getDaysInMonth(month) * MS_PER_DAY;
|
||||
}
|
||||
|
||||
return elapsed;
|
||||
|
@ -109,7 +109,7 @@ public class CalendarUtil {
|
|||
int month = calendar.get(Calendar.MONTH) - 1;
|
||||
int year = calendar.get(Calendar.YEAR);
|
||||
while (month > Calendar.JANUARY) {
|
||||
elapsed += getDaysInMonth(year, month) * MS_PER_DAY;
|
||||
elapsed += getDaysInMonth(month) * MS_PER_DAY;
|
||||
|
||||
month--;
|
||||
}
|
||||
|
@ -120,11 +120,10 @@ public class CalendarUtil {
|
|||
/**
|
||||
* Gets the number of days for the given month in the given year.
|
||||
*
|
||||
* @param year The year.
|
||||
* @param month The month (1 - 12).
|
||||
* @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);
|
||||
return monthCal.getActualMaximum(Calendar.DAY_OF_MONTH);
|
||||
}
|
||||
|
|
|
@ -373,8 +373,8 @@ public class MusicUtil {
|
|||
if (artistName.equals(Artist.UNKNOWN_ARTIST_DISPLAY_NAME)) {
|
||||
return true;
|
||||
}
|
||||
artistName = artistName.trim().toLowerCase();
|
||||
return artistName.equals("unknown") || artistName.equals("<unknown>");
|
||||
String tempName = artistName.trim().toLowerCase();
|
||||
return tempName.equals("unknown") || tempName.equals("<unknown>");
|
||||
}
|
||||
|
||||
public static boolean isFavorite(@NonNull final Context context, @NonNull final Song song) {
|
||||
|
|
|
@ -194,10 +194,11 @@ public class RetroColorUtil {
|
|||
|
||||
@ColorInt
|
||||
public static int shiftBackgroundColorForDarkText(@ColorInt int backgroundColor) {
|
||||
int color = 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> {
|
||||
|
|
|
@ -88,6 +88,16 @@ public class PopupBackground extends Drawable {
|
|||
outline.setConvexPath(mPath);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAlpha(int alpha) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setColorFilter(@Nullable ColorFilter colorFilter) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getPadding(@NonNull Rect padding) {
|
||||
if (needMirroring()) {
|
||||
|
@ -109,13 +119,6 @@ public class PopupBackground extends Drawable {
|
|||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAlpha(int alpha) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setColorFilter(@Nullable ColorFilter colorFilter) {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onBoundsChange(@NonNull Rect bounds) {
|
||||
|
|
97
app/src/main/res/layout/fragment_full_player.xml
Normal file
97
app/src/main/res/layout/fragment_full_player.xml
Normal 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>
|
214
app/src/main/res/layout/fragment_layout_test.xml
Normal file
214
app/src/main/res/layout/fragment_layout_test.xml
Normal 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>
|
|
@ -28,6 +28,7 @@
|
|||
android:id="@+id/progressSlider"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
app:haloRadius="0dp"
|
||||
app:labelBehavior="gone"
|
||||
app:layout_constraintEnd_toStartOf="@id/songTotalTime"
|
||||
app:layout_constraintStart_toEndOf="@id/songCurrentProgress"
|
||||
|
@ -74,7 +75,9 @@
|
|||
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"
|
||||
|
@ -92,7 +95,9 @@
|
|||
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"
|
||||
|
|
|
@ -22,8 +22,7 @@
|
|||
android:visibility="gone"
|
||||
app:srcCompat="@drawable/ic_drag_vertical_white_24dp"
|
||||
app:tint="?attr/colorControlNormal"
|
||||
tools:ignore="ContentDescription"
|
||||
tools:visibility="visible" />
|
||||
tools:ignore="ContentDescription" />
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/imageContainer"
|
||||
|
|
|
@ -18,12 +18,14 @@ package code.name.monkey.appthemehelper.common.prefs.supportv7.dialogs;
|
|||
import android.app.Dialog;
|
||||
import android.os.Bundle;
|
||||
import android.view.Window;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.fragment.app.DialogFragment;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.preference.DialogPreference;
|
||||
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||
|
||||
/**
|
||||
|
@ -72,7 +74,7 @@ public class ATEPreferenceDialogFragment extends DialogFragment {
|
|||
onDialogClosed(false);
|
||||
});
|
||||
|
||||
this.onPrepareDialogBuilder(materialDialog);
|
||||
//this.onPrepareDialogBuilder(materialDialog);
|
||||
AlertDialog dialog = materialDialog.create();
|
||||
if (this.needInputMethod()) {
|
||||
this.requestInputMethod(dialog);
|
||||
|
@ -84,11 +86,11 @@ public class ATEPreferenceDialogFragment extends DialogFragment {
|
|||
|
||||
}
|
||||
|
||||
protected boolean needInputMethod() {
|
||||
return false;
|
||||
protected void onPrepareDialogBuilder(MaterialAlertDialogBuilder builder) {
|
||||
}
|
||||
|
||||
protected void onPrepareDialogBuilder(MaterialAlertDialogBuilder builder) {
|
||||
protected boolean needInputMethod() {
|
||||
return false;
|
||||
}
|
||||
|
||||
private void requestInputMethod(Dialog dialog) {
|
||||
|
|
|
@ -17,6 +17,7 @@ import android.widget.RadioButton;
|
|||
import android.widget.SeekBar;
|
||||
import android.widget.Switch;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.CheckResult;
|
||||
import androidx.annotation.ColorInt;
|
||||
import androidx.annotation.DrawableRes;
|
||||
|
@ -26,10 +27,13 @@ import androidx.appcompat.widget.AppCompatEditText;
|
|||
import androidx.appcompat.widget.SwitchCompat;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.core.graphics.drawable.DrawableCompat;
|
||||
import code.name.monkey.appthemehelper.R;
|
||||
|
||||
import com.google.android.material.floatingactionbutton.FloatingActionButton;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import code.name.monkey.appthemehelper.R;
|
||||
|
||||
/**
|
||||
* @author afollestad, plusCubed
|
||||
*/
|
||||
|
@ -105,9 +109,9 @@ public final class TintHelper {
|
|||
if (drawable == null) {
|
||||
return null;
|
||||
}
|
||||
drawable = DrawableCompat.wrap(drawable.mutate());
|
||||
DrawableCompat.setTintList(drawable, sl);
|
||||
return drawable;
|
||||
Drawable temp = DrawableCompat.wrap(drawable.mutate());
|
||||
DrawableCompat.setTintList(temp, sl);
|
||||
return temp;
|
||||
}
|
||||
|
||||
public static void setCursorTint(@NonNull EditText editText, @ColorInt int color) {
|
||||
|
|
Loading…
Reference in a new issue