Improved carousel effect

This commit is contained in:
h4h13 2019-07-31 00:00:19 +05:30
parent 310cfe8491
commit 0b025f3516
10 changed files with 234 additions and 73 deletions

View file

@ -94,6 +94,8 @@ class AlbumCoverPagerAdapter(fm: FragmentManager, private val dataSet: ArrayList
var finalLayout = layout
if (PreferenceUtil.getInstance().nowPlayingScreen == NowPlayingScreen.CLASSIC) {
finalLayout = R.layout.fragment_album_full_cover
} else if (PreferenceUtil.getInstance().carouselEffect()) {
finalLayout= R.layout.fragment_album_carousel_cover;
}
val view = inflater.inflate(finalLayout, container, false)
albumCover = view.findViewById(R.id.player_image)

View file

@ -16,54 +16,36 @@ package code.name.monkey.retromusic.dialogs
import android.app.Dialog
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.DialogFragment
import androidx.recyclerview.widget.DefaultItemAnimator
import androidx.recyclerview.widget.LinearLayoutManager
import code.name.monkey.appthemehelper.ThemeStore
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.loaders.PlaylistLoader
import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.adapter.playlist.AddToPlaylist
import code.name.monkey.retromusic.views.RoundedBottomSheetDialogFragment
import kotlinx.android.synthetic.main.dialog_add_to_playlist.*
import code.name.monkey.retromusic.util.PlaylistsUtil
import com.google.android.material.dialog.MaterialAlertDialogBuilder
class AddToPlaylistDialog : DialogFragment() {
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
return super.onCreateDialog(savedInstanceState)
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.dialog_add_to_playlist, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val songs = arguments!!.getParcelableArrayList<Song>("songs")
actionAddPlaylist.setOnClickListener {
CreatePlaylistDialog.create(songs!!).show(activity!!.supportFragmentManager, "ADD_TO_PLAYLIST")
dismiss()
}
bannerTitle.setTextColor(ThemeStore.textColorPrimary(context!!))
val playlists = PlaylistLoader.getAllPlaylists(activity!!).blockingFirst()
val playlistAdapter = AddToPlaylist(activity!!, playlists, R.layout.item_playlist, songs!!, dialog!!)
recyclerView.apply {
layoutManager = LinearLayoutManager(context)
itemAnimator = DefaultItemAnimator()
adapter = playlistAdapter
}
override fun onCreateDialog(
savedInstanceState: Bundle?
): Dialog {
val cntx = requireContext()
val playlists = PlaylistLoader.getAllPlaylists(cntx).blockingFirst()
val playlistNames = arrayOfNulls<CharSequence>(playlists.size + 1)
playlistNames[0] = cntx.resources.getString(code.name.monkey.retromusic.R.string.action_new_playlist)
return MaterialAlertDialogBuilder(requireContext())
.setTitle(R.string.add_playlist_title)
.setItems(playlistNames) { dialog, which ->
val songs = arguments!!.getParcelableArrayList<Song>("songs") ?: return@setItems
if (which == 0) {
dialog.dismiss()
activity?.supportFragmentManager?.let { CreatePlaylistDialog.create(songs).show(it, "ADD_TO_PLAYLIST") }
} else {
dialog.dismiss()
PlaylistsUtil.addToPlaylist(cntx, songs, playlists[which - 1].id, true)
}
}
.create()
}
companion object {

View file

@ -35,7 +35,7 @@ open class MiniPlayerFragment : AbsMusicServiceFragment(), MusicProgressViewUpda
override fun onClick(view: View) {
when (view.id) {
R.id.actionPlayingQueue -> NavigationUtil.goToPlayingQueue(activity!!)
R.id.actionPlayingQueue -> NavigationUtil.goToPlayingQueue(requireActivity())
R.id.actionNext -> MusicPlayerRemote.playNextSong()
R.id.actionPrevious -> MusicPlayerRemote.back()
}
@ -44,8 +44,8 @@ open class MiniPlayerFragment : AbsMusicServiceFragment(), MusicProgressViewUpda
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
view.setBackgroundColor(ThemeStore.primaryColor(context!!))
view.setOnTouchListener(FlingPlayBackController(context!!))
view.setBackgroundColor(ThemeStore.primaryColor(requireContext()))
view.setOnTouchListener(FlingPlayBackController(requireContext()))
//view.setOnClickListener(v -> NavigationUtil.gotoNowPlayingActivity(getContext()));
setUpMiniPlayer()
@ -66,7 +66,7 @@ open class MiniPlayerFragment : AbsMusicServiceFragment(), MusicProgressViewUpda
private fun setUpMiniPlayer() {
setUpPlayPauseButton()
ViewUtil.setProgressDrawable(progressBar, ThemeStore.accentColor(context!!))
ViewUtil.setProgressDrawable(progressBar, ThemeStore.accentColor(requireContext()))
}
private fun setUpPlayPauseButton() {
@ -78,10 +78,10 @@ open class MiniPlayerFragment : AbsMusicServiceFragment(), MusicProgressViewUpda
val song = MusicPlayerRemote.currentSong
val title = SpannableString(song.title)
title.setSpan(ForegroundColorSpan(ThemeStore.textColorPrimary(context!!)), 0, title.length, 0)
title.setSpan(ForegroundColorSpan(ThemeStore.textColorPrimary(requireContext())), 0, title.length, 0)
val text = SpannableString(song.artistName)
text.setSpan(ForegroundColorSpan(ThemeStore.textColorSecondary(context!!)), 0, text.length, 0)
text.setSpan(ForegroundColorSpan(ThemeStore.textColorSecondary(requireContext())), 0, text.length, 0)
builder.append(title).append("").append(text)

View file

@ -111,6 +111,8 @@ class VolumeFragment : Fragment(), SeekBar.OnSeekBarChangeListener, OnAudioVolum
fun setTintable(color: Int) {
ViewUtil.setProgressDrawable(volumeSeekBar, color, true)
volumeDown.setColorFilter(Color.WHITE, PorterDuff.Mode.SRC_IN)
volumeUp.setColorFilter(Color.WHITE, PorterDuff.Mode.SRC_IN)
}
fun removeThumb() {

View file

@ -5,12 +5,14 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.viewpager.widget.ViewPager
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.adapter.album.AlbumCoverPagerAdapter
import code.name.monkey.retromusic.adapter.album.AlbumCoverPagerAdapter.AlbumCoverFragment
import code.name.monkey.retromusic.fragments.NowPlayingScreen
import code.name.monkey.retromusic.fragments.base.AbsMusicServiceFragment
import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.transform.CarousalPagerTransformer
import code.name.monkey.retromusic.transform.ParallaxPagerTransformer
import code.name.monkey.retromusic.adapter.album.AlbumCoverPagerAdapter
import code.name.monkey.retromusic.fragments.NowPlayingScreen
import code.name.monkey.retromusic.fragments.base.AbsMusicServiceFragment
import code.name.monkey.retromusic.util.PreferenceUtil
import kotlinx.android.synthetic.main.fragment_player_album_cover.*
@ -18,11 +20,9 @@ import kotlinx.android.synthetic.main.fragment_player_album_cover.*
class PlayerAlbumCoverFragment : AbsMusicServiceFragment(), ViewPager.OnPageChangeListener {
private var callbacks: Callbacks? = null
private var currentPosition: Int = 0
private val colorReceiver = object : AlbumCoverPagerAdapter.AlbumCoverFragment.ColorReceiver {
private val colorReceiver = object : AlbumCoverFragment.ColorReceiver {
override fun onColorReady(color: Int, request: Int) {
if (currentPosition == request) {
notifyColorChange(color)
@ -31,7 +31,7 @@ class PlayerAlbumCoverFragment : AbsMusicServiceFragment(), ViewPager.OnPageChan
}
fun removeSlideEffect() {
val transformer = ParallaxPagerTransformer(code.name.monkey.retromusic.R.id.player_image)
val transformer = ParallaxPagerTransformer(R.id.player_image)
transformer.setSpeed(0.3f)
viewPager.setPageTransformer(true, transformer)
@ -39,7 +39,7 @@ class PlayerAlbumCoverFragment : AbsMusicServiceFragment(), ViewPager.OnPageChan
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
return inflater.inflate(code.name.monkey.retromusic.R.layout.fragment_player_album_cover, container, false)
return inflater.inflate(R.layout.fragment_player_album_cover, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
@ -53,9 +53,9 @@ class PlayerAlbumCoverFragment : AbsMusicServiceFragment(), ViewPager.OnPageChan
(PreferenceUtil.getInstance().nowPlayingScreen == NowPlayingScreen.ADAPTIVE)
|| (PreferenceUtil.getInstance().nowPlayingScreen == NowPlayingScreen.FIT))) {
viewPager.clipToPadding = false
viewPager.setPadding(96, 0, 96, 0)
viewPager.pageMargin = 18
viewPager.setPageTransformer(false, CarousalPagerTransformer(context!!))
viewPager.setPadding(40, 40, 40, 0)
viewPager.pageMargin = 16
viewPager.setPageTransformer(false, CarousalPagerTransformer(requireContext()))
} else {
viewPager.offscreenPageLimit = 2
viewPager.setPageTransformer(true, PreferenceUtil.getInstance().albumCoverTransform)
@ -66,7 +66,6 @@ class PlayerAlbumCoverFragment : AbsMusicServiceFragment(), ViewPager.OnPageChan
override fun onDestroyView() {
super.onDestroyView()
viewPager.removeOnPageChangeListener(this)
}
@ -134,7 +133,6 @@ class PlayerAlbumCoverFragment : AbsMusicServiceFragment(), ViewPager.OnPageChan
}
companion object {
val TAG: String = PlayerAlbumCoverFragment::class.java.simpleName

View file

@ -12,19 +12,21 @@ import android.view.animation.DecelerateInterpolator
import android.view.animation.LinearInterpolator
import android.widget.SeekBar
import androidx.core.content.ContextCompat
import code.name.monkey.appthemehelper.ThemeStore
import code.name.monkey.appthemehelper.util.ColorUtil
import code.name.monkey.appthemehelper.util.MaterialValueHelper
import code.name.monkey.appthemehelper.util.TintHelper
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.extensions.ripAlpha
import code.name.monkey.retromusic.fragments.base.AbsPlayerControlsFragment
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.service.MusicService
import code.name.monkey.retromusic.fragments.base.AbsPlayerControlsFragment
import code.name.monkey.retromusic.util.MusicUtil
import code.name.monkey.retromusic.util.ViewUtil
import kotlinx.android.synthetic.main.fragment_player_playback_controls.*
import code.name.monkey.retromusic.util.PreferenceUtil
import kotlinx.android.synthetic.main.fragment_blur_player_playback_controls.*
import kotlinx.android.synthetic.main.media_button.*
@ -42,7 +44,7 @@ class BlurPlaybackControlsFragment : AbsPlayerControlsFragment() {
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_player_playback_controls, container, false)
return inflater.inflate(R.layout.fragment_blur_player_playback_controls, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
@ -57,13 +59,13 @@ class BlurPlaybackControlsFragment : AbsPlayerControlsFragment() {
}
showBonceAnimation()
}
text.isSelected = true
}
private fun updateSong() {
val song = MusicPlayerRemote.currentSong
title.text = song.title
text.text = song.artistName
text.text = "${song.artistName}${song.albumName}"
}
override fun onResume() {
@ -102,20 +104,28 @@ class BlurPlaybackControlsFragment : AbsPlayerControlsFragment() {
override fun setDark(color: Int) {
lastPlaybackControlsColor = Color.WHITE
lastDisabledPlaybackControlsColor = ContextCompat.getColor(context!!, R.color.md_grey_500)
lastDisabledPlaybackControlsColor = ContextCompat.getColor(requireContext(), R.color.md_grey_500)
title.setTextColor(lastPlaybackControlsColor)
text.setTextColor(lastDisabledPlaybackControlsColor)
setFabColor(lastPlaybackControlsColor)
ViewUtil.setProgressDrawable(progressSlider, lastPlaybackControlsColor)
songCurrentProgress.setTextColor(lastPlaybackControlsColor)
songTotalTime.setTextColor(lastPlaybackControlsColor)
updateRepeatState()
updateShuffleState()
updatePrevNextColor()
volumeFragment?.tintWhiteColor()
val colorFinal = if (PreferenceUtil.getInstance().adaptiveColor) {
color
} else {
ThemeStore.accentColor(requireContext())
}.ripAlpha()
text.setTextColor(colorFinal)
TintHelper.setTintAuto(progressSlider, colorFinal, false)
volumeFragment?.setTintable(colorFinal)
setFabColor(colorFinal)
}
private fun setFabColor(i: Int) {

View file

@ -17,6 +17,7 @@ package code.name.monkey.retromusic.transform
import android.content.Context
import android.view.View
import androidx.viewpager.widget.ViewPager
import kotlin.math.abs
class CarousalPagerTransformer(context: Context) : ViewPager.PageTransformer {
@ -35,8 +36,8 @@ class CarousalPagerTransformer(context: Context) : ViewPager.PageTransformer {
val leftInScreen = view.left - viewPager!!.scrollX
val centerXInViewPager = leftInScreen + view.measuredWidth / 2
val offsetX = centerXInViewPager - viewPager!!.measuredWidth / 2
val offsetRate = offsetX.toFloat() * 0.20f / viewPager!!.measuredWidth
val scaleFactor = 1 - Math.abs(offsetRate)
val offsetRate = offsetX.toFloat() * 0.30f / viewPager!!.measuredWidth
val scaleFactor = 1 - abs(offsetRate)
if (scaleFactor > 0) {
view.scaleX = scaleFactor
view.scaleY = scaleFactor

View file

@ -0,0 +1,38 @@
<?xml version="1.0" encoding="utf-8"?><!--
~ Copyright (c) 2019 Hemanth Savarala.
~
~ Licensed under the GNU General Public License v3
~
~ This is free software: you can redistribute it and/or modify it under
~ the terms of the GNU General Public License as published by
~ the Free Software Foundation either version 3 of the License, or (at your option) any later version.
~
~ This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
~ without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
~ See the GNU General Public License for more details.
-->
<code.name.monkey.retromusic.views.WidthFitSquareLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center">
<com.google.android.material.card.MaterialCardView
android:id="@+id/player_album_art_frame"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
app:cardCornerRadius="8dp">
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/player_image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
tools:ignore="ContentDescription,UnusedAttribute" />
</com.google.android.material.card.MaterialCardView>
</code.name.monkey.retromusic.views.WidthFitSquareLayout>

View file

@ -16,7 +16,7 @@
<View
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/shadow_up_strong" />
android:background="@drawable/shadow_up_full_theme" />
<View
android:id="@+id/mask"

View file

@ -0,0 +1,128 @@
<?xml version="1.0" encoding="utf-8"?><!--
~ Copyright (c) 2019 Hemanth Savarala.
~
~ Licensed under the GNU General Public License v3
~
~ This is free software: you can redistribute it and/or modify it under
~ the terms of the GNU General Public License as published by
~ the Free Software Foundation either version 3 of the License, or (at your option) any later version.
~
~ This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
~ without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
~ See the GNU General Public License for more details.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/playback_controls"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_vertical"
android:orientation="vertical"
tools:ignore="MissingPrefix">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0"
android:gravity="center"
android:orientation="vertical">
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:ellipsize="marquee"
android:focusable="true"
android:focusableInTouchMode="true"
android:freezesText="true"
android:gravity="center"
android:marqueeRepeatLimit="marquee_forever"
android:paddingStart="16dp"
android:paddingEnd="16dp"
android:scrollHorizontally="true"
android:singleLine="true"
android:textColor="@color/md_white_1000"
android:textSize="22sp"
tools:text="Title" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:ellipsize="marquee"
android:focusable="true"
android:focusableInTouchMode="true"
android:freezesText="true"
android:gravity="center"
android:marqueeRepeatLimit="marquee_forever"
android:paddingStart="16dp"
android:paddingEnd="16dp"
android:scrollHorizontally="true"
android:singleLine="true"
android:textAppearance="@style/TextAppearance.MaterialComponents.Caption"
android:textColor="?android:attr/textColorSecondary" />
</LinearLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="28dp"
android:paddingStart="12dp"
android:layout_marginTop="12dp"
android:paddingEnd="12dp">
<androidx.appcompat.widget.AppCompatSeekBar
android:id="@+id/progressSlider"
style="@style/Widget.MaterialProgressBar.ProgressBar.Horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:layout_toLeftOf="@id/songTotalTime"
android:layout_toRightOf="@id/songCurrentProgress"
android:maxHeight="1.5dp"
android:progressDrawable="@drawable/color_progress_seek"
android:splitTrack="false"
tools:ignore="RtlHardcoded,UnusedAttribute"
tools:progress="20" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/songTotalTime"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_alignParentRight="true"
android:fontFamily="sans-serif-medium"
android:gravity="center_vertical|right|end"
android:paddingRight="8dp"
android:singleLine="true"
android:textAppearance="@style/TextAppearance.AppCompat.Title"
android:textColor="?android:textColorSecondary"
android:textSize="12sp"
tools:ignore="RtlHardcoded,RtlSymmetry" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/songCurrentProgress"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_alignParentLeft="true"
android:fontFamily="sans-serif-medium"
android:gravity="center_vertical|left|end"
android:paddingLeft="8dp"
android:singleLine="true"
android:textAppearance="@style/TextAppearance.AppCompat.Title"
android:textColor="?android:textColorSecondary"
android:textSize="12sp"
tools:ignore="RtlHardcoded,RtlSymmetry" />
</RelativeLayout>
<include layout="@layout/media_button" />
<FrameLayout
android:id="@+id/volumeFragmentContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0"
android:paddingStart="8dp"
android:paddingEnd="8dp" />
</LinearLayout>