diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/AlbumListFragment.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/AlbumListFragment.kt
index 8722bae0..f5b4b4e4 100644
--- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/AlbumListFragment.kt
+++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/AlbumListFragment.kt
@@ -61,10 +61,10 @@ class AlbumListFragment : GenericListFragment<MusicDirectory.Entry, AlbumRowAdap
     override val viewAdapter: AlbumRowAdapter by lazy {
         AlbumRowAdapter(
             liveDataItems.value ?: listOf(),
-            selectFolderHeader,
             { entry -> onItemClick(entry) },
             { menuItem, entry -> onContextMenuItemSelected(menuItem, entry) },
-            imageLoaderProvider.getImageLoader()
+            imageLoaderProvider.getImageLoader(),
+            onMusicFolderUpdate
         )
     }
 
diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/AlbumRowAdapter.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/AlbumRowAdapter.kt
index 9785c9e5..2a5f1c46 100644
--- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/AlbumRowAdapter.kt
+++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/AlbumRowAdapter.kt
@@ -7,10 +7,8 @@
 
 package org.moire.ultrasonic.fragment
 
-import android.view.LayoutInflater
 import android.view.MenuItem
 import android.view.View
-import android.view.ViewGroup
 import android.widget.ImageView
 import android.widget.LinearLayout
 import android.widget.TextView
@@ -18,22 +16,21 @@ import androidx.recyclerview.widget.RecyclerView
 import org.moire.ultrasonic.R
 import org.moire.ultrasonic.domain.MusicDirectory
 import org.moire.ultrasonic.util.ImageLoader
-import org.moire.ultrasonic.view.SelectMusicFolderView
 
 /**
  * Creates a Row in a RecyclerView which contains the details of an Album
  */
 class AlbumRowAdapter(
     albumList: List<MusicDirectory.Entry>,
-    private var selectFolderHeader: SelectMusicFolderView?,
     onItemClick: (MusicDirectory.Entry) -> Unit,
     onContextMenuClick: (MenuItem, MusicDirectory.Entry) -> Boolean,
-    private val imageLoader: ImageLoader
+    private val imageLoader: ImageLoader,
+    onMusicFolderUpdate: (String?) -> Unit
 ) : GenericRowAdapter<MusicDirectory.Entry>(
-    selectFolderHeader,
     onItemClick,
     onContextMenuClick,
-    imageLoader
+    imageLoader,
+    onMusicFolderUpdate
 ) {
 
     override var itemList = albumList
@@ -48,20 +45,8 @@ class AlbumRowAdapter(
         super.notifyDataSetChanged()
     }
 
-    override fun onCreateViewHolder(
-        parent: ViewGroup,
-        viewType: Int
-    ): RecyclerView.ViewHolder {
-        if (viewType == TYPE_ITEM) {
-            val row = LayoutInflater.from(parent.context)
-                .inflate(layout, parent, false)
-            return AlbumViewHolder(row)
-        }
-        return selectFolderHeader!!
-    }
-
     override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
-        if (holder is AlbumViewHolder) {
+        if (holder is ViewHolder) {
             val listPosition = if (selectFolderHeader != null) position - 1 else position
             val entry = itemList[listPosition]
             holder.album.text = entry.title
@@ -73,7 +58,7 @@ class AlbumRowAdapter(
             imageLoader.loadImage(
                 holder.coverArt,
                 MusicDirectory.Entry().apply { coverArt = holder.coverArtId },
-                false, 0, false, true, R.drawable.ic_contact_picture
+                false, 0, false, true, R.drawable.unknown_album
             )
         }
     }
@@ -88,13 +73,20 @@ class AlbumRowAdapter(
     /**
      * Holds the view properties of an Item row
      */
-    class AlbumViewHolder(
-        itemView: View
-    ) : RecyclerView.ViewHolder(itemView) {
-        var album: TextView = itemView.findViewById(R.id.album_title)
-        var artist: TextView = itemView.findViewById(R.id.album_artist)
-        var details: LinearLayout = itemView.findViewById(R.id.row_album_details)
-        var coverArt: ImageView = itemView.findViewById(R.id.album_coverart)
+    class ViewHolder(
+        view: View
+    ) : RecyclerView.ViewHolder(view) {
+        var album: TextView = view.findViewById(R.id.album_title)
+        var artist: TextView = view.findViewById(R.id.album_artist)
+        var details: LinearLayout = view.findViewById(R.id.row_album_details)
+        var coverArt: ImageView = view.findViewById(R.id.album_coverart)
         var coverArtId: String? = null
     }
+
+    /**
+     * Creates an instance of our ViewHolder class
+     */
+    override fun newViewHolder(view: View): RecyclerView.ViewHolder {
+        return ViewHolder(view)
+    }
 }
diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/ArtistListFragment.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/ArtistListFragment.kt
index 2f8e78a6..ddda850b 100644
--- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/ArtistListFragment.kt
+++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/ArtistListFragment.kt
@@ -54,10 +54,10 @@ class ArtistListFragment : GenericListFragment<Artist, ArtistRowAdapter>() {
     override val viewAdapter: ArtistRowAdapter by lazy {
         ArtistRowAdapter(
             liveDataItems.value ?: listOf(),
-            selectFolderHeader,
             { entry -> onItemClick(entry) },
             { menuItem, entry -> onContextMenuItemSelected(menuItem, entry) },
-            imageLoaderProvider.getImageLoader()
+            imageLoaderProvider.getImageLoader(),
+            onMusicFolderUpdate
         )
     }
 }
diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/ArtistRowAdapter.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/ArtistRowAdapter.kt
index a021b606..dfd86ef9 100644
--- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/ArtistRowAdapter.kt
+++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/ArtistRowAdapter.kt
@@ -17,22 +17,21 @@ import org.moire.ultrasonic.domain.Artist
 import org.moire.ultrasonic.domain.MusicDirectory
 import org.moire.ultrasonic.util.ImageLoader
 import org.moire.ultrasonic.util.Util
-import org.moire.ultrasonic.view.SelectMusicFolderView
 
 /**
  * Creates a Row in a RecyclerView which contains the details of an Artist
  */
 class ArtistRowAdapter(
     artistList: List<Artist>,
-    private var selectFolderHeader: SelectMusicFolderView?,
     onItemClick: (Artist) -> Unit,
     onContextMenuClick: (MenuItem, Artist) -> Boolean,
-    private val imageLoader: ImageLoader
+    private val imageLoader: ImageLoader,
+    onMusicFolderUpdate: (String?) -> Unit
 ) : GenericRowAdapter<Artist>(
-    selectFolderHeader,
     onItemClick,
     onContextMenuClick,
-    imageLoader
+    imageLoader,
+    onMusicFolderUpdate
 ),
     SectionedAdapter {
 
@@ -51,7 +50,7 @@ class ArtistRowAdapter(
     }
 
     override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
-        if (holder is ItemViewHolder) {
+        if (holder is ViewHolder) {
             val listPosition = if (selectFolderHeader != null) position - 1 else position
             holder.textView.text = itemList[listPosition].name
             holder.section.text = getSectionForArtist(listPosition)
@@ -101,4 +100,11 @@ class ArtistRowAdapter(
         if (!section.isLetter()) section = '#'
         return section.toString()
     }
+
+    /**
+     * Creates an instance of our ViewHolder class
+     */
+    override fun newViewHolder(view: View): RecyclerView.ViewHolder {
+        return ViewHolder(view)
+    }
 }
diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/GenericListFragment.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/GenericListFragment.kt
index a0b0021e..723193ad 100644
--- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/GenericListFragment.kt
+++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/GenericListFragment.kt
@@ -88,15 +88,25 @@ abstract class GenericListFragment<T : GenericEntry, TA : GenericRowAdapter<T>>
     /**
      * The observer to be called if the available music folders have changed
      */
-    val musicFolderObserver = { changedFolders: List<MusicFolder> ->
-        viewAdapter.notifyDataSetChanged()
-        selectFolderHeader?.setData(
-            activeServerProvider.getActiveServer().musicFolderId,
-            changedFolders
-        )
+    @Suppress("CommentOverPrivateProperty")
+    private val musicFolderObserver = { folders: List<MusicFolder> ->
+        viewAdapter.setFolderList(folders, listModel.activeServer.musicFolderId)
         Unit
     }
 
+    /**
+     * What to do when the user has modified the folder filter
+     */
+    val onMusicFolderUpdate = { selectedFolderId: String? ->
+        if (!listModel.isOffline()) {
+            val currentSetting = listModel.activeServer
+            currentSetting.musicFolderId = selectedFolderId
+            serverSettingsModel.updateItem(currentSetting)
+        }
+        viewAdapter.notifyDataSetChanged()
+        listModel.refresh(refreshListView!!, arguments)
+    }
+
     /**
      * Whether to show the folder selector
      */
@@ -142,27 +152,15 @@ abstract class GenericListFragment<T : GenericEntry, TA : GenericRowAdapter<T>>
         // Create a View Manager
         viewManager = LinearLayoutManager(this.context)
 
-        // Show folder selector UI if enabled
-        if (showFolderHeader()) {
-            selectFolderHeader = SelectMusicFolderView(
-                requireContext(), view as ViewGroup
-            ) { selectedFolderId ->
-                if (!listModel.isOffline()) {
-                    val currentSetting = listModel.activeServer
-                    currentSetting.musicFolderId = selectedFolderId
-                    serverSettingsModel.updateItem(currentSetting)
-                }
-                viewAdapter.notifyDataSetChanged()
-                listModel.refresh(refreshListView!!, arguments)
-            }
-        }
-
         // Hook up the view with the manager and the adapter
         listView = view.findViewById<RecyclerView>(recyclerViewId).apply {
             setHasFixedSize(true)
             layoutManager = viewManager
             adapter = viewAdapter
         }
+
+        // Configure whether to show the folder header
+        viewAdapter.folderHeaderEnabled = showFolderHeader()
     }
 
     @Override
diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/GenericRowAdapter.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/GenericRowAdapter.kt
index 32714999..414c76d0 100644
--- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/GenericRowAdapter.kt
+++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/GenericRowAdapter.kt
@@ -19,6 +19,7 @@ import android.widget.TextView
 import androidx.recyclerview.widget.RecyclerView
 import org.moire.ultrasonic.R
 import org.moire.ultrasonic.data.ActiveServerProvider
+import org.moire.ultrasonic.domain.MusicFolder
 import org.moire.ultrasonic.util.ImageLoader
 import org.moire.ultrasonic.view.SelectMusicFolderView
 
@@ -26,16 +27,20 @@ import org.moire.ultrasonic.view.SelectMusicFolderView
 * An abstract Adapter, which can be extended to display a List of <T> in a RecyclerView
 */
 abstract class GenericRowAdapter<T>(
-    private var selectFolderHeader: SelectMusicFolderView?,
     val onItemClick: (T) -> Unit,
     val onContextMenuClick: (MenuItem, T) -> Boolean,
-    private val imageLoader: ImageLoader
+    private val imageLoader: ImageLoader,
+    private val onMusicFolderUpdate: (String?) -> Unit
 ) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
-
     open var itemList: List<T> = listOf()
     protected abstract val layout: Int
     protected abstract val contextMenuLayout: Int
 
+    var folderHeaderEnabled: Boolean = true
+    var selectFolderHeader: SelectMusicFolderView? = null
+    var musicFolders: List<MusicFolder> = listOf()
+    var selectedFolder: String? = null
+
     /**
      * Sets the data to be displayed in the RecyclerView
      */
@@ -44,6 +49,25 @@ abstract class GenericRowAdapter<T>(
         notifyDataSetChanged()
     }
 
+    /**
+     * Sets the content and state of the music folder selector row
+     */
+    fun setFolderList(changedFolders: List<MusicFolder>, selectedId: String?) {
+        musicFolders = changedFolders
+        selectedFolder = selectedId
+
+        selectFolderHeader?.setData(
+            selectedFolder,
+            musicFolders
+        )
+
+        notifyDataSetChanged()
+    }
+
+    open fun newViewHolder(view: View): RecyclerView.ViewHolder {
+        return ViewHolder(view)
+    }
+
     override fun onCreateViewHolder(
         parent: ViewGroup,
         viewType: Int
@@ -51,13 +75,27 @@ abstract class GenericRowAdapter<T>(
         if (viewType == TYPE_ITEM) {
             val row = LayoutInflater.from(parent.context)
                 .inflate(layout, parent, false)
-            return ItemViewHolder(row)
+            return newViewHolder(row)
+        } else {
+            val row = LayoutInflater.from(parent.context)
+                .inflate(
+                    R.layout.select_folder_header, parent, false
+                )
+            selectFolderHeader = SelectMusicFolderView(parent.context, row, onMusicFolderUpdate)
+
+            if (musicFolders.isNotEmpty()) {
+                selectFolderHeader?.setData(
+                    selectedFolder,
+                    musicFolders
+                )
+            }
+
+            return selectFolderHeader!!
         }
-        return selectFolderHeader!!
     }
 
     override fun onViewRecycled(holder: RecyclerView.ViewHolder) {
-        if ((holder is ItemViewHolder) && (holder.coverArtId != null)) {
+        if ((holder is ViewHolder) && (holder.coverArtId != null)) {
             imageLoader.cancel(holder.coverArtId)
         }
         super.onViewRecycled(holder)
@@ -73,7 +111,7 @@ abstract class GenericRowAdapter<T>(
     }
 
     override fun getItemViewType(position: Int): Int {
-        return if (position == 0 && selectFolderHeader != null) TYPE_HEADER else TYPE_ITEM
+        return if (position == 0 && folderHeaderEnabled) TYPE_HEADER else TYPE_ITEM
     }
 
     internal fun createPopupMenu(view: View, position: Int): Boolean {
@@ -94,7 +132,7 @@ abstract class GenericRowAdapter<T>(
     /**
      * Holds the view properties of an Item row
      */
-    class ItemViewHolder(
+    class ViewHolder(
         itemView: View
     ) : RecyclerView.ViewHolder(itemView) {
         var section: TextView = itemView.findViewById(R.id.row_section)
diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/TrackCollectionFragment.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/TrackCollectionFragment.kt
index 8eeaf9c5..b5ecc21f 100644
--- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/TrackCollectionFragment.kt
+++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/TrackCollectionFragment.kt
@@ -34,13 +34,10 @@ import java.util.Random
 import kotlinx.coroutines.CoroutineExceptionHandler
 import kotlinx.coroutines.launch
 import org.koin.android.ext.android.inject
-import org.koin.android.viewmodel.ext.android.viewModel
 import org.koin.core.component.KoinApiExtension
 import org.moire.ultrasonic.R
-import org.moire.ultrasonic.data.ActiveServerProvider
 import org.moire.ultrasonic.data.ActiveServerProvider.Companion.isOffline
 import org.moire.ultrasonic.domain.MusicDirectory
-import org.moire.ultrasonic.domain.MusicFolder
 import org.moire.ultrasonic.fragment.FragmentTitle.Companion.getTitle
 import org.moire.ultrasonic.fragment.FragmentTitle.Companion.setTitle
 import org.moire.ultrasonic.service.CommunicationErrorHandler
@@ -57,7 +54,6 @@ import org.moire.ultrasonic.util.EntryByDiscAndTrackComparator
 import org.moire.ultrasonic.util.Util
 import org.moire.ultrasonic.view.AlbumView
 import org.moire.ultrasonic.view.EntryAdapter
-import org.moire.ultrasonic.view.SelectMusicFolderView
 import org.moire.ultrasonic.view.SongView
 import timber.log.Timber
 
@@ -71,7 +67,6 @@ class TrackCollectionFragment : Fragment() {
     private var refreshAlbumListView: SwipeRefreshLayout? = null
     private var albumListView: ListView? = null
     private var header: View? = null
-    private var selectFolderHeader: SelectMusicFolderView? = null
     private var albumButtons: View? = null
     private var emptyView: TextView? = null
     private var selectButton: ImageView? = null
@@ -95,7 +90,6 @@ class TrackCollectionFragment : Fragment() {
     private val imageLoaderProvider: ImageLoaderProvider by inject()
     private val shareHandler: ShareHandler by inject()
     private var cancellationToken: CancellationToken? = null
-    private val activeServerProvider: ActiveServerProvider by inject()
 
     private val model: TrackCollectionModel by viewModels()
     private val random: Random = SecureRandom()
@@ -131,19 +125,6 @@ class TrackCollectionFragment : Fragment() {
             false
         )
 
-        selectFolderHeader = SelectMusicFolderView(
-            requireContext(), view as ViewGroup
-        ) { selectedFolderId ->
-            if (!isOffline()) {
-                val serverSettingsModel: ServerSettingsModel by viewModel()
-                val currentSetting = activeServerProvider.getActiveServer()
-                currentSetting.musicFolderId = selectedFolderId
-                serverSettingsModel.updateItem(currentSetting)
-            }
-            this.updateDisplay(true)
-        }
-
-        model.musicFolders.observe(viewLifecycleOwner, musicFolderObserver)
         model.currentDirectory.observe(viewLifecycleOwner, defaultObserver)
         model.songsForGenre.observe(viewLifecycleOwner, songsForGenreObserver)
 
@@ -622,15 +603,6 @@ class TrackCollectionFragment : Fragment() {
         mediaPlayerController.unpin(songs)
     }
 
-    private val musicFolderObserver = Observer<List<MusicFolder>> { changedFolders ->
-        if (changedFolders != null) {
-            selectFolderHeader!!.setData(
-                activeServerProvider.getActiveServer().musicFolderId,
-                changedFolders
-            )
-        }
-    }
-
     private val songsForGenreObserver = Observer<MusicDirectory> { musicDirectory ->
 
         // Hide more button when results are less than album list size
@@ -726,12 +698,9 @@ class TrackCollectionFragment : Fragment() {
                 }
             }
         } else {
-            if (model.showSelectFolderHeader(arguments)) {
-                if (albumListView!!.headerViewsCount == 0) {
-                    albumListView!!.addHeaderView(selectFolderHeader!!.itemView, null, false)
-                }
-            }
 
+            // TODO: This code path can be removed when getArtist has been moved to
+            // AlbumListFragment (getArtist returns the albums of an artist)
             pinButton!!.visibility = View.GONE
             unpinButton!!.visibility = View.GONE
             downloadButton!!.visibility = View.GONE
diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/view/SelectMusicFolderView.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/view/SelectMusicFolderView.kt
index 28d34b2d..3dcec9a4 100644
--- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/view/SelectMusicFolderView.kt
+++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/view/SelectMusicFolderView.kt
@@ -1,89 +1,87 @@
-package org.moire.ultrasonic.view
-
-import android.content.Context
-import android.view.LayoutInflater
-import android.view.MenuItem
-import android.view.ViewGroup
-import android.widget.LinearLayout
-import android.widget.PopupMenu
-import android.widget.TextView
-import androidx.recyclerview.widget.RecyclerView
-import org.moire.ultrasonic.R
-import org.moire.ultrasonic.domain.MusicFolder
-
-/**
- * This little view shows the currently selected Folder (or catalog) on the music server.
- * When clicked it will drop down a list of all available Folders and allow you to
- * select one. The intended usage is to supply a filter to lists of artists, albums, etc
- */
-class SelectMusicFolderView(
-    private val context: Context,
-    root: ViewGroup,
-    private val onUpdate: (String?) -> Unit
-) : RecyclerView.ViewHolder(
-    LayoutInflater.from(context).inflate(
-        R.layout.select_folder_header, root, false
-    )
-) {
-    private var musicFolders: List<MusicFolder> = mutableListOf<MusicFolder>()
-    private var selectedFolderId: String? = null
-    private val folderName: TextView = itemView.findViewById(R.id.select_folder_name)
-    private val layout: LinearLayout = itemView.findViewById(R.id.select_folder_header)
-    private val MENU_GROUP_MUSIC_FOLDER = 10
-
-    init {
-        folderName.text = context.getString(R.string.select_artist_all_folders)
-        layout.setOnClickListener { onFolderClick() }
-    }
-
-    fun setData(selectedId: String?, folders: List<MusicFolder>) {
-        selectedFolderId = selectedId
-        musicFolders = folders
-        if (selectedFolderId != null) {
-            for ((id, name) in musicFolders) {
-                if (id == selectedFolderId) {
-                    folderName.text = name
-                    break
-                }
-            }
-        } else {
-            folderName.text = context.getString(R.string.select_artist_all_folders)
-        }
-    }
-
-    private fun onFolderClick() {
-        val popup = PopupMenu(context, layout)
-
-        var menuItem = popup.menu.add(
-            MENU_GROUP_MUSIC_FOLDER, -1, 0, R.string.select_artist_all_folders
-        )
-        if (selectedFolderId == null || selectedFolderId!!.isEmpty()) {
-            menuItem.isChecked = true
-        }
-        musicFolders.forEachIndexed { i, musicFolder ->
-            val (id, name) = musicFolder
-            menuItem = popup.menu.add(MENU_GROUP_MUSIC_FOLDER, i, i + 1, name)
-            if (id == selectedFolderId) {
-                menuItem.isChecked = true
-            }
-        }
-
-        popup.menu.setGroupCheckable(MENU_GROUP_MUSIC_FOLDER, true, true)
-
-        popup.setOnMenuItemClickListener { item -> onFolderMenuItemSelected(item) }
-        popup.show()
-    }
-
-    private fun onFolderMenuItemSelected(menuItem: MenuItem): Boolean {
-        val selectedFolder = if (menuItem.itemId == -1) null else musicFolders[menuItem.itemId]
-        val musicFolderName = selectedFolder?.name
-            ?: context.getString(R.string.select_artist_all_folders)
-        selectedFolderId = selectedFolder?.id
-
-        menuItem.isChecked = true
-        folderName.text = musicFolderName
-        onUpdate(selectedFolderId)
-
-        return true
-    }
-}
+package org.moire.ultrasonic.view
+
+import android.content.Context
+import android.view.MenuItem
+import android.view.View
+import android.widget.LinearLayout
+import android.widget.PopupMenu
+import android.widget.TextView
+import androidx.recyclerview.widget.RecyclerView
+import org.moire.ultrasonic.R
+import org.moire.ultrasonic.domain.MusicFolder
+
+/**
+ * This little view shows the currently selected Folder (or catalog) on the music server.
+ * When clicked it will drop down a list of all available Folders and allow you to
+ * select one. The intended usage is to supply a filter to lists of artists, albums, etc
+ */
+class SelectMusicFolderView(
+    private val context: Context,
+    view: View,
+    private val onUpdate: (String?) -> Unit
+) : RecyclerView.ViewHolder(view) {
+    private var musicFolders: List<MusicFolder> = mutableListOf()
+    private var selectedFolderId: String? = null
+    private val folderName: TextView = itemView.findViewById(R.id.select_folder_name)
+    private val layout: LinearLayout = itemView.findViewById(R.id.select_folder_header)
+
+    init {
+        folderName.text = context.getString(R.string.select_artist_all_folders)
+        layout.setOnClickListener { onFolderClick() }
+    }
+
+    fun setData(selectedId: String?, folders: List<MusicFolder>) {
+        selectedFolderId = selectedId
+        musicFolders = folders
+        if (selectedFolderId != null) {
+            for ((id, name) in musicFolders) {
+                if (id == selectedFolderId) {
+                    folderName.text = name
+                    break
+                }
+            }
+        } else {
+            folderName.text = context.getString(R.string.select_artist_all_folders)
+        }
+    }
+
+    private fun onFolderClick() {
+        val popup = PopupMenu(context, layout)
+
+        var menuItem = popup.menu.add(
+            MENU_GROUP_MUSIC_FOLDER, -1, 0, R.string.select_artist_all_folders
+        )
+        if (selectedFolderId == null || selectedFolderId!!.isEmpty()) {
+            menuItem.isChecked = true
+        }
+        musicFolders.forEachIndexed { i, musicFolder ->
+            val (id, name) = musicFolder
+            menuItem = popup.menu.add(MENU_GROUP_MUSIC_FOLDER, i, i + 1, name)
+            if (id == selectedFolderId) {
+                menuItem.isChecked = true
+            }
+        }
+
+        popup.menu.setGroupCheckable(MENU_GROUP_MUSIC_FOLDER, true, true)
+
+        popup.setOnMenuItemClickListener { item -> onFolderMenuItemSelected(item) }
+        popup.show()
+    }
+
+    private fun onFolderMenuItemSelected(menuItem: MenuItem): Boolean {
+        val selectedFolder = if (menuItem.itemId == -1) null else musicFolders[menuItem.itemId]
+        val musicFolderName = selectedFolder?.name
+            ?: context.getString(R.string.select_artist_all_folders)
+        selectedFolderId = selectedFolder?.id
+
+        menuItem.isChecked = true
+        folderName.text = musicFolderName
+        onUpdate(selectedFolderId)
+
+        return true
+    }
+
+    companion object {
+        const val MENU_GROUP_MUSIC_FOLDER = 10
+    }
+}
diff --git a/ultrasonic/src/main/res/drawable-hdpi/unknown_album.png b/ultrasonic/src/main/res/drawable-hdpi/unknown_album.png
deleted file mode 100644
index e59b7868..00000000
Binary files a/ultrasonic/src/main/res/drawable-hdpi/unknown_album.png and /dev/null differ
diff --git a/ultrasonic/src/main/res/drawable/unknown_album.xml b/ultrasonic/src/main/res/drawable/unknown_album.xml
index eae63c63..54f39529 100644
--- a/ultrasonic/src/main/res/drawable/unknown_album.xml
+++ b/ultrasonic/src/main/res/drawable/unknown_album.xml
@@ -1,12 +1,13 @@
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="100dp"
-    android:height="100dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
-    <path
-        android:fillColor="#000"
-        android:pathData="M0 0 L24 0 L24 24 L0 24 Z"/>
-    <path
-        android:fillColor="#FFF"
-        android:pathData="M12,3v10.55c-0.59,-0.34 -1.27,-0.55 -2,-0.55 -2.21,0 -4,1.79 -4,4s1.79,4 4,4 4,-1.79 4,-4V7h4V3h-6z"/>
+    android:width="200dp"
+    android:height="200dp"
+    android:viewportWidth="100"
+    android:viewportHeight="100">
+  <path
+      android:pathData="M0,0h100v100h-100z"
+      android:fillColor="#1a1a1a"/>
+  <path
+      android:pathData="M42.415,84.787C49.463,84.53 55.166,77.789 54.75,70.704 55.614,58.35 56.479,45.979 57.342,33.633c0.513,-0.518 1.407,0.72 1.903,0.815 5.393,3.785 9.987,9.62 9.845,16.528 -0.003,5.402 -1.991,10.554 -4.162,15.413C71.552,59.26 74.281,48.374 70.666,39.149 68.858,33.816 64.197,30.278 61.795,25.279A26.452,26.452 0,0 1,58.5 14.397c-0.343,-0.816 -1.323,-0.945 -2.094,-0.999l-0.017,-0.001c-2.434,-0.17 -2.216,1.472 -2.331,3.117l-3.274,46.814c0,0 -1.255,-0.207 -2.188,-0.272 -7.098,-0.965 -15.202,3.666 -16.437,11.095 -1.246,5.877 4.638,11.171 10.257,10.635z"
+      android:strokeWidth="0.85"
+      android:fillColor="#ffffff"/>
 </vector>