单击片段中的工具栏菜单项 (Kotlin)
ToolBar menu item click in a fragment (Kotlin)
在我的应用程序中,我有一个 Activity,其中有一个 FrameLayout。在这个FrameLayout中,有一个片段,包含一个ToolBar和一个RecyclerView。
在这个工具栏中,我有一个搜索按钮,它应该在项目点击时启动一个 Activity。但是,当我尝试使用 onOptionsItemSelected 时,应用程序已成功构建和安装,但是当我尝试点击有问题的按钮时,没有任何反应。 Logcat,也没说什么。
可以指出我做错了什么吗?是否有更简单或其他更容易的方法来管理工具栏项上的点击?
Fragment.kt
class FragmentTrack : Fragment() {
...
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setHasOptionsMenu(true)
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? = inflater.inflate(R.layout.fragment_track, container, false)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
...
topToolbar.setNavigationOnClickListener {
val dialog = FragmentBottomSheetDrawer()
dialog.show(childFragmentManager, dialog.tag)
}
}
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
inflater.inflate(R.menu.menu_toolbar, menu)
super.onCreateOptionsMenu(menu, inflater)
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
when(item.itemId) {
R.id.fsvSearch -> Toast.makeText(context, "Clicked search button", Toast.LENGTH_SHORT).show()
}
return true
}
}
fragment.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:theme="@style/Theme.Design.NoActionBar">
<androidx.appcompat.widget.Toolbar
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/topToolbar"
android:background="@color/colorPrimaryDark"
app:navigationIcon="@drawable/ic_outline_menu_24"
app:popupTheme="@style/popupMenuThemeDark"
app:titleTextColor="@android:color/white"
app:title="Revo"
app:menu="@menu/menu_toolbar"
app:layout_scrollFlags="scroll|enterAlways" />
</com.google.android.material.appbar.AppBarLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rvTracks"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:clipToPadding="false"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
/>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
toolbar_menu.xml
<?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/fsvSearch"
android:icon="@drawable/ic_search_24px"
android:title="@string/search"
app:showAsAction="always"/>
<item
android:id="@+id/fsvOrder"
android:icon="@drawable/ic_sort_24px"
android:title="@string/sort"
app:showAsAction="ifRoom">
<menu>
<group android:id="@+id/sortMenu" android:checkableBehavior="single">
<item
android:id="@+id/sortIncrease"
android:title="@string/increasing"/>
<item
android:id="@+id/sortDecrease"
android:title="@string/decreasing"/>
<item
android:id="@+id/sortMArtist"
android:title="@string/artist"/>
<item
android:id="@+id/sortAlbum"
android:title="@string/albums"/>
<item
android:id="@+id/sortYear"
android:title="@string/year"/>
<item
android:id="@+id/sortDate"
android:title="@string/date"/>
</group>
</menu>
</item>
<item
android:id="@+id/fsvGrid"
android:icon="@drawable/ic_grid_on_24px"
android:title="@string/grid"
app:showAsAction="ifRoom">
<menu>
<group android:id="@+id/gridMenu" android:checkableBehavior="single">
<item
android:id="@+id/gridOne"
android:title="1"/>
<item
android:id="@+id/gridTwo"
android:title="2"/>
<item
android:id="@+id/gridThree"
android:title="3"/>
<item
android:id="@+id/gridFour"
android:title="4"/>
</group>
</menu>
</item>
</menu>
多亏了一些外部帮助,我找到了解决方案。可以更轻松地处理工具栏项目。
在onViewCreated
方法中,我们必须添加:
topToolbar.inflateMenu(R.menu.menu_toolbar)
topToolbar.setOnMenuItemClickListener {
when(it.itemId) {
R.id.fsvSearch -> //your code
}
true
}
此外,如果菜单重复,请删除工具栏中的 app:menu
标签 xml
感谢 Meltix,我做了很多研究,但 SO 中的大多数帖子都是关于 Java 和老式的 ActionBar。关于 material ToolBar 和 kotlin 示例的信息不多。
就我而言,我正在开发主要使用 Java 开发的旧应用程序,但现在使用 Kotlin 开发新功能。在我的片段中,我无法更改 ActionBar 的图标和行为(我想要一个特定的 ActionBar 用于我的片段)。我找到的解决方案是隐藏 ActionBar 并创建一个工具栏以在其中扩展自定义菜单。我还添加了一个后退箭头按钮(感谢 John:here)。
我得出的结论(也许我错了)您无法从 kotlin 片段管理 ActionBar,这就是您必须使用工具栏的原因。这是我的代码,以防它可以帮助别人。
MyFragment.kt
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
// hide the old actionBar
(activity as AppCompatActivity).supportActionBar!!.hide()
// create the toolbar
val toolbar = binding?.myToolbar
// add the back arrow button, see function below
val resId = getResIdFromAttribute(toolbar.context, android.R.attr.homeAsUpIndicator)
toolbar.navigationIcon = ContextCompat.getDrawable(toolbar.context, resId)
// tapping on the arrow will pop the current fragment
toolbar.setNavigationOnClickListener { parentFragmentManager?.popBackStackImmediate() }
// change toolbar title
toolbar.title = "Some title"
// inflate a custom menu, see code below
toolbar.inflateMenu(R.menu.my_custom_menu)
toolbar.setOnMenuItemClickListener {
when (it.itemId) {
R.id.infoButton -> someAction()
}
true
}
}
// get back arrow icon
@AnyRes
fun getResIdFromAttribute(context: Context, @AttrRes attr: Int): Int {
if (attr == 0) return 0
val typedValueAttr = TypedValue()
context.theme.resolveAttribute(attr, typedValueAttr, true)
return typedValueAttr.resourceId
}
my_fragment.xml
...
<androidx.appcompat.widget.Toolbar
android:id="@+id/myToolBar"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:visibility="visible"
app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
android:background="@color/azulOscuro"
>
</androidx.appcompat.widget.Toolbar>
my_custom_menu.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:jsmovil="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<item
android:id="@+id/infoButton"
android:icon="@drawable/ic_info_blanco"
android:title="@string/tutorial"
android:textColor="@color/blanco"
jsmovil:showAsAction="always"
/>
</menu>
结果
在我的应用程序中,我有一个 Activity,其中有一个 FrameLayout。在这个FrameLayout中,有一个片段,包含一个ToolBar和一个RecyclerView。
在这个工具栏中,我有一个搜索按钮,它应该在项目点击时启动一个 Activity。但是,当我尝试使用 onOptionsItemSelected 时,应用程序已成功构建和安装,但是当我尝试点击有问题的按钮时,没有任何反应。 Logcat,也没说什么。
可以指出我做错了什么吗?是否有更简单或其他更容易的方法来管理工具栏项上的点击?
Fragment.kt
class FragmentTrack : Fragment() {
...
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setHasOptionsMenu(true)
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? = inflater.inflate(R.layout.fragment_track, container, false)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
...
topToolbar.setNavigationOnClickListener {
val dialog = FragmentBottomSheetDrawer()
dialog.show(childFragmentManager, dialog.tag)
}
}
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
inflater.inflate(R.menu.menu_toolbar, menu)
super.onCreateOptionsMenu(menu, inflater)
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
when(item.itemId) {
R.id.fsvSearch -> Toast.makeText(context, "Clicked search button", Toast.LENGTH_SHORT).show()
}
return true
}
}
fragment.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:theme="@style/Theme.Design.NoActionBar">
<androidx.appcompat.widget.Toolbar
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/topToolbar"
android:background="@color/colorPrimaryDark"
app:navigationIcon="@drawable/ic_outline_menu_24"
app:popupTheme="@style/popupMenuThemeDark"
app:titleTextColor="@android:color/white"
app:title="Revo"
app:menu="@menu/menu_toolbar"
app:layout_scrollFlags="scroll|enterAlways" />
</com.google.android.material.appbar.AppBarLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rvTracks"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:clipToPadding="false"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
/>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
toolbar_menu.xml
<?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/fsvSearch"
android:icon="@drawable/ic_search_24px"
android:title="@string/search"
app:showAsAction="always"/>
<item
android:id="@+id/fsvOrder"
android:icon="@drawable/ic_sort_24px"
android:title="@string/sort"
app:showAsAction="ifRoom">
<menu>
<group android:id="@+id/sortMenu" android:checkableBehavior="single">
<item
android:id="@+id/sortIncrease"
android:title="@string/increasing"/>
<item
android:id="@+id/sortDecrease"
android:title="@string/decreasing"/>
<item
android:id="@+id/sortMArtist"
android:title="@string/artist"/>
<item
android:id="@+id/sortAlbum"
android:title="@string/albums"/>
<item
android:id="@+id/sortYear"
android:title="@string/year"/>
<item
android:id="@+id/sortDate"
android:title="@string/date"/>
</group>
</menu>
</item>
<item
android:id="@+id/fsvGrid"
android:icon="@drawable/ic_grid_on_24px"
android:title="@string/grid"
app:showAsAction="ifRoom">
<menu>
<group android:id="@+id/gridMenu" android:checkableBehavior="single">
<item
android:id="@+id/gridOne"
android:title="1"/>
<item
android:id="@+id/gridTwo"
android:title="2"/>
<item
android:id="@+id/gridThree"
android:title="3"/>
<item
android:id="@+id/gridFour"
android:title="4"/>
</group>
</menu>
</item>
</menu>
多亏了一些外部帮助,我找到了解决方案。可以更轻松地处理工具栏项目。
在onViewCreated
方法中,我们必须添加:
topToolbar.inflateMenu(R.menu.menu_toolbar)
topToolbar.setOnMenuItemClickListener {
when(it.itemId) {
R.id.fsvSearch -> //your code
}
true
}
此外,如果菜单重复,请删除工具栏中的 app:menu
标签 xml
感谢 Meltix,我做了很多研究,但 SO 中的大多数帖子都是关于 Java 和老式的 ActionBar。关于 material ToolBar 和 kotlin 示例的信息不多。 就我而言,我正在开发主要使用 Java 开发的旧应用程序,但现在使用 Kotlin 开发新功能。在我的片段中,我无法更改 ActionBar 的图标和行为(我想要一个特定的 ActionBar 用于我的片段)。我找到的解决方案是隐藏 ActionBar 并创建一个工具栏以在其中扩展自定义菜单。我还添加了一个后退箭头按钮(感谢 John:here)。 我得出的结论(也许我错了)您无法从 kotlin 片段管理 ActionBar,这就是您必须使用工具栏的原因。这是我的代码,以防它可以帮助别人。
MyFragment.kt
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
// hide the old actionBar
(activity as AppCompatActivity).supportActionBar!!.hide()
// create the toolbar
val toolbar = binding?.myToolbar
// add the back arrow button, see function below
val resId = getResIdFromAttribute(toolbar.context, android.R.attr.homeAsUpIndicator)
toolbar.navigationIcon = ContextCompat.getDrawable(toolbar.context, resId)
// tapping on the arrow will pop the current fragment
toolbar.setNavigationOnClickListener { parentFragmentManager?.popBackStackImmediate() }
// change toolbar title
toolbar.title = "Some title"
// inflate a custom menu, see code below
toolbar.inflateMenu(R.menu.my_custom_menu)
toolbar.setOnMenuItemClickListener {
when (it.itemId) {
R.id.infoButton -> someAction()
}
true
}
}
// get back arrow icon
@AnyRes
fun getResIdFromAttribute(context: Context, @AttrRes attr: Int): Int {
if (attr == 0) return 0
val typedValueAttr = TypedValue()
context.theme.resolveAttribute(attr, typedValueAttr, true)
return typedValueAttr.resourceId
}
my_fragment.xml
...
<androidx.appcompat.widget.Toolbar
android:id="@+id/myToolBar"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:visibility="visible"
app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
android:background="@color/azulOscuro"
>
</androidx.appcompat.widget.Toolbar>
my_custom_menu.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:jsmovil="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<item
android:id="@+id/infoButton"
android:icon="@drawable/ic_info_blanco"
android:title="@string/tutorial"
android:textColor="@color/blanco"
jsmovil:showAsAction="always"
/>
</menu>
结果