Add search to LibraryFragment

Add searching to LibraryFragment.
This commit is contained in:
OxygenCobalt 2020-10-03 09:14:49 -06:00
parent 3a44ce7e43
commit 69c508caec
19 changed files with 184 additions and 59 deletions

View file

@ -1,19 +1,19 @@
TODO: TODO:
? - Could do with some more research. TODOs surrounded with ?s are things I want to do, but need to do more research on and may be a nightmare to implement.
! - Tried to do, but is completely broken. TODOs surrounded with !s are things I tried to do, but failed for reasons included in the TODO. I still want to add these, but theres no way for me to do them at the moment.
/detail/ /detail/
- ? Implement Toolbar update functionality ? - ? Implement Toolbar update functionality ?
- ! Implement shared element transitions ! - ! Implement shared element transitions [Return transitions are broken] !
/music/ /music/
- Add option to show all genres - Add option to show all genres
- ! Move genres to songs ! - ! Move genres to songs [Wont find songs w/o genres]!
- ! Remove lists from music models ! - ! Remove lists from music models [Current genre loading system makes it impossible] !
- ! Dont determine track/album/artist counts on the fly ! - ! Dont determine track/album/artist counts on the fly [Audio columns for those values are broken] !
/songs/ /songs/
@ -23,12 +23,13 @@ TODO:
/library/ /library/
- Search
- Exit functionality - Exit functionality
- ? Remove gap from where I removed the overflow menu ?
- ? Add icons to overflow menu items ?
- ? Show Artists, Albums, and Songs in search ? - ? Show Artists, Albums, and Songs in search ?
- ? Implement filtering for above ^^^ [Will resolve gap issue] ?
- ? Move into ViewPager ? - ? Move into ViewPager ?
- ! Move Adapter functionality to ListAdapter! - ! Move Adapter functionality to ListAdapter [RecyclerView scrolls to middle/bottom when data is re-sorted] !
To be added: To be added:
/prefs/ /prefs/

View file

@ -11,7 +11,9 @@
android:roundIcon="@mipmap/ic_launcher_round" android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true" android:supportsRtl="true"
android:theme="@style/Theme.Base"> android:theme="@style/Theme.Base">
<activity android:name=".MainActivity"> <activity android:name=".MainActivity"
android:windowSoftInputMode="adjustPan">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN" />

View file

@ -13,7 +13,6 @@ import androidx.navigation.fragment.navArgs
import org.oxycblt.auxio.R import org.oxycblt.auxio.R
import org.oxycblt.auxio.databinding.FragmentArtistDetailBinding import org.oxycblt.auxio.databinding.FragmentArtistDetailBinding
import org.oxycblt.auxio.detail.adapters.DetailAlbumAdapter import org.oxycblt.auxio.detail.adapters.DetailAlbumAdapter
import org.oxycblt.auxio.music.Album
import org.oxycblt.auxio.music.MusicViewModel import org.oxycblt.auxio.music.MusicViewModel
import org.oxycblt.auxio.recycler.ClickListener import org.oxycblt.auxio.recycler.ClickListener
import org.oxycblt.auxio.theme.applyDivider import org.oxycblt.auxio.theme.applyDivider

View file

@ -13,7 +13,6 @@ import androidx.navigation.fragment.navArgs
import org.oxycblt.auxio.R import org.oxycblt.auxio.R
import org.oxycblt.auxio.databinding.FragmentGenreDetailBinding import org.oxycblt.auxio.databinding.FragmentGenreDetailBinding
import org.oxycblt.auxio.detail.adapters.DetailArtistAdapter import org.oxycblt.auxio.detail.adapters.DetailArtistAdapter
import org.oxycblt.auxio.music.Artist
import org.oxycblt.auxio.music.MusicViewModel import org.oxycblt.auxio.music.MusicViewModel
import org.oxycblt.auxio.recycler.ClickListener import org.oxycblt.auxio.recycler.ClickListener
import org.oxycblt.auxio.theme.applyDivider import org.oxycblt.auxio.theme.applyDivider

View file

@ -22,7 +22,7 @@ class LibraryAdapter(
private val listener: ClickListener<BaseModel> private val listener: ClickListener<BaseModel>
) : RecyclerView.Adapter<RecyclerView.ViewHolder>() { ) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
private var data: List<BaseModel> var data: List<BaseModel>
init { init {
// Assign the data on startup depending on the type // Assign the data on startup depending on the type

View file

@ -5,11 +5,14 @@ import android.util.Log
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.appcompat.widget.SearchView
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.core.view.forEach import androidx.core.view.forEach
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels import androidx.fragment.app.activityViewModels
import androidx.navigation.fragment.findNavController import androidx.navigation.fragment.findNavController
import androidx.transition.Fade
import androidx.transition.TransitionManager
import org.oxycblt.auxio.MainFragmentDirections import org.oxycblt.auxio.MainFragmentDirections
import org.oxycblt.auxio.R import org.oxycblt.auxio.R
import org.oxycblt.auxio.databinding.FragmentLibraryBinding import org.oxycblt.auxio.databinding.FragmentLibraryBinding
@ -26,7 +29,7 @@ import org.oxycblt.auxio.theme.applyColor
import org.oxycblt.auxio.theme.applyDivider import org.oxycblt.auxio.theme.applyDivider
import org.oxycblt.auxio.theme.resolveAttr import org.oxycblt.auxio.theme.resolveAttr
class LibraryFragment : Fragment() { class LibraryFragment : Fragment(), SearchView.OnQueryTextListener {
private val musicModel: MusicViewModel by activityViewModels() private val musicModel: MusicViewModel by activityViewModels()
private val libraryModel: LibraryViewModel by activityViewModels() private val libraryModel: LibraryViewModel by activityViewModels()
@ -38,12 +41,52 @@ class LibraryFragment : Fragment() {
): View? { ): View? {
val binding = FragmentLibraryBinding.inflate(inflater) val binding = FragmentLibraryBinding.inflate(inflater)
val artistAdapter = LibraryAdapter( // Toolbar setup
binding.libraryToolbar.overflowIcon = ContextCompat.getDrawable(
requireContext(), R.drawable.ic_sort_none
)
binding.libraryToolbar.menu.apply {
val item = findItem(R.id.action_search)
val searchView = item.actionView as SearchView
searchView.queryHint = getString(R.string.hint_search_library)
searchView.setOnQueryTextListener(this@LibraryFragment)
searchView.setOnQueryTextFocusChangeListener { _, hasFocus ->
this.setGroupVisible(R.id.group_sorting, !hasFocus)
// Make sure the search item will still be visible, and then do an animation
item.isVisible = !hasFocus
TransitionManager.beginDelayedTransition(
binding.libraryToolbar, Fade()
)
item.collapseActionView()
}
}
binding.libraryToolbar.setOnMenuItemClickListener {
if (it.itemId != R.id.action_search) {
libraryModel.updateSortMode(it)
} else {
// Do whatever this is in order to make the SearchView focusable.
(it.actionView as SearchView).isIconified = false
// Then also do a basic animation
TransitionManager.beginDelayedTransition(
binding.libraryToolbar, Fade()
)
it.expandActionView()
}
true
}
val libraryAdapter = LibraryAdapter(
libraryModel.showMode.value!!, libraryModel.showMode.value!!,
ClickListener { navToItem(it) } ClickListener { navToItem(it) }
) )
binding.libraryRecycler.adapter = artistAdapter // RecyclerView setup
binding.libraryRecycler.adapter = libraryAdapter
binding.libraryRecycler.applyDivider() binding.libraryRecycler.applyDivider()
binding.libraryRecycler.setHasFixedSize(true) binding.libraryRecycler.setHasFixedSize(true)
@ -51,7 +94,7 @@ class LibraryFragment : Fragment() {
Log.d(this::class.simpleName, "Updating sort mode to $mode") Log.d(this::class.simpleName, "Updating sort mode to $mode")
// Update the adapter with the new data // Update the adapter with the new data
artistAdapter.updateData( libraryAdapter.updateData(
when (libraryModel.showMode.value) { when (libraryModel.showMode.value) {
SHOW_GENRES -> mode.getSortedGenreList(musicModel.genres.value!!) SHOW_GENRES -> mode.getSortedGenreList(musicModel.genres.value!!)
SHOW_ARTISTS -> mode.getSortedArtistList(musicModel.artists.value!!) SHOW_ARTISTS -> mode.getSortedArtistList(musicModel.artists.value!!)
@ -61,12 +104,7 @@ class LibraryFragment : Fragment() {
} }
) )
// Then update the shown icon & the currently highlighted sort icon to reflect // Then update the menu item in the toolbar to reflect the new mode
// the new sorting mode.
binding.libraryToolbar.overflowIcon = ContextCompat.getDrawable(
requireContext(), mode.iconRes
)
binding.libraryToolbar.menu.forEach { binding.libraryToolbar.menu.forEach {
if (it.itemId == libraryModel.sortMode.value!!.toMenuId()) { if (it.itemId == libraryModel.sortMode.value!!.toMenuId()) {
it.applyColor(resolveAttr(requireContext(), R.attr.colorPrimary)) it.applyColor(resolveAttr(requireContext(), R.attr.colorPrimary))
@ -76,10 +114,17 @@ class LibraryFragment : Fragment() {
} }
} }
binding.libraryToolbar.setOnMenuItemClickListener { libraryModel.searchQuery.observe(viewLifecycleOwner) { query ->
libraryModel.updateSortMode(it) // Update the adapter with the new data
libraryAdapter.updateData(
when (libraryModel.showMode.value) {
SHOW_GENRES -> musicModel.genres.value!!
SHOW_ARTISTS -> musicModel.artists.value!!
SHOW_ALBUMS -> musicModel.albums.value!!
true else -> musicModel.artists.value!!
}.filter { it.name.contains(query, true) }
)
} }
Log.d(this::class.simpleName, "Fragment created.") Log.d(this::class.simpleName, "Fragment created.")
@ -87,6 +132,14 @@ class LibraryFragment : Fragment() {
return binding.root return binding.root
} }
override fun onQueryTextSubmit(query: String): Boolean = false
override fun onQueryTextChange(query: String): Boolean {
libraryModel.updateSearchQuery(query)
return false
}
private fun navToItem(baseModel: BaseModel) { private fun navToItem(baseModel: BaseModel) {
Log.d(this::class.simpleName, "Navigating to the detail fragment for ${baseModel.name}") Log.d(this::class.simpleName, "Navigating to the detail fragment for ${baseModel.name}")

View file

@ -8,7 +8,7 @@ import org.oxycblt.auxio.R
import org.oxycblt.auxio.recycler.SortMode import org.oxycblt.auxio.recycler.SortMode
import org.oxycblt.auxio.theme.SHOW_ARTISTS import org.oxycblt.auxio.theme.SHOW_ARTISTS
class LibraryViewModel : ViewModel() { class LibraryViewModel() : ViewModel() {
// TODO: Move these to prefs when they're added // TODO: Move these to prefs when they're added
private val mShowMode = MutableLiveData(SHOW_ARTISTS) private val mShowMode = MutableLiveData(SHOW_ARTISTS)
val showMode: LiveData<Int> get() = mShowMode val showMode: LiveData<Int> get() = mShowMode
@ -16,11 +16,14 @@ class LibraryViewModel : ViewModel() {
private val mSortMode = MutableLiveData(SortMode.ALPHA_DOWN) private val mSortMode = MutableLiveData(SortMode.ALPHA_DOWN)
val sortMode: LiveData<SortMode> get() = mSortMode val sortMode: LiveData<SortMode> get() = mSortMode
private val mSearchQuery = MutableLiveData("")
val searchQuery: LiveData<String> get() = mSearchQuery
fun updateSortMode(item: MenuItem) { fun updateSortMode(item: MenuItem) {
val mode = when (item.itemId) { val mode = when (item.itemId) {
R.id.sort_none -> SortMode.NONE R.id.option_sort_none -> SortMode.NONE
R.id.sort_alpha_down -> SortMode.ALPHA_DOWN R.id.option_sort_alpha_down -> SortMode.ALPHA_DOWN
R.id.sort_alpha_up -> SortMode.ALPHA_UP R.id.option_sort_alpha_up -> SortMode.ALPHA_UP
else -> SortMode.NONE else -> SortMode.NONE
} }
@ -29,4 +32,8 @@ class LibraryViewModel : ViewModel() {
mSortMode.value = mode mSortMode.value = mode
} }
} }
fun updateSearchQuery(query: String) {
mSearchQuery.value = query
}
} }

View file

@ -3,6 +3,7 @@ package org.oxycblt.auxio.recycler
import org.oxycblt.auxio.R import org.oxycblt.auxio.R
import org.oxycblt.auxio.music.Album import org.oxycblt.auxio.music.Album
import org.oxycblt.auxio.music.Artist import org.oxycblt.auxio.music.Artist
import org.oxycblt.auxio.music.BaseModel
import org.oxycblt.auxio.music.Genre import org.oxycblt.auxio.music.Genre
import org.oxycblt.auxio.music.Song import org.oxycblt.auxio.music.Song
@ -77,13 +78,30 @@ enum class SortMode(val iconRes: Int) {
} }
} }
fun getSortedBaseModelList(list: List<BaseModel>): List<BaseModel> {
return when (this) {
ALPHA_UP -> list.sortedWith(
compareByDescending(String.CASE_INSENSITIVE_ORDER) { it.name }
)
ALPHA_DOWN -> list.sortedWith(
compareBy(String.CASE_INSENSITIVE_ORDER) { it.name }
)
NUMERIC_UP -> list.sortedWith(compareByDescending { it.id })
NUMERIC_DOWN -> list.sortedWith(compareBy { it.id })
else -> list
}
}
fun toMenuId(): Int { fun toMenuId(): Int {
return when (this) { return when (this) {
NONE -> R.id.sort_none NONE -> R.id.option_sort_none
ALPHA_UP -> R.id.sort_alpha_up ALPHA_UP -> R.id.option_sort_alpha_up
ALPHA_DOWN -> R.id.sort_alpha_down ALPHA_DOWN -> R.id.option_sort_alpha_down
else -> R.id.sort_none else -> R.id.option_sort_none
} }
} }
} }

View file

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Custom cursor shape that reflects the current accent color.
https://stackoverflow.com/a/28311351/14143986
-->
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >
<solid android:color="?android:attr/colorPrimary" />
<size android:width="2dp" />
</shape>

View file

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M15.5,14h-0.79l-0.28,-0.27C15.41,12.59 16,11.11 16,9.5 16,5.91 13.09,3 9.5,3S3,5.91 3,9.5 5.91,16 9.5,16c1.61,0 3.09,-0.59 4.23,-1.57l0.27,0.28v0.79l5,4.99L20.49,19l-4.99,-5zM9.5,14C7.01,14 5,11.99 5,9.5S7.01,5 9.5,5 14,7.01 14,9.5 11.99,14 9.5,14z"/>
</vector>

View file

@ -4,7 +4,7 @@
android:height="24dp" android:height="24dp"
android:viewportWidth="24" android:viewportWidth="24"
android:viewportHeight="24" android:viewportHeight="24"
android:tint="?attr/colorPrimary"> android:tint="?android:attr/colorControlNormal">
<path <path
android:fillColor="@android:color/white" android:fillColor="@android:color/white"
android:pathData="M3,18h6v-2L3,16v2zM3,6v2h18L21,6L3,6zM3,13h12v-2L3,11v2z" /> android:pathData="M3,18h6v-2L3,16v2zM3,6v2h18L21,6L3,6zM3,13h12v-2L3,11v2z" />

View file

@ -25,7 +25,7 @@
android:layout_height="?android:attr/actionBarSize" android:layout_height="?android:attr/actionBarSize"
android:background="?android:attr/windowBackground" android:background="?android:attr/windowBackground"
android:elevation="@dimen/elevation_normal" android:elevation="@dimen/elevation_normal"
app:titleTextAppearance="@style/TextAppearance.Toolbar.Bold" app:titleTextAppearance="@style/TextAppearance.Toolbar.Header"
app:navigationIcon="@drawable/ic_back" app:navigationIcon="@drawable/ic_back"
app:title="@string/title_library_fragment" /> app:title="@string/title_library_fragment" />

View file

@ -25,7 +25,7 @@
android:layout_height="?android:attr/actionBarSize" android:layout_height="?android:attr/actionBarSize"
android:background="?android:attr/windowBackground" android:background="?android:attr/windowBackground"
android:elevation="@dimen/elevation_normal" android:elevation="@dimen/elevation_normal"
app:titleTextAppearance="@style/TextAppearance.Toolbar.Bold" app:titleTextAppearance="@style/TextAppearance.Toolbar.Header"
app:navigationIcon="@drawable/ic_back" app:navigationIcon="@drawable/ic_back"
app:title="@string/title_library_fragment" /> app:title="@string/title_library_fragment" />

View file

@ -25,7 +25,7 @@
android:layout_height="?android:attr/actionBarSize" android:layout_height="?android:attr/actionBarSize"
android:background="?android:attr/windowBackground" android:background="?android:attr/windowBackground"
android:elevation="@dimen/elevation_normal" android:elevation="@dimen/elevation_normal"
app:titleTextAppearance="@style/TextAppearance.Toolbar.Bold" app:titleTextAppearance="@style/TextAppearance.Toolbar.Header"
app:navigationIcon="@drawable/ic_back" app:navigationIcon="@drawable/ic_back"
app:title="@string/title_library_fragment" /> app:title="@string/title_library_fragment" />

View file

@ -7,8 +7,7 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:orientation="vertical" android:orientation="vertical"
android:animateLayoutChanges="true" android:animateLayoutChanges="true">
android:descendantFocusability="blocksDescendants">
<androidx.appcompat.widget.Toolbar <androidx.appcompat.widget.Toolbar
android:id="@+id/library_toolbar" android:id="@+id/library_toolbar"
@ -16,10 +15,11 @@
android:layout_height="?android:attr/actionBarSize" android:layout_height="?android:attr/actionBarSize"
android:background="?android:attr/windowBackground" android:background="?android:attr/windowBackground"
android:elevation="@dimen/elevation_normal" android:elevation="@dimen/elevation_normal"
android:theme="@style/Toolbar.Style"
app:popupTheme="@style/AppThemeOverlay.Popup" app:popupTheme="@style/AppThemeOverlay.Popup"
app:menu="@menu/menu_library" app:menu="@menu/menu_library"
app:titleTextAppearance="@style/TextAppearance.Toolbar.Bold" app:titleTextAppearance="@style/TextAppearance.Toolbar.Header"
app:title="@string/title_library_fragment" /> app:title="@string/title_library_fragment"/>
<androidx.recyclerview.widget.RecyclerView <androidx.recyclerview.widget.RecyclerView
android:id="@+id/library_recycler" android:id="@+id/library_recycler"

View file

@ -15,7 +15,7 @@
android:layout_height="?android:attr/actionBarSize" android:layout_height="?android:attr/actionBarSize"
android:background="?android:attr/windowBackground" android:background="?android:attr/windowBackground"
android:elevation="@dimen/elevation_normal" android:elevation="@dimen/elevation_normal"
app:titleTextAppearance="@style/TextAppearance.Toolbar.Bold" app:titleTextAppearance="@style/TextAppearance.Toolbar.Header"
app:title="@string/title_all_songs" /> app:title="@string/title_all_songs" />
<androidx.recyclerview.widget.RecyclerView <androidx.recyclerview.widget.RecyclerView

View file

@ -1,18 +1,29 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"> <menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item <item
android:id="@+id/sort_none" android:id="@+id/action_search"
android:icon="@drawable/ic_sort_none" android:icon="@drawable/ic_search"
android:title="@string/label_sort_none" android:title="@string/label_search"
android:contentDescription="@string/description_sort_none" /> app:actionViewClass="androidx.appcompat.widget.SearchView"
<item app:showAsAction="collapseActionView|always" />
android:id="@+id/sort_alpha_down"
android:icon="@drawable/ic_sort_alpha_down" <group android:id="@+id/group_sorting">
android:title="@string/label_sort_alpha_down" <item
android:contentDescription="@string/description_sort_alpha_down" /> android:id="@+id/option_sort_none"
<item android:icon="@drawable/ic_sort_none"
android:id="@+id/sort_alpha_up" android:title="@string/label_sort_none"
android:icon="@drawable/ic_sort_alpha_up" android:contentDescription="@string/description_sort_none" />
android:title="@string/label_sort_alpha_up" <item
android:contentDescription="@string/description_sort_alpha_up" /> android:id="@+id/option_sort_alpha_down"
android:icon="@drawable/ic_sort_alpha_down"
android:title="@string/label_sort_alpha_down"
android:contentDescription="@string/description_sort_alpha_down" />
<item
android:id="@+id/option_sort_alpha_up"
android:icon="@drawable/ic_sort_alpha_up"
android:title="@string/label_sort_alpha_up"
android:contentDescription="@string/description_sort_alpha_up" />
</group>
</menu> </menu>

View file

@ -17,10 +17,14 @@
<string name="label_artists">Artists</string> <string name="label_artists">Artists</string>
<string name="label_albums">Albums</string> <string name="label_albums">Albums</string>
<string name="label_songs">Songs</string> <string name="label_songs">Songs</string>
<string name="label_search">Search</string>
<string name="label_sort_none">Default</string> <string name="label_sort_none">Default</string>
<string name="label_sort_alpha_down">A-Z</string> <string name="label_sort_alpha_down">A-Z</string>
<string name="label_sort_alpha_up">Z-A</string> <string name="label_sort_alpha_up">Z-A</string>
<!-- Hint Namespace | EditText Hints -->
<string name="hint_search_library">Search Library…</string>
<!-- Description Namespace | Accessibility Strings --> <!-- Description Namespace | Accessibility Strings -->
<string name="description_album_cover">Album Cover for %s</string> <string name="description_album_cover">Album Cover for %s</string>
<string name="description_artist_image">Artist Image for %s</string> <string name="description_artist_image">Artist Image for %s</string>

View file

@ -5,14 +5,24 @@
<item name="android:windowBackground">@color/background</item> <item name="android:windowBackground">@color/background</item>
<item name="android:statusBarColor">@android:color/black</item> <item name="android:statusBarColor">@android:color/black</item>
<item name="android:fontFamily">@font/inter</item> <item name="android:fontFamily">@font/inter</item>
<item name="android:textCursorDrawable">@drawable/cursor</item>
<item name="actionBarPopupTheme">@style/AppThemeOverlay.Popup</item> <item name="actionBarPopupTheme">@style/AppThemeOverlay.Popup</item>
</style> </style>
<style name="TextAppearance.Toolbar.Bold" parent="TextAppearance.Widget.AppCompat.Toolbar.Title"> <style name="Toolbar.Style" parent="ThemeOverlay.MaterialComponents.ActionBar">
<item name="android:searchViewStyle">@style/Toolbar.SearchViewStyle</item>
</style>
<style name="TextAppearance.Toolbar.Header" parent="TextAppearance.Widget.AppCompat.Toolbar.Title">
<item name="android:fontFamily">@font/inter_black</item> <item name="android:fontFamily">@font/inter_black</item>
<item name="android:textColor">?android:attr/colorPrimary</item> <item name="android:textColor">?android:attr/colorPrimary</item>
</style> </style>
<style name="Toolbar.SearchViewStyle" parent="Widget.AppCompat.SearchView">
<item name="android:searchIcon">@drawable/ic_search</item>
<item name="android:closeIcon">@drawable/ic_back</item>
</style>
<style name="DetailHeader"> <style name="DetailHeader">
<item name="android:textAppearance">?android:attr/textAppearanceLarge</item> <item name="android:textAppearance">?android:attr/textAppearanceLarge</item>
<item name="android:textColor">?android:attr/colorPrimary</item> <item name="android:textColor">?android:attr/colorPrimary</item>