2014-04-16 177 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