Show manga list by author
This commit is contained in:
@@ -1,13 +1,15 @@
|
|||||||
package org.koitharu.kotatsu.ui.common
|
package org.koitharu.kotatsu.ui.common
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import android.view.View
|
||||||
import androidx.annotation.DrawableRes
|
import androidx.annotation.DrawableRes
|
||||||
import com.google.android.material.chip.Chip
|
import com.google.android.material.chip.Chip
|
||||||
import org.koitharu.kotatsu.utils.ext.getThemeColor
|
import org.koitharu.kotatsu.utils.ext.getThemeColor
|
||||||
|
|
||||||
class ChipsFactory(private val context: Context) {
|
class ChipsFactory(private val context: Context) {
|
||||||
|
|
||||||
fun create(convertView: Chip? = null, text: CharSequence, @DrawableRes iconRes: Int = 0, tag: Any? = null): Chip {
|
fun create(convertView: Chip? = null, text: CharSequence, @DrawableRes iconRes: Int = 0,
|
||||||
|
tag: Any? = null, onClickListener: View.OnClickListener? = null): Chip {
|
||||||
val chip = convertView ?: Chip(context).apply {
|
val chip = convertView ?: Chip(context).apply {
|
||||||
setTextColor(context.getThemeColor(android.R.attr.textColorPrimary))
|
setTextColor(context.getThemeColor(android.R.attr.textColorPrimary))
|
||||||
isCloseIconVisible = false
|
isCloseIconVisible = false
|
||||||
@@ -20,6 +22,7 @@ class ChipsFactory(private val context: Context) {
|
|||||||
chip.setChipIconResource(iconRes)
|
chip.setChipIconResource(iconRes)
|
||||||
}
|
}
|
||||||
chip.tag = tag
|
chip.tag = tag
|
||||||
|
chip.setOnClickListener(onClickListener)
|
||||||
return chip
|
return chip
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,9 +1,11 @@
|
|||||||
package org.koitharu.kotatsu.ui.details
|
package org.koitharu.kotatsu.ui.details
|
||||||
|
|
||||||
import android.text.Spanned
|
import android.text.Spanned
|
||||||
|
import android.view.View
|
||||||
import androidx.core.text.parseAsHtml
|
import androidx.core.text.parseAsHtml
|
||||||
import androidx.core.view.isVisible
|
import androidx.core.view.isVisible
|
||||||
import coil.api.load
|
import coil.api.load
|
||||||
|
import com.google.android.material.chip.Chip
|
||||||
import kotlinx.android.synthetic.main.fragment_details.*
|
import kotlinx.android.synthetic.main.fragment_details.*
|
||||||
import moxy.ktx.moxyPresenter
|
import moxy.ktx.moxyPresenter
|
||||||
import org.koitharu.kotatsu.R
|
import org.koitharu.kotatsu.R
|
||||||
@@ -13,11 +15,12 @@ import org.koitharu.kotatsu.core.model.MangaHistory
|
|||||||
import org.koitharu.kotatsu.ui.common.BaseFragment
|
import org.koitharu.kotatsu.ui.common.BaseFragment
|
||||||
import org.koitharu.kotatsu.ui.main.list.favourites.categories.FavouriteCategoriesDialog
|
import org.koitharu.kotatsu.ui.main.list.favourites.categories.FavouriteCategoriesDialog
|
||||||
import org.koitharu.kotatsu.ui.reader.ReaderActivity
|
import org.koitharu.kotatsu.ui.reader.ReaderActivity
|
||||||
|
import org.koitharu.kotatsu.ui.search.MangaSearchSheet
|
||||||
import org.koitharu.kotatsu.utils.ext.addChips
|
import org.koitharu.kotatsu.utils.ext.addChips
|
||||||
import org.koitharu.kotatsu.utils.ext.textAndVisible
|
import org.koitharu.kotatsu.utils.ext.textAndVisible
|
||||||
import kotlin.math.roundToInt
|
import kotlin.math.roundToInt
|
||||||
|
|
||||||
class MangaDetailsFragment : BaseFragment(R.layout.fragment_details), MangaDetailsView {
|
class MangaDetailsFragment : BaseFragment(R.layout.fragment_details), MangaDetailsView, View.OnClickListener {
|
||||||
|
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
private val presenter by moxyPresenter(factory = MangaDetailsPresenter.Companion::getInstance)
|
private val presenter by moxyPresenter(factory = MangaDetailsPresenter.Companion::getInstance)
|
||||||
@@ -47,7 +50,9 @@ class MangaDetailsFragment : BaseFragment(R.layout.fragment_details), MangaDetai
|
|||||||
chips_tags.addChips(listOf(a)) {
|
chips_tags.addChips(listOf(a)) {
|
||||||
create(
|
create(
|
||||||
text = it,
|
text = it,
|
||||||
iconRes = R.drawable.ic_chip_user
|
iconRes = R.drawable.ic_chip_user,
|
||||||
|
tag = it,
|
||||||
|
onClickListener = this@MangaDetailsFragment
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -55,7 +60,8 @@ class MangaDetailsFragment : BaseFragment(R.layout.fragment_details), MangaDetai
|
|||||||
create(
|
create(
|
||||||
text = it.title,
|
text = it.title,
|
||||||
iconRes = R.drawable.ic_chip_tag,
|
iconRes = R.drawable.ic_chip_tag,
|
||||||
tag = it
|
tag = it,
|
||||||
|
onClickListener = this@MangaDetailsFragment
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
imageView_favourite.setOnClickListener {
|
imageView_favourite.setOnClickListener {
|
||||||
@@ -87,6 +93,15 @@ class MangaDetailsFragment : BaseFragment(R.layout.fragment_details), MangaDetai
|
|||||||
|
|
||||||
override fun onMangaRemoved(manga: Manga) = Unit //handled in activity
|
override fun onMangaRemoved(manga: Manga) = Unit //handled in activity
|
||||||
|
|
||||||
|
override fun onClick(v: View) {
|
||||||
|
if (v is Chip) {
|
||||||
|
when(val tag = v.tag) {
|
||||||
|
is String -> MangaSearchSheet.show(activity?.supportFragmentManager ?: childFragmentManager,
|
||||||
|
manga?.source ?: return, tag)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun updateReadButton() {
|
private fun updateReadButton() {
|
||||||
if (manga?.chapters.isNullOrEmpty()) {
|
if (manga?.chapters.isNullOrEmpty()) {
|
||||||
button_read.isEnabled = false
|
button_read.isEnabled = false
|
||||||
|
|||||||
@@ -0,0 +1,196 @@
|
|||||||
|
package org.koitharu.kotatsu.ui.main.list
|
||||||
|
|
||||||
|
import android.content.SharedPreferences
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.view.MenuItem
|
||||||
|
import android.view.View
|
||||||
|
import androidx.appcompat.widget.Toolbar
|
||||||
|
import androidx.core.view.isGone
|
||||||
|
import androidx.core.view.isVisible
|
||||||
|
import androidx.recyclerview.widget.DividerItemDecoration
|
||||||
|
import androidx.recyclerview.widget.GridLayoutManager
|
||||||
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import com.google.android.material.bottomsheet.BottomSheetBehavior
|
||||||
|
import com.google.android.material.bottomsheet.BottomSheetDialog
|
||||||
|
import com.google.android.material.snackbar.Snackbar
|
||||||
|
import kotlinx.android.synthetic.main.sheet_list.*
|
||||||
|
import moxy.MvpDelegate
|
||||||
|
import org.koin.android.ext.android.inject
|
||||||
|
import org.koitharu.kotatsu.R
|
||||||
|
import org.koitharu.kotatsu.core.model.Manga
|
||||||
|
import org.koitharu.kotatsu.core.model.MangaFilter
|
||||||
|
import org.koitharu.kotatsu.core.model.MangaTag
|
||||||
|
import org.koitharu.kotatsu.core.model.SortOrder
|
||||||
|
import org.koitharu.kotatsu.core.prefs.AppSettings
|
||||||
|
import org.koitharu.kotatsu.core.prefs.ListMode
|
||||||
|
import org.koitharu.kotatsu.ui.common.BaseBottomSheet
|
||||||
|
import org.koitharu.kotatsu.ui.common.list.OnRecyclerItemClickListener
|
||||||
|
import org.koitharu.kotatsu.ui.common.list.PaginationScrollListener
|
||||||
|
import org.koitharu.kotatsu.ui.common.list.decor.SpacingItemDecoration
|
||||||
|
import org.koitharu.kotatsu.ui.details.MangaDetailsActivity
|
||||||
|
import org.koitharu.kotatsu.utils.UiUtils
|
||||||
|
import org.koitharu.kotatsu.utils.ext.*
|
||||||
|
|
||||||
|
abstract class MangaListSheet<E> : BaseBottomSheet(R.layout.sheet_list), MangaListView<E>,
|
||||||
|
PaginationScrollListener.Callback, OnRecyclerItemClickListener<Manga>,
|
||||||
|
SharedPreferences.OnSharedPreferenceChangeListener, Toolbar.OnMenuItemClickListener {
|
||||||
|
|
||||||
|
private val settings by inject<AppSettings>()
|
||||||
|
|
||||||
|
private var adapter: MangaListAdapter? = null
|
||||||
|
|
||||||
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
adapter = MangaListAdapter(this)
|
||||||
|
initListMode(settings.listMode)
|
||||||
|
recyclerView.adapter = adapter
|
||||||
|
recyclerView.addOnScrollListener(PaginationScrollListener(4, this))
|
||||||
|
settings.subscribe(this)
|
||||||
|
toolbar.inflateMenu(R.menu.opt_list_sheet)
|
||||||
|
toolbar.setOnMenuItemClickListener(this)
|
||||||
|
toolbar.setNavigationOnClickListener {
|
||||||
|
dismiss()
|
||||||
|
}
|
||||||
|
if (dialog !is BottomSheetDialog) {
|
||||||
|
toolbar.isVisible = true
|
||||||
|
textView_title.isVisible = false
|
||||||
|
appbar.elevation = resources.getDimension(R.dimen.elevation_large)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onDestroyView() {
|
||||||
|
settings.unsubscribe(this)
|
||||||
|
adapter = null
|
||||||
|
super.onDestroyView()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||||
|
super.onActivityCreated(savedInstanceState)
|
||||||
|
if (savedInstanceState?.containsKey(MvpDelegate.MOXY_DELEGATE_TAGS_KEY) != true) {
|
||||||
|
onRequestMoreItems(0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected fun setTitle(title: CharSequence) {
|
||||||
|
toolbar.title = title
|
||||||
|
textView_title.text = title
|
||||||
|
}
|
||||||
|
|
||||||
|
protected fun setSubtitle(subtitle: CharSequence) {
|
||||||
|
toolbar.subtitle = subtitle
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreateDialog(savedInstanceState: Bundle?) =
|
||||||
|
super.onCreateDialog(savedInstanceState).also {
|
||||||
|
val behavior = (it as? BottomSheetDialog)?.behavior ?: return@also
|
||||||
|
behavior.addBottomSheetCallback(object : BottomSheetBehavior.BottomSheetCallback() {
|
||||||
|
private val elevation = resources.getDimension(R.dimen.elevation_large)
|
||||||
|
|
||||||
|
override fun onSlide(bottomSheet: View, slideOffset: Float) = Unit
|
||||||
|
|
||||||
|
override fun onStateChanged(bottomSheet: View, newState: Int) {
|
||||||
|
if (newState == BottomSheetBehavior.STATE_EXPANDED) {
|
||||||
|
toolbar.isVisible = true
|
||||||
|
textView_title.isVisible = false
|
||||||
|
appbar.elevation = elevation
|
||||||
|
} else {
|
||||||
|
toolbar.isVisible = false
|
||||||
|
textView_title.isVisible = true
|
||||||
|
appbar.elevation = 0f
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onMenuItemClick(item: MenuItem) = when (item.itemId) {
|
||||||
|
R.id.action_list_mode -> {
|
||||||
|
ListModeSelectDialog.show(childFragmentManager)
|
||||||
|
true
|
||||||
|
}
|
||||||
|
else -> false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences, key: String) {
|
||||||
|
when (key) {
|
||||||
|
getString(R.string.key_list_mode) -> initListMode(settings.listMode)
|
||||||
|
getString(R.string.key_grid_size) -> UiUtils.SpanCountResolver.update(recyclerView)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onItemClick(item: Manga, position: Int, view: View) {
|
||||||
|
startActivity(MangaDetailsActivity.newIntent(context ?: return, item))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onListChanged(list: List<Manga>) {
|
||||||
|
adapter?.replaceData(list)
|
||||||
|
textView_holder.isVisible = list.isEmpty()
|
||||||
|
recyclerView.callOnScrollListeners()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onListAppended(list: List<Manga>) {
|
||||||
|
adapter?.appendData(list)
|
||||||
|
if (list.isNotEmpty()) {
|
||||||
|
textView_holder.isVisible = false
|
||||||
|
}
|
||||||
|
recyclerView.callOnScrollListeners()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onListError(e: Throwable) {
|
||||||
|
Snackbar.make(recyclerView, e.getDisplayMessage(resources), Snackbar.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onInitFilter(
|
||||||
|
sortOrders: List<SortOrder>,
|
||||||
|
tags: List<MangaTag>,
|
||||||
|
currentFilter: MangaFilter?
|
||||||
|
) = Unit
|
||||||
|
|
||||||
|
override fun onItemRemoved(item: Manga) {
|
||||||
|
adapter?.let {
|
||||||
|
it.removeItem(item)
|
||||||
|
textView_holder.isGone = it.hasItems
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onError(e: Throwable) {
|
||||||
|
Snackbar.make(recyclerView, e.getDisplayMessage(resources), Snackbar.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onLoadingStateChanged(isLoading: Boolean) {
|
||||||
|
progressBar.isVisible = isLoading && !recyclerView.hasItems
|
||||||
|
if (isLoading) {
|
||||||
|
textView_holder.isVisible = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun initListMode(mode: ListMode) {
|
||||||
|
val ctx = context ?: return
|
||||||
|
val position = recyclerView.firstItem
|
||||||
|
recyclerView.adapter = null
|
||||||
|
recyclerView.layoutManager = null
|
||||||
|
recyclerView.clearItemDecorations()
|
||||||
|
recyclerView.removeOnLayoutChangeListener(UiUtils.SpanCountResolver)
|
||||||
|
adapter?.listMode = mode
|
||||||
|
recyclerView.layoutManager = when (mode) {
|
||||||
|
ListMode.GRID -> GridLayoutManager(ctx, UiUtils.resolveGridSpanCount(ctx))
|
||||||
|
else -> LinearLayoutManager(ctx)
|
||||||
|
}
|
||||||
|
recyclerView.adapter = adapter
|
||||||
|
recyclerView.addItemDecoration(
|
||||||
|
when (mode) {
|
||||||
|
ListMode.LIST -> DividerItemDecoration(ctx, RecyclerView.VERTICAL)
|
||||||
|
ListMode.DETAILED_LIST,
|
||||||
|
ListMode.GRID -> SpacingItemDecoration(
|
||||||
|
resources.getDimensionPixelOffset(R.dimen.grid_spacing)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
if (mode == ListMode.GRID) {
|
||||||
|
recyclerView.addOnLayoutChangeListener(UiUtils.SpanCountResolver)
|
||||||
|
}
|
||||||
|
adapter?.notifyDataSetChanged()
|
||||||
|
recyclerView.firstItem = position
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
package org.koitharu.kotatsu.ui.search
|
||||||
|
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.view.View
|
||||||
|
import androidx.fragment.app.FragmentManager
|
||||||
|
import moxy.ktx.moxyPresenter
|
||||||
|
import org.koitharu.kotatsu.R
|
||||||
|
import org.koitharu.kotatsu.core.model.MangaSource
|
||||||
|
import org.koitharu.kotatsu.ui.main.list.MangaListSheet
|
||||||
|
import org.koitharu.kotatsu.utils.ext.withArgs
|
||||||
|
|
||||||
|
class MangaSearchSheet : MangaListSheet<Unit>() {
|
||||||
|
|
||||||
|
private val presenter by moxyPresenter(factory = ::SearchPresenter)
|
||||||
|
|
||||||
|
private lateinit var source: MangaSource
|
||||||
|
private lateinit var query: String
|
||||||
|
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
source = requireArguments().getParcelable(ARG_SOURCE)!!
|
||||||
|
query = requireArguments().getString(ARG_QUERY).orEmpty()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
|
||||||
|
setTitle(query)
|
||||||
|
setSubtitle(getString(R.string.search_results_on_s, source.title))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onRequestMoreItems(offset: Int) {
|
||||||
|
presenter.loadList(source, query, offset)
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
|
||||||
|
private const val ARG_SOURCE = "source"
|
||||||
|
private const val ARG_QUERY = "query"
|
||||||
|
|
||||||
|
private const val TAG = "MangaSearchSheet"
|
||||||
|
|
||||||
|
fun show(fm: FragmentManager, source: MangaSource, query: String) {
|
||||||
|
MangaSearchSheet().withArgs(2) {
|
||||||
|
putParcelable(ARG_SOURCE, source)
|
||||||
|
putString(ARG_QUERY, query)
|
||||||
|
}.show(fm, TAG)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
77
app/src/main/res/layout/sheet_list.xml
Normal file
77
app/src/main/res/layout/sheet_list.xml
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout
|
||||||
|
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:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<com.google.android.material.appbar.AppBarLayout
|
||||||
|
android:id="@+id/appbar"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="?attr/actionBarSize"
|
||||||
|
android:background="?android:windowBackground"
|
||||||
|
android:elevation="0dp"
|
||||||
|
app:elevation="0dp">
|
||||||
|
|
||||||
|
<com.google.android.material.appbar.MaterialToolbar
|
||||||
|
android:id="@+id/toolbar"
|
||||||
|
style="@style/Widget.MaterialComponents.Toolbar.Surface"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:elevation="0dp"
|
||||||
|
android:outlineProvider="@null"
|
||||||
|
android:visibility="gone"
|
||||||
|
app:elevation="0dp"
|
||||||
|
app:navigationIcon="@drawable/ic_cross"
|
||||||
|
tools:visibility="visible" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/textView_title"
|
||||||
|
style="@style/MaterialAlertDialog.MaterialComponents.Title.Text"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:padding="16dp"
|
||||||
|
android:textColor="?android:textColorSecondary"
|
||||||
|
tools:visibility="gone" />
|
||||||
|
|
||||||
|
</com.google.android.material.appbar.AppBarLayout>
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:minHeight="120dp">
|
||||||
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/recyclerView"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:scrollbars="vertical"
|
||||||
|
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
|
||||||
|
tools:listitem="@layout/item_manga_list" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/textView_holder"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:gravity="center"
|
||||||
|
android:textAppearance="?android:textAppearanceMedium"
|
||||||
|
android:textColor="?android:textColorSecondary"
|
||||||
|
tools:text="@tools:sample/lorem[3]" />
|
||||||
|
|
||||||
|
<ProgressBar
|
||||||
|
android:id="@+id/progressBar"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:indeterminate="true"
|
||||||
|
android:visibility="gone" />
|
||||||
|
|
||||||
|
</FrameLayout>
|
||||||
|
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
12
app/src/main/res/menu/opt_list_sheet.xml
Normal file
12
app/src/main/res/menu/opt_list_sheet.xml
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<menu
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||||
|
|
||||||
|
<item
|
||||||
|
android:id="@+id/action_list_mode"
|
||||||
|
android:orderInCategory="20"
|
||||||
|
android:title="@string/list_mode"
|
||||||
|
app:showAsAction="never" />
|
||||||
|
|
||||||
|
</menu>
|
||||||
Reference in New Issue
Block a user