rework the app UI

This commit is contained in:
tibbi 2018-02-07 17:16:30 +01:00
parent 4ce92ac53d
commit 5539c08786
12 changed files with 386 additions and 209 deletions

View file

@ -45,7 +45,7 @@ ext {
}
dependencies {
implementation 'com.simplemobiletools:commons:3.10.0'
implementation 'com.simplemobiletools:commons:3.10.6'
implementation 'com.squareup:otto:1.3.8'
implementation 'com.facebook.stetho:stetho:1.5.0'

View file

@ -4,32 +4,35 @@ import android.app.SearchManager
import android.content.Context
import android.content.Intent
import android.graphics.Paint
import android.graphics.drawable.ColorDrawable
import android.media.AudioManager
import android.os.Bundle
import android.os.Environment
import android.support.v4.view.MenuItemCompat
import android.support.v7.widget.LinearLayoutManager
import android.support.v7.widget.SearchView
import android.view.Menu
import android.view.MenuItem
import android.view.ViewGroup
import android.widget.SeekBar
import com.bumptech.glide.Glide
import com.bumptech.glide.load.engine.DiskCacheStrategy
import com.bumptech.glide.request.RequestOptions
import com.simplemobiletools.commons.dialogs.FilePickerDialog
import com.simplemobiletools.commons.dialogs.RadioGroupDialog
import com.simplemobiletools.commons.extensions.*
import com.simplemobiletools.commons.helpers.*
import com.simplemobiletools.commons.interfaces.RecyclerScrollCallback
import com.simplemobiletools.commons.interfaces.RefreshRecyclerViewListener
import com.simplemobiletools.commons.models.RadioItem
import com.simplemobiletools.commons.models.Release
import com.simplemobiletools.commons.views.MyLinearLayoutManager
import com.simplemobiletools.musicplayer.BuildConfig
import com.simplemobiletools.musicplayer.R
import com.simplemobiletools.musicplayer.adapters.SongAdapter
import com.simplemobiletools.musicplayer.dialogs.ChangeSortingDialog
import com.simplemobiletools.musicplayer.dialogs.NewPlaylistDialog
import com.simplemobiletools.musicplayer.dialogs.RemovePlaylistDialog
import com.simplemobiletools.musicplayer.extensions.config
import com.simplemobiletools.musicplayer.extensions.dbHelper
import com.simplemobiletools.musicplayer.extensions.playlistChanged
import com.simplemobiletools.musicplayer.extensions.sendIntent
import com.simplemobiletools.musicplayer.extensions.*
import com.simplemobiletools.musicplayer.helpers.*
import com.simplemobiletools.musicplayer.inlines.indexOfFirstOrNull
import com.simplemobiletools.musicplayer.models.Events
@ -39,14 +42,19 @@ import com.simplemobiletools.musicplayer.services.MusicService
import com.squareup.otto.Bus
import com.squareup.otto.Subscribe
import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.android.synthetic.main.item_navigation.*
import java.io.File
import java.util.*
class MainActivity : SimpleActivity(), SeekBar.OnSeekBarChangeListener, RefreshRecyclerViewListener {
class MainActivity : SimpleActivity(), RefreshRecyclerViewListener {
private var isThirdPartyIntent = false
private var songs = ArrayList<Song>()
private var searchMenuItem: MenuItem? = null
private var isSearchOpen = false
private var artView: ViewGroup? = null
private var actionbarSize = 0
private var topArtHeight = 0
private var storedUseEnglish = false
@ -60,7 +68,13 @@ class MainActivity : SimpleActivity(), SeekBar.OnSeekBarChangeListener, RefreshR
bus = BusProvider.instance
bus.register(this)
progressbar.setOnSeekBarChangeListener(this)
initSeekbarChangeListener()
actionbarSize = getActionBarHeight()
topArtHeight = resources.getDimensionPixelSize(R.dimen.top_art_height)
artView = layoutInflater.inflate(R.layout.item_transparent, null) as ViewGroup
songs_fastscroller.measureItemIndex = LIST_HEADERS_COUNT
handlePermission(PERMISSION_WRITE_STORAGE) {
if (it) {
@ -77,6 +91,15 @@ class MainActivity : SimpleActivity(), SeekBar.OnSeekBarChangeListener, RefreshR
volumeControlStream = AudioManager.STREAM_MUSIC
checkWhatsNewDialog()
storeStateVariables()
songs_list.recyclerScrollCallback = object : RecyclerScrollCallback {
override fun onScrolled(scrollY: Int) {
top_navigation.beVisibleIf(scrollY > topArtHeight)
val minOverlayTransitionY = actionbarSize - topArtHeight
art_holder.translationY = Math.min(0, Math.max(minOverlayTransitionY, -scrollY / 2)).toFloat()
song_list_background.translationY = Math.max(0, -scrollY + topArtHeight).toFloat()
}
}
}
override fun onResume() {
@ -94,6 +117,9 @@ class MainActivity : SimpleActivity(), SeekBar.OnSeekBarChangeListener, RefreshR
songs_fastscroller.allowBubbleDisplay = config.showInfoBubble
songs_fastscroller.updateBubbleColors()
art_holder.background = ColorDrawable(config.backgroundColor)
song_list_background.background = ColorDrawable(config.backgroundColor)
top_navigation.background = ColorDrawable(config.backgroundColor)
}
override fun onPause() {
@ -193,7 +219,7 @@ class MainActivity : SimpleActivity(), SeekBar.OnSeekBarChangeListener, RefreshR
override fun onMenuItemActionExpand(item: MenuItem?): Boolean {
songs_playlist_empty.text = getString(R.string.no_items_found)
songs_playlist_empty_add_folder.beGone()
main_header_holder.beGone()
art_holder.beGone()
isSearchOpen = true
return true
}
@ -201,7 +227,7 @@ class MainActivity : SimpleActivity(), SeekBar.OnSeekBarChangeListener, RefreshR
override fun onMenuItemActionCollapse(item: MenuItem?): Boolean {
songs_playlist_empty.text = getString(R.string.playlist_empty)
songs_playlist_empty_add_folder.beVisibleIf(songs.isEmpty())
main_header_holder.beVisible()
art_holder.beVisible()
if (isSearchOpen) {
searchQueryChanged("")
}
@ -364,12 +390,12 @@ class MainActivity : SimpleActivity(), SeekBar.OnSeekBarChangeListener, RefreshR
}
private fun setupIconColors() {
val color = config.textColor
previous_btn.applyColorFilter(color)
play_pause_btn.applyColorFilter(color)
next_btn.applyColorFilter(color)
val textColor = config.textColor
previous_btn.applyColorFilter(textColor)
play_pause_btn.applyColorFilter(textColor)
next_btn.applyColorFilter(textColor)
(songs_list.adapter as? SongAdapter)?.textColor = color
getSongsAdapter()?.textColor = textColor
songs_fastscroller.updatePrimaryColor()
}
@ -383,11 +409,12 @@ class MainActivity : SimpleActivity(), SeekBar.OnSeekBarChangeListener, RefreshR
}
private fun updateSongInfo(song: Song?) {
song_title.text = song?.title ?: ""
song_artist.text = song?.artist ?: ""
progressbar.max = song?.duration ?: 0
progressbar.progress = 0
song_info_title.text = song?.title ?: ""
song_info_artist.text = song?.artist ?: ""
song_progressbar.max = song?.duration ?: 0
song_progressbar.progress = 0
getSongsAdapter()?.updateSong(song)
if (songs.isEmpty() && !isThirdPartyIntent) {
toast(R.string.empty_playlist)
}
@ -397,12 +424,12 @@ class MainActivity : SimpleActivity(), SeekBar.OnSeekBarChangeListener, RefreshR
this.songs = songs
val currAdapter = songs_list.adapter
songs_fastscroller.setViews(songs_list) {
val item = (songs_list.adapter as SongAdapter).songs.getOrNull(it)
val item = getSongsAdapter()?.songs?.getOrNull(it)
songs_fastscroller.updateBubbleText(item?.getBubbleText() ?: "")
}
if (currAdapter == null) {
SongAdapter(this@MainActivity, songs, this, songs_list, songs_fastscroller) {
SongAdapter(this@MainActivity, songs, this, artView!!, songs_list, songs_fastscroller) {
songPicked(getSongIndex(it as Song))
}.apply {
setupDragListener(true)
@ -411,12 +438,12 @@ class MainActivity : SimpleActivity(), SeekBar.OnSeekBarChangeListener, RefreshR
songs_list.adapter = this
}
} else {
val state = (songs_list.layoutManager as LinearLayoutManager).onSaveInstanceState()
val state = (songs_list.layoutManager as MyLinearLayoutManager).onSaveInstanceState()
(currAdapter as SongAdapter).apply {
isThirdPartyIntent = this@MainActivity.isThirdPartyIntent
updateSongs(songs)
}
(songs_list.layoutManager as LinearLayoutManager).onRestoreInstanceState(state)
(songs_list.layoutManager as MyLinearLayoutManager).onRestoreInstanceState(state)
}
markCurrentSong()
songs_playlist_empty.beVisibleIf(songs.isEmpty())
@ -425,15 +452,22 @@ class MainActivity : SimpleActivity(), SeekBar.OnSeekBarChangeListener, RefreshR
private fun getSongIndex(song: Song): Int = songs.indexOfFirstOrNull { it == song } ?: 0
private fun getSongsAdapter() = songs_list.adapter as? SongAdapter
@Subscribe
fun songChangedEvent(event: Events.SongChanged) {
updateSongInfo(event.song)
markCurrentSong()
val cover = getAlbumImage(event.song)
val options = RequestOptions().placeholder(art_image.drawable).diskCacheStrategy(DiskCacheStrategy.RESOURCE)
Glide.with(this).load(cover).apply(options).into(art_image)
}
@Subscribe
fun songStateChanged(event: Events.SongStateChanged) {
play_pause_btn.setImageDrawable(resources.getDrawable(if (event.isPlaying) R.drawable.ic_pause else R.drawable.ic_play))
val isPlaying = event.isPlaying
play_pause_btn.setImageDrawable(resources.getDrawable(if (isPlaying) R.drawable.ic_pause else R.drawable.ic_play))
getSongsAdapter()?.updateSongState(isPlaying)
}
@Subscribe
@ -443,7 +477,9 @@ class MainActivity : SimpleActivity(), SeekBar.OnSeekBarChangeListener, RefreshR
@Subscribe
fun progressUpdated(event: Events.ProgressUpdated) {
progressbar.progress = event.progress
val progress = event.progress
song_progressbar.progress = progress
getSongsAdapter()?.updateSongProgress(progress)
}
@Subscribe
@ -454,33 +490,36 @@ class MainActivity : SimpleActivity(), SeekBar.OnSeekBarChangeListener, RefreshR
private fun markCurrentSong() {
val newSongId = MusicService.mCurrSong?.id ?: -1L
val cnt = songs.size - 1
val songIndex = (0..cnt).firstOrNull { songs[it].id == newSongId } ?: -1
if (songs_list.adapter != null)
(songs_list.adapter as SongAdapter).updateCurrentSongIndex(songIndex)
val songIndex = (0..cnt).firstOrNull { songs[it].id == newSongId }?.plus(0) ?: -1
getSongsAdapter()?.updateCurrentSongIndex(songIndex)
}
private fun searchQueryChanged(text: String) {
val filtered = songs.filter { it.artist.contains(text, true) || it.title.contains(text, true) } as ArrayList
filtered.sortBy { !(it.artist.startsWith(text, true) || it.title.startsWith(text, true)) }
songs_playlist_empty.beVisibleIf(filtered.isEmpty())
(songs_list.adapter as? SongAdapter)?.updateSongs(filtered)
getSongsAdapter()?.updateSongs(filtered)
}
override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) {
val duration = progressbar.max.getFormattedDuration()
val formattedProgress = progress.getFormattedDuration()
song_progress.text = String.format(resources.getString(R.string.progress), formattedProgress, duration)
}
private fun initSeekbarChangeListener() {
song_progressbar.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) {
val duration = song_progressbar.max.getFormattedDuration()
val formattedProgress = progress.getFormattedDuration()
song_progress.text = String.format(resources.getString(R.string.progress), formattedProgress, duration)
}
override fun onStartTrackingTouch(seekBar: SeekBar) {
}
override fun onStartTrackingTouch(seekBar: SeekBar) {
}
override fun onStopTrackingTouch(seekBar: SeekBar) {
Intent(this, MusicService::class.java).apply {
putExtra(PROGRESS, seekBar.progress)
action = SET_PROGRESS
startService(this)
}
override fun onStopTrackingTouch(seekBar: SeekBar) {
Intent(this@MainActivity, MusicService::class.java).apply {
putExtra(PROGRESS, seekBar.progress)
action = SET_PROGRESS
startService(this)
}
}
})
}
override fun refreshItems() {

View file

@ -46,8 +46,8 @@ class WidgetConfigureActivity : SimpleActivity() {
val currSong = MusicService.mCurrSong
if (currSong != null) {
song_title.text = currSong.title
song_artist.text = currSong.artist
song_info_title.text = currSong.title
song_info_artist.text = currSong.artist
}
}
@ -110,8 +110,8 @@ class WidgetConfigureActivity : SimpleActivity() {
config_text_color.setBackgroundColor(mTextColor)
config_save.setTextColor(mTextColor)
song_title.setTextColor(mTextColor)
song_artist.setTextColor(mTextColor)
song_info_title.setTextColor(mTextColor)
song_info_artist.setTextColor(mTextColor)
previous_btn.drawable.applyColorFilter(mTextColor)
play_pause_btn.drawable.applyColorFilter(mTextColor)

View file

@ -5,13 +5,12 @@ import android.net.Uri
import android.view.Menu
import android.view.View
import android.view.ViewGroup
import android.widget.SeekBar
import com.bignerdranch.android.multiselector.MultiSelector
import com.simplemobiletools.commons.adapters.MyRecyclerViewAdapter
import com.simplemobiletools.commons.dialogs.ConfirmationDialog
import com.simplemobiletools.commons.dialogs.PropertiesDialog
import com.simplemobiletools.commons.extensions.applyColorFilter
import com.simplemobiletools.commons.extensions.beInvisibleIf
import com.simplemobiletools.commons.extensions.deleteFiles
import com.simplemobiletools.commons.extensions.shareUris
import com.simplemobiletools.commons.extensions.*
import com.simplemobiletools.commons.interfaces.RefreshRecyclerViewListener
import com.simplemobiletools.commons.views.FastScroller
import com.simplemobiletools.commons.views.MyRecyclerView
@ -22,21 +21,24 @@ import com.simplemobiletools.musicplayer.dialogs.EditDialog
import com.simplemobiletools.musicplayer.extensions.config
import com.simplemobiletools.musicplayer.extensions.dbHelper
import com.simplemobiletools.musicplayer.extensions.sendIntent
import com.simplemobiletools.musicplayer.helpers.EDIT
import com.simplemobiletools.musicplayer.helpers.EDITED_SONG
import com.simplemobiletools.musicplayer.helpers.NEXT
import com.simplemobiletools.musicplayer.helpers.REFRESH_LIST
import com.simplemobiletools.musicplayer.helpers.*
import com.simplemobiletools.musicplayer.models.Song
import com.simplemobiletools.musicplayer.services.MusicService
import kotlinx.android.synthetic.main.item_navigation.view.*
import kotlinx.android.synthetic.main.item_song.view.*
import java.io.File
import java.util.*
class SongAdapter(activity: SimpleActivity, var songs: ArrayList<Song>, val listener: RefreshRecyclerViewListener, recyclerView: MyRecyclerView,
fastScroller: FastScroller, itemClick: (Any) -> Unit) : MyRecyclerViewAdapter(activity, recyclerView, fastScroller, itemClick) {
class SongAdapter(activity: SimpleActivity, var songs: ArrayList<Song>, val listener: RefreshRecyclerViewListener, val transparentView: View,
recyclerView: MyRecyclerView, fastScroller: FastScroller, itemClick: (Any) -> Unit) : MyRecyclerViewAdapter(activity, recyclerView, fastScroller, itemClick) {
private val VIEW_TYPE_TRANSPARENT = 0
private val VIEW_TYPE_NAVIGATION = 1
private val VIEW_TYPE_ITEM = 2
private var currentSongIndex = 0
private var songsHashCode = songs.hashCode()
private var currentSong: Song? = null
private var navigationView: ViewGroup? = null
var isThirdPartyIntent = false
override fun getActionMenuId() = R.menu.cab
@ -47,17 +49,35 @@ class SongAdapter(activity: SimpleActivity, var songs: ArrayList<Song>, val list
view?.song_frame?.isSelected = select
}
override fun onCreateViewHolder(parent: ViewGroup?, viewType: Int) = createViewHolder(R.layout.item_song, parent)
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val song = songs[position]
val view = holder.bindView(song, !isThirdPartyIntent) { itemView, layoutPosition ->
setupView(itemView, song, layoutPosition)
override fun onCreateViewHolder(parent: ViewGroup?, viewType: Int): ViewHolder {
return when (viewType) {
VIEW_TYPE_TRANSPARENT -> TransparentViewHolder(transparentView)
VIEW_TYPE_NAVIGATION -> getNavigationViewHolder()
else -> createViewHolder(R.layout.item_song, parent)
}
bindViewHolder(holder, position, view)
}
override fun getItemCount() = songs.size
override fun getItemViewType(position: Int): Int {
return when (position) {
0 -> VIEW_TYPE_TRANSPARENT
1 -> VIEW_TYPE_NAVIGATION
else -> VIEW_TYPE_ITEM
}
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
if (holder is NavigationViewHolder) {
} else if (holder !is TransparentViewHolder) {
val song = songs[position - LIST_HEADERS_COUNT]
val view = holder.bindView(song, !isThirdPartyIntent) { itemView, layoutPosition ->
setupView(itemView, song, layoutPosition)
}
bindViewHolder(holder, position - LIST_HEADERS_COUNT, view)
}
}
override fun getItemCount() = songs.size + LIST_HEADERS_COUNT
override fun prepareActionMode(menu: Menu) {
menu.apply {
@ -78,6 +98,14 @@ class SongAdapter(activity: SimpleActivity, var songs: ArrayList<Song>, val list
override fun getSelectableItemCount() = songs.size
private fun getNavigationViewHolder(): NavigationViewHolder {
if (navigationView == null) {
navigationView = activity.layoutInflater.inflate(R.layout.item_navigation, null) as ViewGroup
initNavigationView()
}
return NavigationViewHolder(navigationView!!)
}
private fun showProperties() {
if (selectedPositions.size <= 1) {
PropertiesDialog(activity, songs[selectedPositions.first()].path)
@ -191,15 +219,77 @@ class SongAdapter(activity: SimpleActivity, var songs: ArrayList<Song>, val list
}
fun updateCurrentSongIndex(index: Int) {
val correctIndex = index + LIST_HEADERS_COUNT
val prevIndex = currentSongIndex
currentSongIndex = -1
notifyItemChanged(prevIndex)
currentSongIndex = index
if (index >= 0)
notifyItemChanged(index)
currentSongIndex = correctIndex
if (index >= 0) {
notifyItemChanged(correctIndex)
}
}
fun updateSong(song: Song?) {
currentSong = song
navigationView?.apply {
song_info_title.text = song?.title ?: ""
song_info_artist.text = song?.artist ?: ""
song_progressbar.max = song?.duration ?: 0
song_progressbar.progress = 0
}
}
private fun initNavigationView() {
navigationView?.apply {
previous_btn.setOnClickListener { activity.sendIntent(PREVIOUS) }
play_pause_btn.setOnClickListener { activity.sendIntent(PLAYPAUSE) }
next_btn.setOnClickListener { activity.sendIntent(NEXT) }
previous_btn.applyColorFilter(textColor)
play_pause_btn.applyColorFilter(textColor)
next_btn.applyColorFilter(textColor)
song_info_title.setTextColor(textColor)
song_info_artist.setTextColor(textColor)
song_progress.setTextColor(textColor)
song_progressbar.setColors(textColor, baseConfig.primaryColor, baseConfig.backgroundColor)
song_progressbar?.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) {
val duration = song_progressbar.max.getFormattedDuration()
val formattedProgress = progress.getFormattedDuration()
song_progress.text = String.format(resources.getString(R.string.progress), formattedProgress, duration)
}
override fun onStartTrackingTouch(seekBar: SeekBar) {
}
override fun onStopTrackingTouch(seekBar: SeekBar) {
Intent(activity, MusicService::class.java).apply {
putExtra(PROGRESS, seekBar.progress)
action = SET_PROGRESS
activity.startService(this)
}
}
})
updateSong(currentSong)
}
}
fun updateSongState(isPlaying: Boolean) {
navigationView?.play_pause_btn?.setImageDrawable(resources.getDrawable(if (isPlaying) R.drawable.ic_pause else R.drawable.ic_play))
}
fun updateSongProgress(progress: Int) {
navigationView?.song_progressbar?.progress = progress
}
class TransparentViewHolder(view: View) : ViewHolder(view, multiSelector = MultiSelector())
class NavigationViewHolder(view: ViewGroup) : ViewHolder(view, multiSelector = MultiSelector())
private fun setupView(view: View, song: Song, layoutPosition: Int) {
view.apply {
song_title.text = song.title

View file

@ -5,6 +5,8 @@ import android.content.Intent
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.media.MediaMetadataRetriever
import android.util.TypedValue
import com.simplemobiletools.commons.extensions.getColoredBitmap
import com.simplemobiletools.musicplayer.R
import com.simplemobiletools.musicplayer.helpers.*
import com.simplemobiletools.musicplayer.models.Song
@ -48,5 +50,14 @@ fun Context.getAlbumImage(song: Song?): Bitmap {
} catch (e: Exception) {
}
}
return BitmapFactory.decodeResource(resources, R.drawable.ic_headset)
return resources.getColoredBitmap(R.drawable.ic_headset, config.textColor)
}
fun Context.getActionBarHeight(): Int {
val textSizeAttr = intArrayOf(R.attr.actionBarSize)
val attrs = obtainStyledAttributes(TypedValue().data, textSizeAttr)
val actionBarSize = attrs.getDimensionPixelSize(0, -1)
attrs.recycle()
return actionBarSize
}

View file

@ -34,3 +34,5 @@ const val SORT_BY_TITLE = 1
const val SORT_BY_ARTIST = 2
const val SORT_BY_PATH = 4
const val SORT_BY_DURATION = 8
const val LIST_HEADERS_COUNT = 2

View file

@ -80,8 +80,8 @@ class MyWidgetProvider : AppWidgetProvider() {
artist = mCurrSong!!.artist
}
views.setTextViewText(R.id.song_title, title)
views.setTextViewText(R.id.song_artist, artist)
views.setTextViewText(R.id.song_info_title, title)
views.setTextViewText(R.id.song_info_artist, artist)
}
@Subscribe
@ -109,8 +109,8 @@ class MyWidgetProvider : AppWidgetProvider() {
views.apply {
setBackgroundColor(R.id.widget_holder, widgetBgColor)
setTextColor(R.id.song_title, widgetTextColor)
setTextColor(R.id.song_artist, widgetTextColor)
setTextColor(R.id.song_info_title, widgetTextColor)
setTextColor(R.id.song_info_artist, widgetTextColor)
setImageViewBitmap(R.id.previous_btn, res.getColoredBitmap(R.drawable.ic_previous, widgetTextColor))
setImageViewBitmap(R.id.next_btn, res.getColoredBitmap(R.drawable.ic_next, widgetTextColor))
}
@ -135,8 +135,8 @@ class MyWidgetProvider : AppWidgetProvider() {
setupIntent(views, PLAYPAUSE, R.id.play_pause_btn)
setupIntent(views, NEXT, R.id.next_btn)
setupAppOpenIntent(views, R.id.song_title)
setupAppOpenIntent(views, R.id.song_artist)
setupAppOpenIntent(views, R.id.song_info_title)
setupAppOpenIntent(views, R.id.song_info_artist)
}
override fun onAppWidgetOptionsChanged(context: Context, appWidgetManager: AppWidgetManager, widgetId: Int, newOptions: Bundle) {

View file

@ -2,154 +2,85 @@
<RelativeLayout
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/main_holder"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingTop="@dimen/medium_margin">
android:layout_height="match_parent">
<RelativeLayout
android:id="@+id/main_header_holder"
android:id="@+id/art_holder"
android:layout_width="match_parent"
android:layout_height="wrap_content">
android:layout_height="@dimen/top_art_height">
<RelativeLayout
android:id="@+id/song_info_holder"
<ImageView
android:id="@+id/art_image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignBottom="@+id/previous_btn"
android:layout_alignTop="@+id/previous_btn"
android:layout_toLeftOf="@+id/previous_btn"
android:gravity="center_vertical"
android:paddingRight="@dimen/small_margin">
<com.simplemobiletools.commons.views.MyTextView
android:id="@+id/song_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/activity_margin"
android:ellipsize="end"
android:maxLines="1"
android:textSize="@dimen/normal_text_size"
tools:text="Song title"/>
<com.simplemobiletools.commons.views.MyTextView
android:id="@+id/song_artist"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/song_title"
android:layout_marginLeft="@dimen/activity_margin"
android:maxLines="1"
android:textSize="@dimen/smaller_text_size"
tools:text="Song artist"/>
</RelativeLayout>
<ImageView
android:id="@+id/next_btn"
style="@style/MyTransparentButton"
android:layout_width="@dimen/button_size"
android:layout_height="@dimen/button_size"
android:layout_alignParentRight="true"
android:layout_marginRight="@dimen/medium_margin"
android:background="?attr/selectableItemBackgroundBorderless"
android:paddingBottom="@dimen/small_margin"
android:paddingTop="@dimen/small_margin"
android:src="@drawable/ic_next"/>
<ImageView
android:id="@+id/play_pause_btn"
style="@style/MyTransparentButton"
android:layout_width="@dimen/button_size"
android:layout_height="@dimen/button_size"
android:layout_toLeftOf="@+id/next_btn"
android:background="?attr/selectableItemBackgroundBorderless"
android:paddingBottom="@dimen/small_margin"
android:paddingTop="@dimen/small_margin"
android:src="@drawable/ic_play"/>
<ImageView
android:id="@+id/previous_btn"
style="@style/MyTransparentButton"
android:layout_width="@dimen/button_size"
android:layout_height="@dimen/button_size"
android:layout_toLeftOf="@+id/play_pause_btn"
android:background="?attr/selectableItemBackgroundBorderless"
android:paddingBottom="@dimen/small_margin"
android:paddingTop="@dimen/small_margin"
android:src="@drawable/ic_previous"/>
<com.simplemobiletools.commons.views.MySeekBar
android:id="@+id/progressbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/previous_btn"
android:paddingBottom="@dimen/medium_margin"
android:paddingLeft="@dimen/activity_margin"
android:paddingRight="@dimen/activity_margin"
android:paddingTop="@dimen/normal_margin"/>
<com.simplemobiletools.commons.views.MyTextView
android:id="@+id/song_progress"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/progressbar"
android:layout_marginBottom="@dimen/activity_margin"
android:layout_marginLeft="@dimen/activity_margin"
android:layout_marginRight="@dimen/activity_margin"
android:gravity="center_horizontal"
android:maxLines="1"/>
android:adjustViewBounds="true"
android:src="@mipmap/ic_launcher"/>
</RelativeLayout>
<RelativeLayout
android:id="@+id/song_list_holder"
<View
android:id="@+id/song_list_background"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/main_header_holder">
android:background="@android:color/transparent"/>
<com.simplemobiletools.commons.views.MyRecyclerView
android:id="@+id/songs_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
app:layoutManager="com.simplemobiletools.commons.views.MyLinearLayoutManager"/>
<com.simplemobiletools.commons.views.MyRecyclerView
android:id="@+id/songs_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
app:layoutManager="com.simplemobiletools.commons.views.MyLinearLayoutManager"/>
<com.simplemobiletools.commons.views.FastScroller
android:id="@+id/songs_fastscroller"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:paddingLeft="@dimen/normal_margin"
android:paddingStart="@dimen/normal_margin">
<LinearLayout
android:id="@+id/top_navigation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:visibility="gone">
<include layout="@layout/fastscroller_handle_vertical"/>
<include layout="@layout/item_navigation"/>
</com.simplemobiletools.commons.views.FastScroller>
<include layout="@layout/divider"/>
</LinearLayout>
<com.simplemobiletools.commons.views.MyTextView
android:id="@+id/songs_playlist_empty"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:gravity="center"
android:paddingLeft="@dimen/big_margin"
android:paddingRight="@dimen/big_margin"
android:paddingTop="@dimen/medium_margin"
android:text="@string/playlist_empty"
android:textSize="@dimen/bigger_text_size"/>
<com.simplemobiletools.commons.views.FastScroller
android:id="@+id/songs_fastscroller"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:paddingLeft="@dimen/normal_margin"
android:paddingStart="@dimen/normal_margin">
<com.simplemobiletools.commons.views.MyTextView
android:id="@+id/songs_playlist_empty_add_folder"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/songs_playlist_empty"
android:layout_centerHorizontal="true"
android:background="?attr/selectableItemBackground"
android:gravity="center"
android:padding="@dimen/activity_margin"
android:text="@string/add_folder_to_playlist"
android:textSize="@dimen/bigger_text_size"/>
<include layout="@layout/fastscroller_handle_vertical"/>
</com.simplemobiletools.commons.views.FastScroller>
<com.simplemobiletools.commons.views.MyTextView
android:id="@+id/songs_playlist_empty"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/art_holder"
android:layout_centerHorizontal="true"
android:gravity="center"
android:paddingLeft="@dimen/big_margin"
android:paddingRight="@dimen/big_margin"
android:paddingTop="@dimen/medium_margin"
android:text="@string/playlist_empty"
android:textSize="@dimen/bigger_text_size"/>
<com.simplemobiletools.commons.views.MyTextView
android:id="@+id/songs_playlist_empty_add_folder"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/songs_playlist_empty"
android:layout_centerHorizontal="true"
android:background="?attr/selectableItemBackground"
android:gravity="center"
android:padding="@dimen/activity_margin"
android:text="@string/add_folder_to_playlist"
android:textSize="@dimen/bigger_text_size"/>
</RelativeLayout>
</RelativeLayout>

View file

@ -0,0 +1,95 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/navigation_holder"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<RelativeLayout
android:id="@+id/song_info_holder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignBottom="@+id/previous_btn"
android:layout_alignTop="@+id/previous_btn"
android:layout_toLeftOf="@+id/previous_btn"
android:gravity="center_vertical"
android:paddingRight="@dimen/small_margin">
<com.simplemobiletools.commons.views.MyTextView
android:id="@+id/song_info_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/activity_margin"
android:ellipsize="end"
android:maxLines="1"
android:textSize="@dimen/normal_text_size"
tools:text="Song title"/>
<com.simplemobiletools.commons.views.MyTextView
android:id="@+id/song_info_artist"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/song_info_title"
android:layout_marginLeft="@dimen/activity_margin"
android:maxLines="1"
android:textSize="@dimen/smaller_text_size"
tools:text="Song artist"/>
</RelativeLayout>
<ImageView
android:id="@+id/next_btn"
style="@style/MyTransparentButton"
android:layout_width="@dimen/button_size"
android:layout_height="@dimen/button_size"
android:layout_alignParentRight="true"
android:layout_marginRight="@dimen/medium_margin"
android:background="?attr/selectableItemBackgroundBorderless"
android:paddingBottom="@dimen/small_margin"
android:paddingTop="@dimen/small_margin"
android:src="@drawable/ic_next"/>
<ImageView
android:id="@+id/play_pause_btn"
style="@style/MyTransparentButton"
android:layout_width="@dimen/button_size"
android:layout_height="@dimen/button_size"
android:layout_toLeftOf="@+id/next_btn"
android:background="?attr/selectableItemBackgroundBorderless"
android:paddingBottom="@dimen/small_margin"
android:paddingTop="@dimen/small_margin"
android:src="@drawable/ic_play"/>
<ImageView
android:id="@+id/previous_btn"
style="@style/MyTransparentButton"
android:layout_width="@dimen/button_size"
android:layout_height="@dimen/button_size"
android:layout_toLeftOf="@+id/play_pause_btn"
android:background="?attr/selectableItemBackgroundBorderless"
android:paddingBottom="@dimen/small_margin"
android:paddingTop="@dimen/small_margin"
android:src="@drawable/ic_previous"/>
<com.simplemobiletools.commons.views.MySeekBar
android:id="@+id/song_progressbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/song_info_holder"
android:paddingBottom="@dimen/medium_margin"
android:paddingLeft="@dimen/activity_margin"
android:paddingRight="@dimen/activity_margin"
android:paddingTop="@dimen/normal_margin"/>
<com.simplemobiletools.commons.views.MyTextView
android:id="@+id/song_progress"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/song_progressbar"
android:layout_marginBottom="@dimen/activity_margin"
android:layout_marginLeft="@dimen/activity_margin"
android:layout_marginRight="@dimen/activity_margin"
android:gravity="center_horizontal"
android:maxLines="1"/>
</RelativeLayout>

View file

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/recycler_header"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingTop="@dimen/top_art_height"/>

View file

@ -8,7 +8,7 @@
android:gravity="center_horizontal">
<TextView
android:id="@+id/song_title"
android:id="@+id/song_info_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/activity_margin"
@ -22,10 +22,10 @@
android:textSize="@dimen/big_text_size"/>
<TextView
android:id="@+id/song_artist"
android:id="@+id/song_info_artist"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/song_title"
android:layout_below="@+id/song_info_title"
android:layout_marginBottom="@dimen/small_margin"
android:layout_marginLeft="@dimen/activity_margin"
android:layout_marginRight="@dimen/activity_margin"
@ -40,6 +40,6 @@
layout="@layout/widget_controls"
android:layout_width="match_parent"
android:layout_height="@dimen/controls_row_height"
android:layout_below="@+id/song_artist"/>
android:layout_below="@+id/song_info_artist"/>
</RelativeLayout>

View file

@ -1,4 +1,5 @@
<resources>
<dimen name="controls_row_height">60dp</dimen>
<dimen name="button_size">48dp</dimen>
<dimen name="top_art_height">200dp</dimen>
</resources>