2014-04-16 178 views
0

我正在自定义WebView内创建自定义上下文操作栏(CAB)。嵌套上下文操作栏

我的要求是,从第一个CAB中选择一个特定的选项将打开第二个CAB。这是最终目标:

When the user enters selection mode, this CAB appears. When they tap the highlighter, this second CAB appears.

我做了这一点,但选择工作不正常。我知道这看起来是正确的,但如果用户点击任何其他三个图标,这就是结果:

Tap other icons. Selection hangs around when it isn't wanted.

如果用户按下任意的四个初始图标后触及的选择,该应用程序由于空指针异常而崩溃。

当用户触摸选择的动作之后挥之不去的选择,应用程序试图访问ActionMode(姑且称之为firstActionMode)创建与图标的CAB,以无效/刷新。但是,创建具有颜色的CAB时()导致空指针异常,firstActionMode将被销毁。


为了扫清选择,我发现,调用clearFocus()onDestroyActionMode(firstActionMode)方法做这项工作就好了。

private class CustomActionModeCallback extends ActionMode.Callback { 
    @Override 
    public void onDestroyActionMode(ActionMode mode) { 
     clearFocus(); 
    } 
} 

然而,当这是实现,当secondActionMode创建了CAB的选择并不坚持:

Same as before, but... The selection disappears when any icon is clicked.

从这个角度选择色彩实际上产生所需的功能。然而,虽然这个“有效”,但它(最不幸)并不符合我的要求。当显示由secondActionMode创建的CAB时,我需要选择保持可见和功能


这里是我的自定义类( WebView)及其嵌套 ActionMode是代码

public class CustomWebView extends WebView { 

    private ActionMode.Callback mActionModeCallback; 

    @Override 
    public ActionMode startActionMode(Callback callback) { 
     ViewParent parent = getParent(); 
     if (parent == null) { 
      return null; 
     } 
     if (callback instanceof HighlightActionModeCallback) { 
      mActionModeCallback = callback; 
     } else { 
      mActionModeCallback = new CustomActionModeCallback(); 
     }  
     return parent.startActionModeForChild(this, mActionModeCallback); 
    } 

    private class CustomActionModeCallback implements ActionMode.Callback { 
     // Called when the action mode is created; startActionMode() was called 
     @Override 
     public boolean onCreateActionMode(ActionMode mode, Menu menu) { 
      // Inflate a menu resource providing context menu items 
      MenuInflater inflater = mode.getMenuInflater(); 
      inflater.inflate(R.menu.first_menu, menu); 
      return true; 
     } 

     // Called each time the action mode is shown. 
     // Always called after onCreateActionMode, but 
     // may be called multiple times if the mode is invalidated. 
     @Override 
     public boolean onPrepareActionMode(ActionMode mode, Menu menu) { 
      // This method is called when the handlebars are moved. 
      return false; // Return false if nothing is done 
     } 

     // Called when the user selects a contextual menu item 
     @Override 
     public boolean onActionItemClicked(ActionMode mode, MenuItem item) { 

      switch (item.getItemId()) { 
      case R.id.copy: 
       // Do stuff 
       break; 
      case R.id.bookmark: 
       // Do stuff 
       break; 

      case R.id.highlight: 
       startActionMode(new HighlightActionModeCallback()); 
       break; 

      case R.id.note: 
       // Do stuff 
       break; 
      default: 
       return false; 
      } 

      mode.finish(); // Action picked, so close the CAB 
      return true; 
     } 

     // Called when the user exits the action mode 
     @Override 
     public void onDestroyActionMode(ActionMode mode) { 
      clearFocus(); // This is commented in the first four screens. 
     } 
    } 

    private class HighlightActionModeCallback implements ActionMode.Callback { 

     // Called when the action mode is created; startActionMode() was called 
     @Override 
     public boolean onCreateActionMode(ActionMode mode, Menu menu) { 
      // Inflate a menu resource providing context menu items 
      MenuInflater inflater = mode.getMenuInflater(); 
      inflater.inflate(R.menu.highlight_colors, menu); 
      return true; 
     } 

     // Called each time the action mode is shown. 
     // Always called after onCreateActionMode, but 
     // may be called multiple times if the mode is invalidated. 
     @Override 
     public boolean onPrepareActionMode(ActionMode mode, Menu menu) { 
      // This method is called when the handlebars are moved. 
      return false; // Return false if nothing is done 
     } 

     // Called when the user selects a contextual menu item 
     @Override 
     public boolean onActionItemClicked(ActionMode mode, MenuItem item) { 
      mode.finish(); // Action picked, so close the CAB 
      return true; 
     } 

     // Called when the user exits the action mode 
     @Override 
     public void onDestroyActionMode(ActionMode mode) { 
      // Remove the selection highlight and handles. 
      clearFocus(); 
     } 
    } 

} 


如何这个问题能解决?任何和所有的帮助表示赞赏。

回答

0

我现在已经解决了这个问题;我过度思考。解决方案不在于ActionMode,而是在菜单内。

如果选择了荧光笔,则不需要为颜色菜单启动全新的ActionMode,而是更改图标菜单。在onCreateActionMode中保存对Menu参数的引用并设置某种标志;我正在使用布尔值。

private class CustomActionModeCallback implements ActionMode.Callback { 

    private boolean highlighterClicked = false; 
    private Menu mMenu; 

    // Called when the action mode is created; startActionMode() was called 
    @Override 
    public boolean onCreateActionMode(ActionMode mode, Menu menu) { 
     mMenu = menu; 
     // Inflate a menu resource providing context menu items 
     MenuInflater inflater = mode.getMenuInflater(); 
     inflater.inflate(R.menu.first_menu, menu); 
     return true; 
    } 

    // Called each time the action mode is shown. 
    // Always called after onCreateActionMode, but 
    // may be called multiple times if the mode is invalidated. 
    @Override 
    public boolean onPrepareActionMode(ActionMode mode, Menu menu) { 
     // This method is called when the handlebars are moved. 
     MenuInflater inflater = mode.getMenuInflater(); 
     if (highlighterClicked) { 
      menu.clear(); // Remove the four icons 
      inflater.inflate(R.menu.highlight_colors, menu); // Show the colors 
      return true; // This time we did stuff, so return true 
     } 
     return false; // Return false if nothing is done 
    } 

    // Called when the user selects a contextual menu item 
    @Override 
    public boolean onActionItemClicked(ActionMode mode, MenuItem item) { 

     highlighterClicked = false; 
     switch (item.getItemId()) { 
     case R.id.copy: 
      // Do stuff 
      break; 
     case R.id.bookmark: 
      // Do stuff 
      break; 

     case R.id.highlight: 
      highlighterClicked = true; 
      onPrepareActionMode(mode, mMenu); 
      return true; 

     case R.id.note: 
      // Do stuff 
      break; 
     default: 
      // Any of the colors were picked 
      return true; 
     } 

     mode.finish(); // Action picked, so close the CAB 
     return true; 
    } 

    // Called when the user exits the action mode 
    @Override 
    public void onDestroyActionMode(ActionMode mode) { 
     clearFocus(); 
    } 
} 

选择突出显示和句柄保持活动和功能,并且颜色选项按预期工作。

删除第二个ActionModeCallback类是安全的;它是毫无价值的。再次,方式过度思考。 :P