How to handle onContextItemSelected in a multi fragment activity?

前端 未结 11 2076
天命终不由人
天命终不由人 2020-11-29 17:26

I\'m currently trying to adapt my application to use the \"Compatibility Libraries for Android v4\" to provide the benefits of the usage of fragments even to Android 1.6 use

相关标签:
11条回答
  • 2020-11-29 17:57

    Another one solution:

    @Override
    public boolean onContextItemSelected(MenuItem item) {
        if (getUserVisibleHint()) {
            // context menu logic
            return true;
        }
        return false;
    }
    

    Based upon this patch from Jake Wharton.

    0 讨论(0)
  • 2020-11-29 17:57

    In my first fragment, i have set all my menu id > 5000 so, as first line of code of onContextItemSelected of first fragment i have

    if (item.getItemId() < 5000) return false;
    

    and the second fragment will be invoked.

    0 讨论(0)
  • 2020-11-29 18:00

    I liked the simple solution by Sergei G (based on Jake Wharton fix), but inverted because it is easier to add to several fragments:

    public boolean onContextItemSelected(android.view.MenuItem item) 
    {  
        if( getUserVisibleHint() == false ) 
        {
            return false;
        }
    
        // The rest of your onConextItemSelect code
        AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
     }
    

    After that, the code same as it was before.

    0 讨论(0)
  • 2020-11-29 18:04

    I'll post an answer even though you found a workaround because I just dealt with a similar issue. When you inflate the context menu for a specific fragment, assign each menu item a groupId that is unique to the fragment. Then test for the groupId in 'onContextItemSelected.' For Example:

    public void onCreateContextMenu(ContextMenu menu, View v,ContextMenuInfo menuInfo) {
        menu.add(UNIQUE_FRAGMENT_GROUP_ID, MENU_OPTION_1, 0, R.string.src1);
        menu.add(UNIQUE_FRAGMENT_GROUP_ID, MENU_OPTION_2, 0, R.string.src2);
    }
    public boolean onContextItemSelected(MenuItem item) {
        //only this fragment's context menus have group ID of -1
        if (item.getGroupId() == UNIQUE_FRAGMENT_GROUP_ID) {
            switch(item.getItemId()) {
            case MENU_OPTION_1: doSomething(); break;
            case MENU_OPTION_2: doSomethingElse(); break;
        }
    }
    

    This way all of your fragments will still receive calls to 'onContextItemSelected,' but only the correct one will respond, thus avoiding the need to write activity-level code. I assume a modified version of this technique could work even though you aren't using 'menu.add(...)'

    0 讨论(0)
  • 2020-11-29 18:04

    I found out a very easy solution. As onCreateContextMenu() is called every time the ContextMenu is created I set a boolean variable to true.

    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
        super.onCreateContextMenu(menu, v, menuInfo);
        MenuInflater inflater = getActivity().getMenuInflater();
        inflater.inflate(R.menu.film_menu, menu);
        bMenu=true;
    }
    

    The only other thing I have to do is ask for that variable OnContextItemSelected()

    public boolean onContextItemSelected(MenuItem item) {
        if (bMenu) {
            bMenu=false;
            if (item.getItemId() == R.id.filmProperties) {
                ///Your code
                return true;
            } else {
                return super.onContextItemSelected(item);
            }
        } else {
            return super.onContextItemSelected(item);
        }
    }
    

    That's it.

    0 讨论(0)
  • 2020-11-29 18:04

    IMHO we may just check if target view is child of fragment listview. It is very simple and work for me well. I just added to all my fragments:if (getListView.getPositionForView(info.targetView) == -1) return false when migrate from older API

    This is example from one of my parent fragments. This is Scala, but I hope you got an idea.

    @Loggable
    override def onContextItemSelected(menuItem: MenuItem): Boolean = {
      for {
        filterBlock <- TabContent.filterBlock
        optionBlock <- TabContent.optionBlock
        environmentBlock <- TabContent.environmentBlock
        componentBlock <- TabContent.componentBlock
      } yield menuItem.getMenuInfo match {
      case info: AdapterContextMenuInfo =>
        if (getListView.getPositionForView(info.targetView) == -1)
          return false
        TabContent.adapter.getItem(info.position) match {
          case item: FilterBlock.Item =>
            filterBlock.onContextItemSelected(menuItem, item)
          case item: OptionBlock.Item =>
            optionBlock.onContextItemSelected(menuItem, item)
          case item: EnvironmentBlock.Item =>
            environmentBlock.onContextItemSelected(menuItem, item)
          case item: ComponentBlock.Item =>
            componentBlock.onContextItemSelected(menuItem, item)
          case item =>
            log.debug("skip unknown context menu item " + info.targetView)
            false
        }
      case info =>
        log.fatal("unsupported menu info " + info)
        false
      }
    } getOrElse false
    

    P.S. If you trace calls of onContextItemSelected(...) you may notify that super.onContextItemSelected(item) return always false. Valid onContextItemSelected invoked AFTER, not WITHIN. So super.onContextItemSelected(item) is useless and I replaced it with false.

    0 讨论(0)
提交回复
热议问题