private void showcaseActionItem(ViewParent p, Class absAbv, int itemType, int actionItemId) {
    try {
      Field mAmpField = absAbv.getDeclaredField("mActionMenuPresenter");
      mAmpField.setAccessible(true);
      Object mAmp = mAmpField.get(p);
      if (itemType == ITEM_ACTION_OVERFLOW) {
        // Finds the overflow button associated with the ActionMenuPresenter
        Field mObField = mAmp.getClass().getDeclaredField("mOverflowButton");
        mObField.setAccessible(true);
        View mOb = (View) mObField.get(mAmp);
        if (mOb != null) setShowcaseView(mOb);
      } else {
        // Want an ActionItem, so find it
        Field mAmvField = mAmp.getClass().getSuperclass().getDeclaredField("mMenuView");
        mAmvField.setAccessible(true);
        Object mAmv = mAmvField.get(mAmp);

        Field mChField;
        if (mAmv.getClass().toString().contains("com.actionbarsherlock")) {
          // There are thousands of superclasses to traverse up
          // Have to get superclasses because mChildren is private
          mChField =
              mAmv.getClass()
                  .getSuperclass()
                  .getSuperclass()
                  .getSuperclass()
                  .getSuperclass()
                  .getDeclaredField("mChildren");
        } else
          mChField = mAmv.getClass().getSuperclass().getSuperclass().getDeclaredField("mChildren");
        mChField.setAccessible(true);
        Object[] mChs = (Object[]) mChField.get(mAmv);
        for (Object mCh : mChs) {
          if (mCh != null) {
            View v = (View) mCh;
            if (v.getId() == actionItemId) setShowcaseView(v);
          }
        }
      }
    } catch (IllegalAccessException e) {
      e.printStackTrace();
    } catch (NoSuchFieldException e) {
      e.printStackTrace();
    } catch (NullPointerException npe) {
      throw new RuntimeException(
          "insertShowcaseViewWithType() must be called "
              + "after or during onCreateOptionsMenu() of the host Activity");
    }
  }
 /**
  * Quick method to insert a ShowcaseView into an Activity
  *
  * @param viewToShowcase View to showcase
  * @param activity Activity to insert into
  * @param title Text to show as a title. Can be null.
  * @param detailText More detailed text. Can be null.
  * @param options A set of options to customise the ShowcaseView
  * @return the created ShowcaseView instance
  */
 public static ShowcaseView insertShowcaseView(
     View viewToShowcase, Activity activity, int title, int detailText, ConfigOptions options) {
   ShowcaseView sv = new ShowcaseView(activity);
   if (options != null) sv.setConfigOptions(options);
   if (sv.getConfigOptions().insert == INSERT_TO_DECOR) {
     ((ViewGroup) activity.getWindow().getDecorView()).addView(sv);
   } else {
     ((ViewGroup) activity.findViewById(android.R.id.content)).addView(sv);
   }
   sv.setShowcaseView(viewToShowcase);
   sv.setText(title, detailText);
   return sv;
 }
 private void showcaseTitle(ViewParent p, Class abv) {
   try {
     Field mTitleViewField = abv.getDeclaredField("mTitleView");
     mTitleViewField.setAccessible(true);
     View titleView = (View) mTitleViewField.get(p);
     if (titleView != null) {
       setShowcaseView(titleView);
     }
   } catch (NoSuchFieldException e) {
     Log.e("TAG", "Failed to find actionbar title", e);
   } catch (IllegalAccessException e) {
     Log.e("TAG", "Failed to access actionbar title", e);
   }
 }
 private void showcaseSpinner(ViewParent p, Class abv) {
   try {
     Field mSpinnerField = abv.getDeclaredField("mSpinner");
     mSpinnerField.setAccessible(true);
     View mSpinnerView = (View) mSpinnerField.get(p);
     if (mSpinnerView != null) {
       setShowcaseView(mSpinnerView);
     }
   } catch (NoSuchFieldException e) {
     Log.e("TAG", "Failed to find actionbar spinner", e);
   } catch (IllegalAccessException e) {
     Log.e("TAG", "Failed to access actionbar spinner", e);
   }
 }