Browse Source

Audio player redesign

merge-requests/213/head
Nicolas Pomepuy 7 years ago
parent
commit
8afbde0137
  1. 12
      tools/src/main/java/org/videolan/tools/KotlinExtensions.kt
  2. 154
      vlc-android/res/layout/audio_player.xml
  3. 4
      vlc-android/res/layout/playlist_item.xml
  4. 1
      vlc-android/res/values/attrs.xml
  5. 2
      vlc-android/res/values/colors.xml
  6. 4
      vlc-android/res/values/styles.xml
  7. 4
      vlc-android/src/org/videolan/vlc/gui/audio/AudioPlayer.kt
  8. 3
      vlc-android/src/org/videolan/vlc/gui/audio/PlaylistAdapter.kt
  9. 7
      vlc-android/src/org/videolan/vlc/gui/helpers/UiTools.kt
  10. 8
      vlc-android/src/org/videolan/vlc/media/MediaUtils.kt

12
tools/src/main/java/org/videolan/tools/KotlinExtensions.kt

@ -1,7 +1,10 @@
package org.videolan.tools
import android.content.Context
import android.content.res.Resources
import android.util.TypedValue
import android.view.View
import androidx.annotation.AttrRes
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleObserver
import androidx.lifecycle.LifecycleOwner
@ -59,3 +62,12 @@ fun CoroutineScope.conflatedActor(time: Long = 2000L, action: () -> Unit) = acto
delay(time)
}
}
fun Context.getColorFromAttr(
@AttrRes attrColor: Int,
typedValue: TypedValue = TypedValue(),
resolveRefs: Boolean = true
): Int {
theme.resolveAttribute(attrColor, typedValue, resolveRefs)
return typedValue.data
}

154
vlc-android/res/layout/audio_player.xml

@ -185,21 +185,20 @@
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/songs_list"
android:layout_width="0dp"
android:layout_height="0dp"
android:maxWidth="800dp"
app:layout_constraintTop_toBottomOf="@+id/header"
app:layout_constraintBottom_toTopOf="@+id/play_pause"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
android:layout_centerHorizontal="true"
android:clipToPadding="false"
android:visibility="@{showCover ? View.GONE : View.VISIBLE}"
android:layout_gravity="center_horizontal"
android:background="?attr/background_default"
android:layout_marginBottom="@dimen/audio_player_cover_margin"
android:paddingBottom="@dimen/listview_bottom_padding" />
android:id="@+id/songs_list"
android:layout_width="0dp"
android:layout_height="0dp"
android:maxWidth="800dp"
app:layout_constraintTop_toBottomOf="@+id/header"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
android:layout_centerHorizontal="true"
android:clipToPadding="false"
android:visibility="@{showCover ? View.GONE : View.VISIBLE}"
android:layout_gravity="center_horizontal"
android:background="?attr/background_default"
android:paddingBottom="@dimen/listview_bottom_padding"
app:layout_constraintBottom_toTopOf="@+id/bottom_bar"/>
<org.videolan.vlc.gui.view.CoverMediaSwitcher
android:id="@+id/cover_media_switcher"
@ -221,59 +220,66 @@
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/header" />
<include
layout="@layout/shadow_bottom"
android:layout_width="0dp"
android:layout_height="6dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toTopOf="@+id/play_pause"
android:layout_marginBottom="@dimen/audio_player_cover_margin"
android:id="@+id/include"/>
<View
android:layout_width="0dp"
android:layout_height="72dp"
android:id="@+id/bottom_bar"
android:background="?attr/audio_player_transparent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toBottomOf="@+id/backgroundView"
/>
<TextView
android:id="@+id/time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center|start"
android:layout_marginStart="@dimen/default_margin"
android:clickable="true"
android:focusable="true"
android:onClick="@{fragment::onTimeLabelClick}"
android:text="@string/time_0"
android:textSize="12sp"
app:layout_constraintBottom_toTopOf="@+id/timeline"
app:layout_constraintStart_toStartOf="parent" />
android:id="@+id/time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center|start"
android:layout_marginStart="@dimen/default_margin"
android:clickable="true"
android:focusable="true"
android:onClick="@{fragment::onTimeLabelClick}"
android:textColor="?attr/font_audio_light"
android:text="@string/time_0"
android:textSize="12sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/length"
app:layout_constraintBottom_toBottomOf="@+id/length"/>
<SeekBar
android:id="@+id/timeline"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:layout_marginTop="@dimen/half_default_margin"
android:focusable="true"
android:maxHeight="1dip"
android:minHeight="1dip"
android:paddingLeft="@dimen/half_default_margin"
android:paddingRight="@dimen/half_default_margin"
android:progressDrawable="@drawable/po_seekbar"
android:splitTrack="false"
android:thumb="@drawable/seekbar_thumb"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
android:id="@+id/timeline"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:focusable="true"
android:maxHeight="1dip"
android:minHeight="1dip"
android:paddingEnd="0dp"
android:paddingStart="0dp"
android:padding="0dp"
android:progressDrawable="@drawable/po_seekbar"
android:splitTrack="false"
android:thumb="@drawable/seekbar_thumb"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
android:layout_marginBottom="8dp"
app:layout_constraintBottom_toTopOf="@+id/bottom_bar"
app:layout_constraintTop_toTopOf="@+id/bottom_bar"/>
<TextView
android:id="@+id/length"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center|end"
android:layout_marginEnd="@dimen/default_margin"
android:contentDescription="@string/length"
android:text="@string/time_0"
android:textSize="12sp"
app:layout_constraintBottom_toTopOf="@+id/timeline"
app:layout_constraintEnd_toEndOf="parent" />
android:id="@+id/length"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center|end"
android:layout_marginEnd="@dimen/default_margin"
android:contentDescription="@string/length"
android:textColor="?attr/font_audio_light"
android:text="@string/time_0"
android:textSize="12sp"
app:layout_constraintBottom_toTopOf="@+id/repeat"
app:layout_constraintEnd_toEndOf="parent"
/>
<ImageView
android:id="@+id/shuffle"
@ -306,18 +312,18 @@
app:srcCompat="@drawable/ic_repeat"/>
<ImageView
android:id="@+id/play_pause"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_marginBottom="@dimen/audioplayer_controls_margin"
android:contentDescription="@string/play"
android:focusable="true"
android:onClick="@{fragment::onPlayPauseClick}"
android:onLongClick="@{fragment::onStopClick}"
android:scaleType="fitXY"
app:layout_constraintBottom_toTopOf="@+id/time"
app:layout_constraintLeft_toRightOf="@+id/previous"
app:layout_constraintRight_toLeftOf="@+id/next" />
android:id="@+id/play_pause"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_marginBottom="8dp"
android:contentDescription="@string/play"
android:focusable="true"
android:onClick="@{fragment::onPlayPauseClick}"
android:onLongClick="@{fragment::onStopClick}"
android:scaleType="fitXY"
app:layout_constraintLeft_toRightOf="@+id/previous"
app:layout_constraintRight_toLeftOf="@+id/next"
app:layout_constraintBottom_toBottomOf="@+id/backgroundView"/>
<ImageView
android:id="@+id/next"

4
vlc-android/res/layout/playlist_item.xml

@ -92,7 +92,7 @@
android:singleLine="true"
android:ellipsize="middle"
android:text="@{media.title}"
android:textSize="16sp"
android:textSize="14sp"
android:textColor="?attr/font_default"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintHorizontal_bias="0.5"
@ -113,7 +113,7 @@
android:paddingRight="8dp"
android:singleLine="true"
android:ellipsize="middle"
android:textColor="?attr/font_default"
android:textColor="?attr/font_audio_light"
android:fontFamily="sans-serif"
android:textSize="12sp"
android:visibility="@{TextUtils.isEmpty(subTitle) ? View.GONE : View.VISIBLE}"

1
vlc-android/res/values/attrs.xml

@ -23,6 +23,7 @@
<attr name="audio_browser_separator" format="reference|color" />
<attr name="playlist_item_drag_shadow" format="reference|color" />
<attr name="audio_player_header_time" format="reference|color" />
<attr name="audio_player_transparent" format="reference|color"/>
<attr name="list_menu" format="reference|color" />
<attr name="list_subtitle" format="reference|color" />
<attr name="list_title_last" format="reference|color" />

2
vlc-android/res/values/colors.xml

@ -52,6 +52,8 @@
<color name="whitetransparent">#b4ffffff</color>
<color name="ripple_white">#88ffffff</color>
<color name="white_more_transparent">#33ffffff</color>
<color name="white_audio_player_transparent">#aaffffff</color>
<color name="black_audio_player_transparent">#ee2a2a2a</color>
<color name="transparent">#00000000</color>
<color name="white_selection_transparent">#44ffffff</color>

4
vlc-android/res/values/styles.xml

@ -39,6 +39,7 @@
<item name="background_header">@color/grey300</item>
<item name="background_audio_tips">@color/grey50transparent</item>
<item name="audio_player_background_tint">@color/whitetransparent</item>
<item name="audio_player_transparent">@color/white_audio_player_transparent</item>
<item name="audio_browser_separator">@color/orange500</item>
<item name="playlist_item_drag_shadow">@color/orange500</item>
<item name="audio_player_header_time">@color/orange500</item>
@ -88,7 +89,7 @@
<item name="ic_abrepeat_setb">@drawable/ic_abrepeat_setb</item>
<item name="ic_abrepeat_reset">@drawable/ic_abrepeat_reset</item>
<item name="ic_dial">@drawable/ic_dial</item>
<item name="progress_background">@color/grey300</item>
<item name="progress_background">@color/grey400</item>
<item name="ariane_text_color">@color/grey50</item>
<item name="player_icon_color">@color/black</item>
</style>
@ -141,6 +142,7 @@
<item name="background_header">@color/grey900</item>
<item name="background_audio_tips">@color/grey900transparent</item>
<item name="audio_player_background_tint">@color/grey900transparent</item>
<item name="audio_player_transparent">@color/black_audio_player_transparent</item>
<item name="audio_browser_separator">@color/orange500</item>
<item name="playlist_item_drag_shadow">@color/orange500</item>
<item name="audio_player_header_time">@color/orange500</item>

4
vlc-android/src/org/videolan/vlc/gui/audio/AudioPlayer.kt

@ -301,7 +301,7 @@ class AudioPlayer : Fragment(), PlaylistAdapter.IPlayer, TextWatcher, CoroutineS
binding.backgroundView.setImageBitmap(blurredCover)
binding.backgroundView.visibility = View.VISIBLE
binding.songsList.setBackgroundResource(0)
if (playerState == com.google.android.material.bottomsheet.BottomSheetBehavior.STATE_EXPANDED) binding.header.setBackgroundResource(0)
binding.header.setBackgroundColor(UiTools.getColorFromAttribute(requireContext(), R.attr.audio_player_transparent))
} else setDefaultBackground()
}
}
@ -566,7 +566,7 @@ class AudioPlayer : Fragment(), PlaylistAdapter.IPlayer, TextWatcher, CoroutineS
setHeaderVisibilities(advFuncVisible = false, playlistSwitchVisible = false, headerPlayPauseVisible = true, progressBarVisible = true, headerTimeVisible = true, searchVisible = false)
}
BottomSheetBehavior.STATE_EXPANDED -> {
binding.header.setBackgroundResource(0)
binding.header.setBackgroundColor(UiTools.getColorFromAttribute(requireContext(), R.attr.audio_player_transparent))
setHeaderVisibilities(advFuncVisible = true, playlistSwitchVisible = true, headerPlayPauseVisible = false, progressBarVisible = false, headerTimeVisible = false, searchVisible = true)
showPlaylistTips()
playlistAdapter.currentIndex = playlistModel.currentMediaPosition

3
vlc-android/src/org/videolan/vlc/gui/audio/PlaylistAdapter.kt

@ -25,6 +25,7 @@ package org.videolan.vlc.gui.audio
import android.annotation.TargetApi
import android.content.Context
import android.graphics.Typeface
import android.graphics.drawable.BitmapDrawable
import android.os.Build
import android.os.Message
@ -109,10 +110,12 @@ class PlaylistAdapter(private val player: IPlayer) : DiffUtilAdapter<AbstractMed
if (mModel?.playing != false) holder.binding.playing.start() else holder.binding.playing.stop()
holder.binding.playing.visibility = View.VISIBLE
holder.binding.coverImage.visibility = View.INVISIBLE
holder.binding.audioItemTitle.setTypeface(null, Typeface.BOLD)
currentPlayingVisu = holder.binding.playing
} else {
holder.binding.playing.stop()
holder.binding.playing.visibility = View.INVISIBLE
holder.binding.audioItemTitle.typeface = null
holder.binding.coverImage.visibility = View.VISIBLE
}

7
vlc-android/src/org/videolan/vlc/gui/helpers/UiTools.kt

@ -30,7 +30,7 @@ import android.content.Context
import android.content.DialogInterface
import android.content.Intent
import android.content.res.Configuration
import android.graphics.Bitmap
import android.graphics.*
import android.graphics.drawable.BitmapDrawable
import android.media.MediaRouter
import android.net.Uri
@ -63,8 +63,8 @@ import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.ObsoleteCoroutinesApi
import kotlinx.coroutines.launch
import org.videolan.libvlc.util.AndroidUtil
import org.videolan.medialibrary.interfaces.AbstractMedialibrary
import org.videolan.medialibrary.MLServiceLocator
import org.videolan.medialibrary.interfaces.AbstractMedialibrary
import org.videolan.medialibrary.interfaces.media.AbstractMediaWrapper
import org.videolan.medialibrary.media.MediaLibraryItem
import org.videolan.tools.isStarted
@ -78,8 +78,7 @@ import org.videolan.vlc.gui.dialogs.SavePlaylistDialog
import org.videolan.vlc.media.MediaUtils
import org.videolan.vlc.providers.medialibrary.MedialibraryProvider
import org.videolan.vlc.util.*
import java.util.Locale
import java.util.TreeMap
import java.util.*
import kotlin.collections.ArrayList
import kotlin.collections.component1
import kotlin.collections.component2

8
vlc-android/src/org/videolan/vlc/media/MediaUtils.kt

@ -20,14 +20,14 @@ import kotlinx.coroutines.*
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.channels.actor
import org.videolan.libvlc.util.AndroidUtil
import org.videolan.medialibrary.interfaces.AbstractMedialibrary
import org.videolan.medialibrary.MLServiceLocator
import org.videolan.medialibrary.Tools
import org.videolan.medialibrary.interfaces.AbstractMedialibrary
import org.videolan.medialibrary.interfaces.media.AbstractAlbum
import org.videolan.medialibrary.interfaces.media.AbstractFolder
import org.videolan.medialibrary.interfaces.media.AbstractMediaWrapper
import org.videolan.medialibrary.interfaces.media.AbstractPlaylist
import org.videolan.medialibrary.media.*
import org.videolan.medialibrary.media.MediaLibraryItem
import org.videolan.vlc.PlaybackService
import org.videolan.vlc.R
import org.videolan.vlc.VLCApplication
@ -286,13 +286,13 @@ object MediaUtils : CoroutineScope {
var subtitle = media.nowPlaying ?: media.artist
if (media.length > 0L) {
subtitle = if (TextUtils.isEmpty(subtitle)) Tools.millisToString(media.length)
else "$subtitle - ${Tools.millisToString(media.length)}"
else "$subtitle ${Tools.millisToString(media.length)}"
}
return subtitle
}
fun getMediaTitle(mediaWrapper: AbstractMediaWrapper) = mediaWrapper.title
?: FileUtils.getFileNameFromPath(mediaWrapper.location)!!
?: FileUtils.getFileNameFromPath(mediaWrapper.location)
fun getContentMediaUri(data: Uri) = try {
VLCApplication.appContext.contentResolver.query(data,

Loading…
Cancel
Save