mirror of
https://github.com/libre-tube/LibreTube.git
synced 2024-12-13 22:00:30 +05:30
Merge pull request #3335 from Bnyro/audio-mini-player
Audio mini player
This commit is contained in:
commit
a5f44c4e25
@ -18,6 +18,7 @@ import com.github.libretube.constants.PreferenceKeys
|
||||
import com.github.libretube.enums.PlaylistType
|
||||
import com.github.libretube.extensions.toID
|
||||
import com.github.libretube.ui.activities.MainActivity
|
||||
import com.github.libretube.ui.fragments.AudioPlayerFragment
|
||||
import com.github.libretube.ui.fragments.PlayerFragment
|
||||
import com.github.libretube.ui.views.SingleViewTouchableMotionLayout
|
||||
|
||||
@ -117,7 +118,9 @@ object NavigationHelper {
|
||||
*/
|
||||
fun startAudioPlayer(context: Context) {
|
||||
val activity = unwrap(context)
|
||||
activity.navController.navigate(R.id.audioPlayerFragment)
|
||||
activity.supportFragmentManager.commitNow {
|
||||
replace<AudioPlayerFragment>(R.id.container)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -362,7 +362,7 @@ class MainActivity : BaseActivity() {
|
||||
true
|
||||
}
|
||||
R.id.action_audio -> {
|
||||
navController.navigate(R.id.audioPlayerFragment)
|
||||
NavigationHelper.startAudioPlayer(this)
|
||||
true
|
||||
}
|
||||
else -> super.onOptionsItemSelected(item)
|
||||
|
@ -13,7 +13,10 @@ import android.text.format.DateUtils
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.constraintlayout.motion.widget.MotionLayout
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.activityViewModels
|
||||
import androidx.fragment.app.commit
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import com.github.libretube.R
|
||||
import com.github.libretube.api.obj.StreamItem
|
||||
@ -31,14 +34,22 @@ import com.github.libretube.ui.activities.MainActivity
|
||||
import com.github.libretube.ui.dialogs.ShareDialog
|
||||
import com.github.libretube.ui.interfaces.AudioPlayerOptions
|
||||
import com.github.libretube.ui.listeners.AudioPlayerThumbnailListener
|
||||
import com.github.libretube.ui.models.PlayerViewModel
|
||||
import com.github.libretube.ui.sheets.PlaybackOptionsSheet
|
||||
import com.github.libretube.ui.sheets.PlayingQueueSheet
|
||||
import com.github.libretube.ui.sheets.VideoOptionsBottomSheet
|
||||
import com.github.libretube.util.PlayingQueue
|
||||
import kotlin.math.abs
|
||||
|
||||
class AudioPlayerFragment : Fragment(), AudioPlayerOptions {
|
||||
private lateinit var binding: FragmentAudioPlayerBinding
|
||||
private lateinit var audioHelper: AudioHelper
|
||||
private val mainActivity get() = context as MainActivity
|
||||
private val viewModel: PlayerViewModel by activityViewModels()
|
||||
|
||||
// for the transition
|
||||
private var sId: Int = 0
|
||||
private var eId: Int = 0
|
||||
|
||||
private val onTrackChangeListener: (StreamItem) -> Unit = {
|
||||
updateStreamInfo()
|
||||
@ -57,16 +68,7 @@ class AudioPlayerFragment : Fragment(), AudioPlayerOptions {
|
||||
handleServiceConnection()
|
||||
}
|
||||
|
||||
override fun onServiceDisconnected(arg0: ComponentName) {
|
||||
val mainActivity = activity as MainActivity
|
||||
if (mainActivity.navController.currentDestination?.id == R.id.audioPlayerFragment) {
|
||||
mainActivity.navController.popBackStack()
|
||||
} else {
|
||||
mainActivity.navController.backQueue.removeIf {
|
||||
it.destination.id == R.id.audioPlayerFragment
|
||||
}
|
||||
}
|
||||
}
|
||||
override fun onServiceDisconnected(arg0: ComponentName) {}
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
@ -91,6 +93,8 @@ class AudioPlayerFragment : Fragment(), AudioPlayerOptions {
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
initializeTransitionLayout()
|
||||
|
||||
// select the title TV in order for it to automatically scroll
|
||||
binding.title.isSelected = true
|
||||
binding.uploader.isSelected = true
|
||||
@ -142,7 +146,13 @@ class AudioPlayerFragment : Fragment(), AudioPlayerOptions {
|
||||
binding.close.setOnClickListener {
|
||||
activity?.unbindService(connection)
|
||||
BackgroundHelper.stopBackgroundPlay(requireContext())
|
||||
findNavController().popBackStack()
|
||||
killFragment()
|
||||
}
|
||||
|
||||
binding.miniPlayerClose.setOnClickListener {
|
||||
activity?.unbindService(connection)
|
||||
BackgroundHelper.stopBackgroundPlay(requireContext())
|
||||
killFragment()
|
||||
}
|
||||
|
||||
val listener = AudioPlayerThumbnailListener(requireContext(), this)
|
||||
@ -155,6 +165,10 @@ class AudioPlayerFragment : Fragment(), AudioPlayerOptions {
|
||||
if (isPaused) playerService?.play() else playerService?.pause()
|
||||
}
|
||||
|
||||
binding.miniPlayerPause.setOnClickListener {
|
||||
if (isPaused) playerService?.play() else playerService?.pause()
|
||||
}
|
||||
|
||||
// load the stream info into the UI
|
||||
updateStreamInfo()
|
||||
|
||||
@ -164,6 +178,63 @@ class AudioPlayerFragment : Fragment(), AudioPlayerOptions {
|
||||
}
|
||||
}
|
||||
|
||||
private fun killFragment() {
|
||||
viewModel.isFullscreen.value = false
|
||||
binding.playerMotionLayout.transitionToEnd()
|
||||
mainActivity.supportFragmentManager.commit {
|
||||
remove(this@AudioPlayerFragment)
|
||||
}
|
||||
|
||||
onDestroy()
|
||||
}
|
||||
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
private fun initializeTransitionLayout() {
|
||||
mainActivity.binding.container.visibility = View.VISIBLE
|
||||
val mainMotionLayout = mainActivity.binding.mainMotionLayout
|
||||
|
||||
binding.playerMotionLayout.addTransitionListener(object : MotionLayout.TransitionListener {
|
||||
override fun onTransitionStarted(
|
||||
motionLayout: MotionLayout?,
|
||||
startId: Int,
|
||||
endId: Int
|
||||
) {
|
||||
}
|
||||
|
||||
override fun onTransitionChange(
|
||||
motionLayout: MotionLayout?,
|
||||
startId: Int,
|
||||
endId: Int,
|
||||
progress: Float
|
||||
) {
|
||||
mainMotionLayout.progress = abs(progress)
|
||||
eId = endId
|
||||
sId = startId
|
||||
}
|
||||
|
||||
override fun onTransitionCompleted(motionLayout: MotionLayout?, currentId: Int) {
|
||||
if (currentId == eId) {
|
||||
viewModel.isMiniPlayerVisible.value = true
|
||||
mainMotionLayout.progress = 1F
|
||||
} else if (currentId == sId) {
|
||||
viewModel.isMiniPlayerVisible.value = false
|
||||
mainMotionLayout.progress = 0F
|
||||
}
|
||||
}
|
||||
|
||||
override fun onTransitionTrigger(
|
||||
MotionLayout: MotionLayout?,
|
||||
triggerId: Int,
|
||||
positive: Boolean,
|
||||
progress: Float
|
||||
) {
|
||||
}
|
||||
})
|
||||
|
||||
binding.playerMotionLayout.progress = 1.toFloat()
|
||||
binding.playerMotionLayout.transitionToStart()
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the information from a new stream into the UI
|
||||
*/
|
||||
@ -172,6 +243,8 @@ class AudioPlayerFragment : Fragment(), AudioPlayerOptions {
|
||||
current ?: return
|
||||
|
||||
binding.title.text = current.title
|
||||
binding.miniPlayerTitle.text = current.title
|
||||
|
||||
binding.uploader.text = current.uploaderName
|
||||
binding.uploader.setOnClickListener {
|
||||
NavigationHelper.navigateChannel(requireContext(), current.uploaderUrl?.toID())
|
||||
@ -188,6 +261,7 @@ class AudioPlayerFragment : Fragment(), AudioPlayerOptions {
|
||||
|
||||
ImageHelper.getAsync(requireContext(), thumbnailUrl) {
|
||||
binding.thumbnail.setImageBitmap(it)
|
||||
binding.miniPlayerThumbnail.setImageBitmap(it)
|
||||
binding.thumbnail.visibility = View.VISIBLE
|
||||
binding.progress.visibility = View.GONE
|
||||
}
|
||||
@ -232,9 +306,9 @@ class AudioPlayerFragment : Fragment(), AudioPlayerOptions {
|
||||
|
||||
private fun handleServiceConnection() {
|
||||
playerService?.onIsPlayingChanged = { isPlaying ->
|
||||
binding.playPause.setIconResource(
|
||||
if (isPlaying) R.drawable.ic_pause else R.drawable.ic_play
|
||||
)
|
||||
val iconResource = if (isPlaying) R.drawable.ic_pause else R.drawable.ic_play
|
||||
binding.playPause.setIconResource(iconResource)
|
||||
binding.miniPlayerPause.setImageResource(iconResource)
|
||||
isPaused = !isPlaying
|
||||
}
|
||||
initializeSeekBar()
|
||||
|
@ -14,7 +14,7 @@ class SingleViewTouchableMotionLayout(context: Context, attributeSet: AttributeS
|
||||
MotionLayout(context, attributeSet) {
|
||||
|
||||
private val viewToDetectTouch by lazy {
|
||||
findViewById<View>(R.id.main_container) // TODO move to Attributes
|
||||
findViewById<View>(R.id.main_container) ?: findViewById(R.id.audio_player_container)
|
||||
}
|
||||
private val viewRect = Rect()
|
||||
private var touchStarted = false
|
||||
|
@ -1,204 +1,275 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<com.github.libretube.ui.views.SingleViewTouchableMotionLayout 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/playerMotionLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
app:layoutDescription="@xml/audio_player_scene">
|
||||
|
||||
<FrameLayout
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/audio_player_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1">
|
||||
android:layout_height="match_parent"
|
||||
android:background="?android:attr/colorBackground"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<com.google.android.material.imageview.ShapeableImageView
|
||||
android:id="@+id/thumbnail"
|
||||
<LinearLayout
|
||||
android:id="@+id/audio_player_main"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
app:layout_constraintBottom_toBottomOf="@id/audio_player_container"
|
||||
app:layout_constraintEnd_toEndOf="@id/audio_player_container"
|
||||
app:layout_constraintStart_toStartOf="@id/audio_player_container"
|
||||
app:layout_constraintTop_toTopOf="@id/audio_player_container">
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginHorizontal="20dp"
|
||||
android:layout_marginVertical="10dp"
|
||||
android:adjustViewBounds="true"
|
||||
android:scaleType="fitCenter"
|
||||
app:shapeAppearanceOverlay="@style/ShapeAppearance.Material3.Corner.Small"
|
||||
tools:src="@tools:sample/backgrounds/scenic" />
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/volumeControls"
|
||||
android:layout_width="42dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:background="@drawable/controls_layout_bg"
|
||||
android:orientation="vertical"
|
||||
android:visibility="gone"
|
||||
tools:ignore="RtlHardcoded">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/volume_textView"
|
||||
style="@style/SwipeControlString"
|
||||
<com.google.android.material.imageview.ShapeableImageView
|
||||
android:id="@+id/thumbnail"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
app:autoSizeTextType="uniform" />
|
||||
android:layout_marginHorizontal="20dp"
|
||||
android:layout_marginVertical="10dp"
|
||||
android:adjustViewBounds="true"
|
||||
android:scaleType="fitCenter"
|
||||
app:shapeAppearanceOverlay="@style/ShapeAppearance.Material3.Corner.Small"
|
||||
tools:src="@tools:sample/backgrounds/scenic" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/volumeControls"
|
||||
android:layout_width="42dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:background="@drawable/controls_layout_bg"
|
||||
android:orientation="vertical"
|
||||
android:visibility="gone"
|
||||
tools:ignore="RtlHardcoded">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/volume_textView"
|
||||
style="@style/SwipeControlString"
|
||||
android:layout_gravity="center"
|
||||
app:autoSizeTextType="uniform" />
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/volume_progressBar"
|
||||
style="@android:style/Widget.ProgressBar.Horizontal"
|
||||
android:layout_width="7dp"
|
||||
android:layout_height="100dp"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginVertical="4dp"
|
||||
android:progressDrawable="@drawable/vertical_progressbar" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/volume_imageView"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:layout_gravity="center"
|
||||
android:contentDescription="@string/volume"
|
||||
android:src="@drawable/ic_volume_up" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/volume_progressBar"
|
||||
style="@android:style/Widget.ProgressBar.Horizontal"
|
||||
android:layout_width="7dp"
|
||||
android:layout_height="100dp"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginVertical="4dp"
|
||||
android:progressDrawable="@drawable/vertical_progressbar" />
|
||||
android:id="@+id/progress"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/volume_imageView"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:layout_gravity="center"
|
||||
android:contentDescription="@string/volume"
|
||||
android:src="@drawable/ic_volume_up" />
|
||||
</FrameLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="20dp"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/title"
|
||||
style="@style/TextViewMarquee"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="24sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/uploader"
|
||||
style="@style/TextViewMarquee"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="10dp"
|
||||
android:textSize="18sp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/progress"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center" />
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="20dp"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/title"
|
||||
style="@style/TextViewMarquee"
|
||||
<com.google.android.material.slider.Slider
|
||||
android:id="@+id/time_bar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="24sp" />
|
||||
android:layout_marginHorizontal="20dp"
|
||||
app:labelBehavior="gone" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/uploader"
|
||||
style="@style/TextViewMarquee"
|
||||
<FrameLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="10dp"
|
||||
android:textSize="18sp" />
|
||||
android:paddingHorizontal="20dp">
|
||||
|
||||
</LinearLayout>
|
||||
<TextView
|
||||
android:id="@+id/current_position"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="start|center"
|
||||
tools:text="00:00" />
|
||||
|
||||
<com.google.android.material.slider.Slider
|
||||
android:id="@+id/time_bar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="20dp"
|
||||
app:labelBehavior="gone" />
|
||||
<TextView
|
||||
android:id="@+id/duration"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="end|center"
|
||||
tools:text="10:15" />
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingHorizontal="20dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/current_position"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="start|center"
|
||||
tools:text="00:00" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/duration"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="end|center"
|
||||
tools:text="10:15" />
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginTop="10dp"
|
||||
android:layout_marginBottom="36dp">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/prev"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginHorizontal="20dp"
|
||||
android:background="?attr/selectableItemBackgroundBorderless"
|
||||
android:src="@drawable/ic_prev" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/play_pause"
|
||||
android:layout_width="72dp"
|
||||
android:layout_height="72dp"
|
||||
android:insetLeft="0dp"
|
||||
android:insetTop="0dp"
|
||||
android:insetRight="0dp"
|
||||
android:insetBottom="0dp"
|
||||
app:icon="@drawable/ic_pause"
|
||||
app:iconSize="24dp"
|
||||
app:shapeAppearanceOverlay="@style/ShapeAppearance.Material3.Corner.Full" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/next"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginHorizontal="20dp"
|
||||
android:background="?attr/selectableItemBackgroundBorderless"
|
||||
android:src="@drawable/ic_next" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<com.google.android.material.card.MaterialCardView
|
||||
style="@style/Widget.Material3.CardView.Elevated"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginBottom="30dp"
|
||||
app:cardCornerRadius="18dp">
|
||||
</FrameLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:padding="15dp">
|
||||
android:layout_marginTop="10dp"
|
||||
android:layout_marginBottom="36dp">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/open_queue"
|
||||
style="@style/AudioPlayerButton"
|
||||
android:src="@drawable/ic_queue" />
|
||||
android:id="@+id/prev"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginHorizontal="20dp"
|
||||
android:background="?attr/selectableItemBackgroundBorderless"
|
||||
android:src="@drawable/ic_prev" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/play_pause"
|
||||
android:layout_width="72dp"
|
||||
android:layout_height="72dp"
|
||||
android:insetLeft="0dp"
|
||||
android:insetTop="0dp"
|
||||
android:insetRight="0dp"
|
||||
android:insetBottom="0dp"
|
||||
app:icon="@drawable/ic_pause"
|
||||
app:iconSize="24dp"
|
||||
app:shapeAppearanceOverlay="@style/ShapeAppearance.Material3.Corner.Full" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/playback_options"
|
||||
style="@style/AudioPlayerButton"
|
||||
android:layout_width="27dp"
|
||||
android:layout_height="27dp"
|
||||
android:src="@drawable/ic_speed" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/open_video"
|
||||
style="@style/AudioPlayerButton"
|
||||
android:src="@drawable/ic_video" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/share"
|
||||
style="@style/AudioPlayerButton"
|
||||
android:src="@drawable/ic_share" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/close"
|
||||
style="@style/AudioPlayerButton"
|
||||
android:src="@drawable/ic_close" />
|
||||
android:id="@+id/next"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginHorizontal="20dp"
|
||||
android:background="?attr/selectableItemBackgroundBorderless"
|
||||
android:src="@drawable/ic_next" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</com.google.android.material.card.MaterialCardView>
|
||||
<com.google.android.material.card.MaterialCardView
|
||||
style="@style/Widget.Material3.CardView.Elevated"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginBottom="30dp"
|
||||
app:cardCornerRadius="18dp">
|
||||
|
||||
</LinearLayout>
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:padding="15dp">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/open_queue"
|
||||
style="@style/AudioPlayerButton"
|
||||
android:src="@drawable/ic_queue" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/playback_options"
|
||||
style="@style/AudioPlayerButton"
|
||||
android:layout_width="27dp"
|
||||
android:layout_height="27dp"
|
||||
android:src="@drawable/ic_speed" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/open_video"
|
||||
style="@style/AudioPlayerButton"
|
||||
android:src="@drawable/ic_video" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/share"
|
||||
style="@style/AudioPlayerButton"
|
||||
android:src="@drawable/ic_share" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/close"
|
||||
style="@style/AudioPlayerButton"
|
||||
android:src="@drawable/ic_close" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</com.google.android.material.card.MaterialCardView>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/miniPlayerControls"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="54dp"
|
||||
android:alpha="0"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintBottom_toBottomOf="@id/audio_player_container"
|
||||
app:layout_constraintEnd_toEndOf="@id/audio_player_container"
|
||||
app:layout_constraintStart_toStartOf="@id/audio_player_container"
|
||||
app:layout_constraintTop_toTopOf="@id/audio_player_container">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/miniPlayerThumbnail"
|
||||
android:layout_width="96dp"
|
||||
android:layout_height="match_parent"
|
||||
android:background="?attr/selectableItemBackgroundBorderless"
|
||||
android:padding="8dp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/miniPlayerTitle"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:layout_weight="1"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:paddingHorizontal="8dp"
|
||||
android:paddingVertical="15dp" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/miniPlayerPause"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:background="?attr/selectableItemBackgroundBorderless"
|
||||
android:padding="8dp"
|
||||
android:src="@drawable/ic_pause" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/miniPlayerClose"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:background="?attr/selectableItemBackgroundBorderless"
|
||||
android:padding="8dp"
|
||||
android:src="@drawable/ic_close" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</com.github.libretube.ui.views.SingleViewTouchableMotionLayout>
|
@ -54,9 +54,4 @@
|
||||
android:name="com.github.libretube.ui.fragments.DownloadsFragment"
|
||||
android:label="@string/downloads"
|
||||
tools:layout="@layout/fragment_downloads" />
|
||||
<fragment
|
||||
android:id="@+id/audioPlayerFragment"
|
||||
android:name="com.github.libretube.ui.fragments.AudioPlayerFragment"
|
||||
android:label="@string/audio_player"
|
||||
tools:layout="@layout/fragment_audio_player" />
|
||||
</navigation>
|
67
app/src/main/res/xml/audio_player_scene.xml
Normal file
67
app/src/main/res/xml/audio_player_scene.xml
Normal file
@ -0,0 +1,67 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<MotionScene xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:motion="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<Transition
|
||||
android:id="@+id/mini_player_transition"
|
||||
motion:constraintSetEnd="@+id/end"
|
||||
motion:constraintSetStart="@id/start"
|
||||
motion:duration="500"
|
||||
motion:motionInterpolator="easeInOut">
|
||||
<KeyFrameSet>
|
||||
<KeyAttribute
|
||||
android:alpha="0"
|
||||
motion:framePosition="90"
|
||||
motion:motionTarget="@+id/miniPlayerControls" />
|
||||
</KeyFrameSet>
|
||||
<OnSwipe
|
||||
motion:dragDirection="dragDown"
|
||||
motion:dragScale="6"
|
||||
motion:maxAcceleration="40"
|
||||
motion:touchAnchorId="@+id/audio_player_container"
|
||||
motion:touchAnchorSide="bottom" />
|
||||
</Transition>
|
||||
|
||||
<ConstraintSet android:id="@+id/start">
|
||||
<Constraint
|
||||
android:id="@+id/audio_player_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
motion:layout_constraintBottom_toBottomOf="parent"
|
||||
motion:layout_constraintEnd_toEndOf="parent"
|
||||
motion:layout_constraintStart_toStartOf="parent"
|
||||
motion:layout_constraintTop_toTopOf="parent" />
|
||||
</ConstraintSet>
|
||||
|
||||
<ConstraintSet android:id="@+id/end">
|
||||
<Constraint
|
||||
android:id="@+id/audio_player_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="54dp"
|
||||
motion:layout_constraintBottom_toBottomOf="parent"
|
||||
motion:layout_constraintEnd_toEndOf="parent"
|
||||
motion:layout_constraintHorizontal_bias="0.5"
|
||||
motion:layout_constraintStart_toStartOf="parent"
|
||||
motion:layout_constraintTop_toTopOf="parent"
|
||||
motion:layout_constraintVertical_bias="1.0" />
|
||||
<Constraint
|
||||
android:id="@+id/audio_player_main"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="1dp"
|
||||
motion:layout_constraintBottom_toBottomOf="parent"
|
||||
motion:layout_constraintEnd_toEndOf="parent"
|
||||
motion:layout_constraintStart_toStartOf="parent"
|
||||
motion:layout_constraintTop_toBottomOf="@+id/main_container" />
|
||||
<Constraint
|
||||
android:id="@+id/miniPlayerControls"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="54dp"
|
||||
android:alpha="1"
|
||||
android:paddingEnd="16dp"
|
||||
android:visibility="visible"
|
||||
motion:layout_constraintBottom_toBottomOf="@+id/audio_player_container"
|
||||
motion:layout_constraintEnd_toEndOf="@id/audio_player_container"
|
||||
motion:layout_constraintStart_toStartOf="@id/audio_player_container"
|
||||
motion:layout_constraintTop_toTopOf="@+id/audio_player_container" />
|
||||
</ConstraintSet>
|
||||
</MotionScene>
|
@ -31,34 +31,6 @@
|
||||
</Transition>
|
||||
|
||||
<ConstraintSet android:id="@+id/start">
|
||||
<Constraint
|
||||
android:id="@+id/player"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
motion:layout_constraintBottom_toBottomOf="@id/main_container"
|
||||
motion:layout_constraintStart_toStartOf="@id/main_container"
|
||||
motion:layout_constraintTop_toTopOf="@id/main_container" />
|
||||
<Constraint
|
||||
android:id="@+id/player"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
motion:layout_constraintBottom_toBottomOf="@id/main_container"
|
||||
motion:layout_constraintStart_toStartOf="@id/main_container"
|
||||
motion:layout_constraintTop_toTopOf="@id/main_container" />
|
||||
<Constraint
|
||||
android:id="@+id/player"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
motion:layout_constraintBottom_toBottomOf="@id/main_container"
|
||||
motion:layout_constraintStart_toStartOf="@id/main_container"
|
||||
motion:layout_constraintTop_toTopOf="@id/main_container" />
|
||||
<Constraint
|
||||
android:id="@+id/player"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
motion:layout_constraintBottom_toBottomOf="@id/main_container"
|
||||
motion:layout_constraintStart_toStartOf="@id/main_container"
|
||||
motion:layout_constraintTop_toTopOf="@id/main_container" />
|
||||
<Constraint
|
||||
android:id="@+id/player"
|
||||
android:layout_width="match_parent"
|
||||
|
Loading…
Reference in New Issue
Block a user