【问题标题】:Toolbar menu onOptionsItemSelected does not work from fragment工具栏菜单 onOptionsItemSelected 在片段中不起作用
【发布时间】:2020-10-17 04:18:05
【问题描述】:

当用户使用导航组件单击工具栏中的菜单时,我正在尝试更改当前片段,但是我根本无法从片段中获取菜单!我正在使用带有 2 个片段的底部导航栏,每个片段都有不同的工具栏菜单项,我没有使用导航抽屉。 这是来自 HomeFragment.kt 的一个小 sn-p:

override​ ​fun​ ​onCreateView​(
    inflater​:​ ​LayoutInflater​, ​container​:​ ​ViewGroup?​,
    savedInstanceState​:​ ​Bundle?​
)​:​ ​View?​ {
    activity?.title ​=​ getString(​R​.string.title_home)
    setHasOptionsMenu(​true​)

    return​ inflater.inflate(​R​.layout.fragment_home, container, ​false​)
}

override​ ​fun​ ​onCreateOptionsMenu​(​menu​:​ ​Menu​, ​inflater​:​ ​MenuInflater​) {
    inflater.inflate(​R​.menu.toolbar_menu, menu)
    super​ .onCreateOptionsMenu(menu, inflater)
}

override​ ​fun​ ​onOptionsItemSelected​(​item​:​ ​MenuItem​)​:​ ​Boolean​ {
    when​ (item.itemId) {
         R​.id.toolbar_about ​-​>​ {
            activity?.findNavController(​R​.id.bottom_nav_host)?.navigate(​R​.id.toAboutFragment)
             Toast​.makeText(context, ​"​You clicked on About menu​"​, ​Toast​.​LENGTH_SHORT​).show()
        }
        else​ ​-​>​ ​super​.onOptionsItemSelected(item)
    }
    return​ ​true​
}

它甚至不显示我指定的 Toast。谁能帮助我?提前致谢!

【问题讨论】:

  • 这可能与您的主机活动有关 - 您在哪里将 supportActionBar 设置到您的工具栏? - 哪个布局包含应添加菜单的工具栏、您的活动或片段?
  • 我在 MainActivity 中设置了 supportActionBar (这是除了 Splashscreenactivity 和用于主题和语言的 baseactivity 之外的唯一活动)onCreate 方法,包含工具栏的布局是 activity_main.xml

标签: android android-toolbar android-architecture-navigation


【解决方案1】:

您可以在主机 Activity 上打开菜单。如果你想在 Fragment 上打开它,你可以使用 context。检查下面的代码。

public class FragmentEditProfile extends Fragment {
    Context m_context;      //Context

    public static FragmentEditProfile newInstance() {
        return new FragmentEditProfile();
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        // Get context of host activity.
        m_context = getContext();
        super.onCreate(savedInstanceState);
    }

    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View fragmentLayout = inflater.inflate(R.layout.fragment_profile_edit, container, false);

        // setNavigationOnClickListener of the host activity.
        ((MainActivity)m_context).toolbar.setNavigationOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //Open the menu using context of host activity
                ((MainActivity) m_context).openDrawer();
            }
        });
        return fragmentLayout;
    }
}

如果您有任何问题,请告诉我。希望能有所帮助。

【讨论】:

  • 嗨,我想我没有具体说明一些事情,我的错。我没有抽屉,我只有一个菜单项应该使用导航组件替换当前片段。我已经直接从片段设置了菜单项(我想在不同的片段上有不同的工具栏菜单)但是无论出于何种原因单击该菜单项都不起作用。我正在使用底部导航栏
  • Fragment 不能覆盖 Activity 的函数。我建议您使用主机活动的上下文。
  • ((MainActivity) m_context).onCreateOptionsMenu() 可以这样使用。
  • 谢谢,我会试试的
  • 如果您有任何问题,请告诉我。祝你成功!
【解决方案2】:

我设法通过直接从活动而不是片段调用onOptionsItemSelected 来解决此问题。所以我的最终代码如下所示:
HomeFragment.kt:

//We set menu from fragment
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) { 
    inflater.inflate(R.menu.toolbar_menu, menu)
    super .onCreateOptionsMenu(menu, inflater) 
}

MainActivity.kt:

override fun onOptionsItemSelected(item: MenuItem): Boolean { 
    val navHost = findNavController(R.id.bottom_nav_host) 
    when (item.itemId) { 
        android.R.id.home -> { 
            onBackPressed() 
            return true 
        }
        //This one is for our fragment toolbar menu
        R.id.toolbar_about -> { 
            navHost.navigate(R.id.toAboutFragment) 
            return true 
        }
    }
    return false
}

【讨论】:

    【解决方案3】:

    有几件事可以检查

    1)样式应用主题

    <resources>
    <style name="AppThem
    parent="Theme.AppCompat.Light.DarkActionBar"> ..... 
    
    1. MainActivity 专注于此
    • setupBottomNavigationBar()controller.observe(this, Observer { navController -> setupActionBarWithNavController(navController) }) currentNavController = 控制器

    除非将主要活动设置为支持片段中的操作栏,否则片段代码将不起作用。我花了一段时间才明白这一点......

        class MainActivity : AppCompatActivity() {
        private var currentNavController: LiveData<NavController>? = null
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_main)
        if (savedInstanceState == null) {
                setupBottomNavigationBar()}
        override fun onRestoreInstanceState(savedInstanceState: Bundle) {
            super.onRestoreInstanceState(savedInstanceState)
        setupBottomNavigationBar()
        }
    
    
        private fun setupBottomNavigationBar() {
            val bottomNavigationView = findViewById<BottomNavigationView>(R.id.bottom_nav)
            val navGraphIds = listOf(R.navigation.signin, R.navigation.register, R.navigation.elections_list)
    
            val controller = bottomNavigationView.setupWithNavController(
                navGraphIds = navGraphIds,
                fragmentManager = supportFragmentManager,
                containerId = R.id.nav_host_container,
                intent = intent
            )     
           controller.observe(this, Observer { navController ->
               setupActionBarWithNavController(navController) })
            currentNavController = controller
        }
        override fun onSupportNavigateUp(): Boolean {
            return currentNavController?.value?.navigateUp() ?: false
        }
      companion object
        }
    
    1. 在您的菜单/menu_collections 中。这只是一个工作示例。大部分内容来自https://www.youtube.com/watch?v=DMkzIOLppf4Coding in Flow 的生产

    菜单代码

    <menu
         android:id="@+id/menu_collections_new"
    xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto">
        <item android:id="@+id/men_item1"
            android:icon="@drawable/ic_icon"
            android:title="item1"
            app:showAsAction="ifRoom"/>
            <item android:id="@+id/men_item2"
                app:showAsAction="never"
                android:title="item2"
                />
            <item android:id="@+id/men_item3"
                android:title="item3"
                app:showAsAction="never">
            <menu>
            <item
             android:id="@+id/subitem1"
            android:title="Subitem1"/>
            <item
                android:id="@+id/subitem2"
                android:title="Subitem2"/>
            </menu>
            </item>
            </menu>
    
    1. 片段代码 在实际片段 FragmentOne.kt 中设置正确的代码 注意 super.onCreateOptionsMenu(menu, inflater)inflater.inflate(R.menu.menu_collections_new, menu)

      覆盖 fun onCreate(savedInstanceState: Bundle?) { setHasOptionsMenu(true) super.onCreate(savedInstanceState) }

      override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
       inflater.inflate(R.menu.menu_collections_new, menu)
       super.onCreateOptionsMenu(menu, inflater)
       }
      
       override fun onOptionsItemSelected(item: MenuItem): Boolean {
      
           when (item.itemId) {
               R.id.men_item1-> onSignOutClicked( "item1")
               R.id.men_item2 -> onSignOutClicked("item2")
               R.id.men_item3 ->onSignOutClicked("item3")
           }
           return super.onOptionsItemSelected(item)
      
      
           private fun onSignOutClicked(description:String) {
           Log.d(TAG,"dja 193 options menu selected $description")
           }
      

    【讨论】:

      猜你喜欢
      • 2016-05-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多