Configurable main navigation
parent
4c2197aa5d
commit
95547a8d03
@ -0,0 +1,33 @@
|
|||||||
|
package org.koitharu.kotatsu.core.prefs
|
||||||
|
|
||||||
|
import androidx.annotation.DrawableRes
|
||||||
|
import androidx.annotation.IdRes
|
||||||
|
import androidx.annotation.StringRes
|
||||||
|
import org.koitharu.kotatsu.R
|
||||||
|
import org.koitharu.kotatsu.list.ui.model.ListModel
|
||||||
|
|
||||||
|
enum class NavItem(
|
||||||
|
@IdRes val id: Int,
|
||||||
|
@StringRes val title: Int,
|
||||||
|
@DrawableRes val icon: Int,
|
||||||
|
) : ListModel {
|
||||||
|
|
||||||
|
HISTORY(R.id.nav_history, R.string.history, R.drawable.ic_history_selector),
|
||||||
|
FAVORITES(R.id.nav_favorites, R.string.favourites, R.drawable.ic_favourites_selector),
|
||||||
|
LOCAL(R.id.nav_local, R.string.on_device, R.drawable.ic_storage_selector),
|
||||||
|
EXPLORE(R.id.nav_explore, R.string.explore, R.drawable.ic_explore_selector),
|
||||||
|
SUGGESTIONS(R.id.nav_suggestions, R.string.suggestions, R.drawable.ic_suggestion_selector),
|
||||||
|
FEED(R.id.nav_feed, R.string.feed, R.drawable.ic_feed_selector),
|
||||||
|
BOOKMARKS(R.id.nav_bookmarks, R.string.bookmarks, R.drawable.ic_bookmark_selector),
|
||||||
|
;
|
||||||
|
|
||||||
|
override fun areItemsTheSame(other: ListModel): Boolean {
|
||||||
|
return other is NavItem && ordinal == other.ordinal
|
||||||
|
}
|
||||||
|
|
||||||
|
fun isAvailable(settings: AppSettings): Boolean = when (this) {
|
||||||
|
SUGGESTIONS -> settings.isSuggestionsEnabled
|
||||||
|
FEED -> settings.isTrackerEnabled
|
||||||
|
else -> true
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,136 @@
|
|||||||
|
package org.koitharu.kotatsu.settings.nav
|
||||||
|
|
||||||
|
import android.content.DialogInterface
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import androidx.core.graphics.Insets
|
||||||
|
import androidx.core.view.updatePadding
|
||||||
|
import androidx.fragment.app.viewModels
|
||||||
|
import androidx.recyclerview.widget.ItemTouchHelper
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
|
import org.koitharu.kotatsu.R
|
||||||
|
import org.koitharu.kotatsu.core.prefs.NavItem
|
||||||
|
import org.koitharu.kotatsu.core.ui.BaseFragment
|
||||||
|
import org.koitharu.kotatsu.core.ui.BaseListAdapter
|
||||||
|
import org.koitharu.kotatsu.core.ui.dialog.RecyclerViewAlertDialog
|
||||||
|
import org.koitharu.kotatsu.core.ui.list.OnListItemClickListener
|
||||||
|
import org.koitharu.kotatsu.core.ui.util.RecyclerViewOwner
|
||||||
|
import org.koitharu.kotatsu.core.util.ext.observe
|
||||||
|
import org.koitharu.kotatsu.databinding.FragmentSettingsSourcesBinding
|
||||||
|
import org.koitharu.kotatsu.list.ui.adapter.ListItemType
|
||||||
|
import org.koitharu.kotatsu.list.ui.model.ListModel
|
||||||
|
import org.koitharu.kotatsu.settings.nav.adapter.navAddAD
|
||||||
|
import org.koitharu.kotatsu.settings.nav.adapter.navAvailableAD
|
||||||
|
import org.koitharu.kotatsu.settings.nav.adapter.navConfigAD
|
||||||
|
|
||||||
|
@AndroidEntryPoint
|
||||||
|
class NavConfigFragment : BaseFragment<FragmentSettingsSourcesBinding>(), RecyclerViewOwner,
|
||||||
|
OnListItemClickListener<NavItem>, View.OnClickListener {
|
||||||
|
|
||||||
|
private var reorderHelper: ItemTouchHelper? = null
|
||||||
|
private val viewModel by viewModels<NavConfigViewModel>()
|
||||||
|
|
||||||
|
override val recyclerView: RecyclerView
|
||||||
|
get() = requireViewBinding().recyclerView
|
||||||
|
|
||||||
|
override fun onCreateViewBinding(
|
||||||
|
inflater: LayoutInflater,
|
||||||
|
container: ViewGroup?,
|
||||||
|
): FragmentSettingsSourcesBinding {
|
||||||
|
return FragmentSettingsSourcesBinding.inflate(inflater, container, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onViewBindingCreated(
|
||||||
|
binding: FragmentSettingsSourcesBinding,
|
||||||
|
savedInstanceState: Bundle?,
|
||||||
|
) {
|
||||||
|
super.onViewBindingCreated(binding, savedInstanceState)
|
||||||
|
val navConfigAdapter = BaseListAdapter<ListModel>()
|
||||||
|
.addDelegate(ListItemType.NAV_ITEM, navConfigAD(this))
|
||||||
|
.addDelegate(ListItemType.FOOTER_LOADING, navAddAD(this))
|
||||||
|
with(binding.recyclerView) {
|
||||||
|
setHasFixedSize(true)
|
||||||
|
adapter = navConfigAdapter
|
||||||
|
reorderHelper = ItemTouchHelper(ReorderCallback()).also {
|
||||||
|
it.attachToRecyclerView(this)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
viewModel.content.observe(viewLifecycleOwner, navConfigAdapter)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onResume() {
|
||||||
|
super.onResume()
|
||||||
|
activity?.setTitle(R.string.main_screen_sections)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onDestroyView() {
|
||||||
|
reorderHelper = null
|
||||||
|
super.onDestroyView()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onWindowInsetsChanged(insets: Insets) {
|
||||||
|
requireViewBinding().recyclerView.updatePadding(
|
||||||
|
bottom = insets.bottom,
|
||||||
|
left = insets.left,
|
||||||
|
right = insets.right,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onClick(v: View) {
|
||||||
|
var dialog: DialogInterface? = null
|
||||||
|
val listener = OnListItemClickListener<NavItem> { item, _ ->
|
||||||
|
viewModel.addItem(item)
|
||||||
|
dialog?.dismiss()
|
||||||
|
}
|
||||||
|
dialog = RecyclerViewAlertDialog.Builder<NavItem>(v.context)
|
||||||
|
.setTitle(R.string.add)
|
||||||
|
.addAdapterDelegate(navAvailableAD(listener))
|
||||||
|
.setCancelable(true)
|
||||||
|
.setItems(viewModel.availableItems)
|
||||||
|
.setNegativeButton(android.R.string.cancel, null)
|
||||||
|
.create()
|
||||||
|
.apply { show() }
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onItemClick(item: NavItem, view: View) {
|
||||||
|
viewModel.removeItem(item)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onItemLongClick(item: NavItem, view: View): Boolean {
|
||||||
|
val holder = viewBinding?.recyclerView?.findContainingViewHolder(view) ?: return false
|
||||||
|
reorderHelper?.startDrag(holder)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
private inner class ReorderCallback : ItemTouchHelper.SimpleCallback(
|
||||||
|
ItemTouchHelper.DOWN or ItemTouchHelper.UP,
|
||||||
|
0,
|
||||||
|
) {
|
||||||
|
|
||||||
|
override fun onMove(
|
||||||
|
recyclerView: RecyclerView,
|
||||||
|
viewHolder: RecyclerView.ViewHolder,
|
||||||
|
target: RecyclerView.ViewHolder,
|
||||||
|
): Boolean = true
|
||||||
|
|
||||||
|
override fun onMoved(
|
||||||
|
recyclerView: RecyclerView,
|
||||||
|
viewHolder: RecyclerView.ViewHolder,
|
||||||
|
fromPos: Int,
|
||||||
|
target: RecyclerView.ViewHolder,
|
||||||
|
toPos: Int,
|
||||||
|
x: Int,
|
||||||
|
y: Int,
|
||||||
|
) {
|
||||||
|
super.onMoved(recyclerView, viewHolder, fromPos, target, toPos, x, y)
|
||||||
|
viewModel.reorder(fromPos, toPos)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) = Unit
|
||||||
|
|
||||||
|
override fun isLongPressDragEnabled() = false
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,80 @@
|
|||||||
|
package org.koitharu.kotatsu.settings.nav
|
||||||
|
|
||||||
|
import androidx.lifecycle.viewModelScope
|
||||||
|
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.Job
|
||||||
|
import kotlinx.coroutines.cancelAndJoin
|
||||||
|
import kotlinx.coroutines.delay
|
||||||
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
|
import kotlinx.coroutines.flow.SharingStarted
|
||||||
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
|
import kotlinx.coroutines.flow.map
|
||||||
|
import kotlinx.coroutines.flow.stateIn
|
||||||
|
import kotlinx.coroutines.plus
|
||||||
|
import org.koitharu.kotatsu.core.prefs.AppSettings
|
||||||
|
import org.koitharu.kotatsu.core.prefs.NavItem
|
||||||
|
import org.koitharu.kotatsu.core.ui.BaseViewModel
|
||||||
|
import org.koitharu.kotatsu.core.ui.util.ActivityRecreationHandle
|
||||||
|
import org.koitharu.kotatsu.list.ui.model.ListModel
|
||||||
|
import org.koitharu.kotatsu.main.ui.MainActivity
|
||||||
|
import org.koitharu.kotatsu.parsers.util.move
|
||||||
|
import org.koitharu.kotatsu.settings.nav.model.NavItemAddModel
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
@HiltViewModel
|
||||||
|
class NavConfigViewModel @Inject constructor(
|
||||||
|
private val settings: AppSettings,
|
||||||
|
private val activityRecreationHandle: ActivityRecreationHandle,
|
||||||
|
) : BaseViewModel() {
|
||||||
|
|
||||||
|
private val items = MutableStateFlow(settings.mainNavItems)
|
||||||
|
|
||||||
|
val content: StateFlow<List<ListModel>> = items.map { snapshot ->
|
||||||
|
if (snapshot.size < NavItem.entries.size) {
|
||||||
|
snapshot + NavItemAddModel(snapshot.size < 5)
|
||||||
|
} else {
|
||||||
|
snapshot
|
||||||
|
}
|
||||||
|
}.stateIn(
|
||||||
|
viewModelScope + Dispatchers.Default,
|
||||||
|
SharingStarted.WhileSubscribed(5000),
|
||||||
|
emptyList()
|
||||||
|
)
|
||||||
|
|
||||||
|
private var commitJob: Job? = null
|
||||||
|
|
||||||
|
val availableItems
|
||||||
|
get() = items.value.let { snapshot ->
|
||||||
|
NavItem.entries.filterNot { x -> x in snapshot }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun reorder(fromPos: Int, toPos: Int) {
|
||||||
|
items.value = items.value.toMutableList().apply {
|
||||||
|
move(fromPos, toPos)
|
||||||
|
commit(this)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun addItem(item: NavItem) {
|
||||||
|
items.value = items.value.plus(item).also {
|
||||||
|
commit(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun removeItem(item: NavItem) {
|
||||||
|
items.value = items.value.minus(item).also {
|
||||||
|
commit(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun commit(value: List<NavItem>) {
|
||||||
|
val prevJob = commitJob
|
||||||
|
commitJob = launchJob {
|
||||||
|
prevJob?.cancelAndJoin()
|
||||||
|
delay(500)
|
||||||
|
settings.mainNavItems = value
|
||||||
|
activityRecreationHandle.recreate(MainActivity::class.java)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,73 @@
|
|||||||
|
package org.koitharu.kotatsu.settings.nav.adapter
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint
|
||||||
|
import android.view.MotionEvent
|
||||||
|
import android.view.View
|
||||||
|
import com.hannesdorfmann.adapterdelegates4.dsl.adapterDelegateViewBinding
|
||||||
|
import org.koitharu.kotatsu.R
|
||||||
|
import org.koitharu.kotatsu.core.prefs.NavItem
|
||||||
|
import org.koitharu.kotatsu.core.ui.list.OnListItemClickListener
|
||||||
|
import org.koitharu.kotatsu.databinding.ItemNavAvailableBinding
|
||||||
|
import org.koitharu.kotatsu.databinding.ItemNavConfigBinding
|
||||||
|
import org.koitharu.kotatsu.list.ui.model.ListModel
|
||||||
|
import org.koitharu.kotatsu.settings.nav.model.NavItemAddModel
|
||||||
|
|
||||||
|
@SuppressLint("ClickableViewAccessibility")
|
||||||
|
fun navConfigAD(
|
||||||
|
clickListener: OnListItemClickListener<NavItem>,
|
||||||
|
) = adapterDelegateViewBinding<NavItem, ListModel, ItemNavConfigBinding>(
|
||||||
|
{ layoutInflater, parent -> ItemNavConfigBinding.inflate(layoutInflater, parent, false) },
|
||||||
|
) {
|
||||||
|
|
||||||
|
val eventListener = object : View.OnClickListener, View.OnTouchListener {
|
||||||
|
override fun onClick(v: View) = clickListener.onItemClick(item, v)
|
||||||
|
|
||||||
|
override fun onTouch(v: View?, event: MotionEvent): Boolean =
|
||||||
|
event.actionMasked == MotionEvent.ACTION_DOWN &&
|
||||||
|
clickListener.onItemLongClick(item, itemView)
|
||||||
|
}
|
||||||
|
binding.imageViewRemove.setOnClickListener(eventListener)
|
||||||
|
binding.imageViewReorder.setOnTouchListener(eventListener)
|
||||||
|
|
||||||
|
bind {
|
||||||
|
with(binding.textViewTitle) {
|
||||||
|
setText(item.title)
|
||||||
|
setCompoundDrawablesRelativeWithIntrinsicBounds(item.icon, 0, 0, 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun navAvailableAD(
|
||||||
|
clickListener: OnListItemClickListener<NavItem>,
|
||||||
|
) = adapterDelegateViewBinding<NavItem, NavItem, ItemNavAvailableBinding>(
|
||||||
|
{ layoutInflater, parent -> ItemNavAvailableBinding.inflate(layoutInflater, parent, false) },
|
||||||
|
) {
|
||||||
|
|
||||||
|
binding.root.setOnClickListener { v ->
|
||||||
|
clickListener.onItemClick(item, v)
|
||||||
|
}
|
||||||
|
|
||||||
|
bind {
|
||||||
|
with(binding.root) {
|
||||||
|
setText(item.title)
|
||||||
|
setCompoundDrawablesRelativeWithIntrinsicBounds(item.icon, 0, 0, 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun navAddAD(
|
||||||
|
clickListener: View.OnClickListener,
|
||||||
|
) = adapterDelegateViewBinding<NavItemAddModel, ListModel, ItemNavAvailableBinding>(
|
||||||
|
{ layoutInflater, parent -> ItemNavAvailableBinding.inflate(layoutInflater, parent, false) },
|
||||||
|
) {
|
||||||
|
|
||||||
|
binding.root.setOnClickListener(clickListener)
|
||||||
|
binding.root.setCompoundDrawablesRelativeWithIntrinsicBounds(R.drawable.ic_add, 0, 0, 0)
|
||||||
|
|
||||||
|
bind {
|
||||||
|
with(binding.root) {
|
||||||
|
setText(if (item.canAdd) R.string.add else R.string.items_limit_exceeded)
|
||||||
|
isEnabled = item.canAdd
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,10 @@
|
|||||||
|
package org.koitharu.kotatsu.settings.nav.model
|
||||||
|
|
||||||
|
import org.koitharu.kotatsu.list.ui.model.ListModel
|
||||||
|
|
||||||
|
data class NavItemAddModel(
|
||||||
|
val canAdd: Boolean,
|
||||||
|
) : ListModel {
|
||||||
|
|
||||||
|
override fun areItemsTheSame(other: ListModel): Boolean = other is NavItemAddModel
|
||||||
|
}
|
||||||
@ -0,0 +1,12 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?><!-- drawable/bookmark.xml -->
|
||||||
|
<vector
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:tint="?attr/colorControlNormal"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24">
|
||||||
|
<path
|
||||||
|
android:fillColor="#000000"
|
||||||
|
android:pathData="M17,3H7A2,2 0 0,0 5,5V21L12,18L19,21V5C19,3.89 18.1,3 17,3Z" />
|
||||||
|
</vector>
|
||||||
@ -0,0 +1,12 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<item
|
||||||
|
android:id="@+id/normal"
|
||||||
|
android:drawable="@drawable/ic_bookmark"
|
||||||
|
android:state_checked="false" />
|
||||||
|
|
||||||
|
<item
|
||||||
|
android:id="@+id/checked"
|
||||||
|
android:drawable="@drawable/ic_bookmark_checked"
|
||||||
|
android:state_checked="true" />
|
||||||
|
</selector>
|
||||||
@ -0,0 +1,12 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?><!-- drawable/sd.xml -->
|
||||||
|
<vector
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:tint="?attr/colorControlNormal"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24">
|
||||||
|
<path
|
||||||
|
android:fillColor="#000000"
|
||||||
|
android:pathData="M18,8H16V4H18M15,8H13V4H15M12,8H10V4H12M18,2H10L4,8V20A2,2 0 0,0 6,22H18A2,2 0 0,0 20,20V4A2,2 0 0,0 18,2Z" />
|
||||||
|
</vector>
|
||||||
@ -0,0 +1,12 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<item
|
||||||
|
android:id="@+id/normal"
|
||||||
|
android:drawable="@drawable/ic_storage"
|
||||||
|
android:state_checked="false" />
|
||||||
|
|
||||||
|
<item
|
||||||
|
android:id="@+id/checked"
|
||||||
|
android:drawable="@drawable/ic_storage_checked"
|
||||||
|
android:state_checked="true" />
|
||||||
|
</selector>
|
||||||
@ -0,0 +1,12 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?><!-- drawable/lightbulb.xml -->
|
||||||
|
<vector
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:tint="?attr/colorControlNormal"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24">
|
||||||
|
<path
|
||||||
|
android:fillColor="#000000"
|
||||||
|
android:pathData="M12,2A7,7 0 0,0 5,9C5,11.38 6.19,13.47 8,14.74V17A1,1 0 0,0 9,18H15A1,1 0 0,0 16,17V14.74C17.81,13.47 19,11.38 19,9A7,7 0 0,0 12,2M9,21A1,1 0 0,0 10,22H14A1,1 0 0,0 15,21V20H9V21Z" />
|
||||||
|
</vector>
|
||||||
@ -0,0 +1,13 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<item
|
||||||
|
android:id="@+id/normal"
|
||||||
|
android:drawable="@drawable/ic_suggestion"
|
||||||
|
android:state_checked="false" />
|
||||||
|
|
||||||
|
<item
|
||||||
|
android:id="@+id/checked"
|
||||||
|
android:drawable="@drawable/ic_suggestion_checked"
|
||||||
|
android:state_checked="true" />
|
||||||
|
</selector>
|
||||||
|
|
||||||
@ -0,0 +1,19 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<TextView
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="?selectableItemBackground"
|
||||||
|
android:drawablePadding="?listPreferredItemPaddingStart"
|
||||||
|
android:ellipsize="end"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:minHeight="?android:listPreferredItemHeightSmall"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:paddingVertical="@dimen/margin_small"
|
||||||
|
android:paddingStart="?listPreferredItemPaddingStart"
|
||||||
|
android:paddingEnd="?listPreferredItemPaddingEnd"
|
||||||
|
android:singleLine="true"
|
||||||
|
android:textAppearance="?attr/textAppearanceBodyLarge"
|
||||||
|
tools:drawableStartCompat="@drawable/ic_feed"
|
||||||
|
tools:text="@string/feed" />
|
||||||
@ -0,0 +1,47 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="?android:windowBackground"
|
||||||
|
android:baselineAligned="false"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:paddingVertical="@dimen/margin_small"
|
||||||
|
android:paddingStart="?listPreferredItemPaddingStart"
|
||||||
|
android:paddingEnd="?listPreferredItemPaddingEnd">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/textView_title"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:drawablePadding="?listPreferredItemPaddingStart"
|
||||||
|
android:ellipsize="end"
|
||||||
|
android:singleLine="true"
|
||||||
|
android:textAppearance="?attr/textAppearanceBodyLarge"
|
||||||
|
tools:drawableStart="@drawable/ic_explore_selector"
|
||||||
|
tools:text="@string/explore" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/imageView_remove"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="?selectableItemBackgroundBorderless"
|
||||||
|
android:contentDescription="@string/remove"
|
||||||
|
android:padding="@dimen/margin_small"
|
||||||
|
android:scaleType="center"
|
||||||
|
android:src="@drawable/ic_delete" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/imageView_reorder"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="?selectableItemBackgroundBorderless"
|
||||||
|
android:contentDescription="@string/reorder"
|
||||||
|
android:padding="@dimen/margin_small"
|
||||||
|
android:scaleType="center"
|
||||||
|
android:src="@drawable/ic_reorder_handle" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
@ -1,25 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<menu
|
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android">
|
|
||||||
|
|
||||||
<item
|
|
||||||
android:id="@+id/nav_history"
|
|
||||||
android:icon="@drawable/ic_history_selector"
|
|
||||||
android:title="@string/history" />
|
|
||||||
|
|
||||||
<item
|
|
||||||
android:id="@+id/nav_favourites"
|
|
||||||
android:icon="@drawable/ic_favourites_selector"
|
|
||||||
android:title="@string/favourites" />
|
|
||||||
|
|
||||||
<item
|
|
||||||
android:id="@+id/nav_explore"
|
|
||||||
android:icon="@drawable/ic_explore_selector"
|
|
||||||
android:title="@string/explore" />
|
|
||||||
|
|
||||||
<item
|
|
||||||
android:id="@+id/nav_feed"
|
|
||||||
android:icon="@drawable/ic_feed_selector"
|
|
||||||
android:title="@string/feed" />
|
|
||||||
|
|
||||||
</menu>
|
|
||||||
@ -1,25 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<menu
|
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android">
|
|
||||||
|
|
||||||
<item
|
|
||||||
android:id="@+id/nav_favourites"
|
|
||||||
android:icon="@drawable/ic_favourites_selector"
|
|
||||||
android:title="@string/favourites" />
|
|
||||||
|
|
||||||
<item
|
|
||||||
android:id="@+id/nav_history"
|
|
||||||
android:icon="@drawable/ic_history_selector"
|
|
||||||
android:title="@string/history" />
|
|
||||||
|
|
||||||
<item
|
|
||||||
android:id="@+id/nav_explore"
|
|
||||||
android:icon="@drawable/ic_explore_selector"
|
|
||||||
android:title="@string/explore" />
|
|
||||||
|
|
||||||
<item
|
|
||||||
android:id="@+id/nav_feed"
|
|
||||||
android:icon="@drawable/ic_feed_selector"
|
|
||||||
android:title="@string/feed" />
|
|
||||||
|
|
||||||
</menu>
|
|
||||||
Loading…
Reference in New Issue