amlcurran/ShowcaseView — pull request #140 by bwp (2014-01-09 18:17:35+00:00)
Title: Various Changes

- Added blockAll to config to prevent user interaction inside showcase circle if desired
- Removed some ShowcaseView class methods marked as deprecated and updated the implementation as appropriate
*Removed: setScaleMultiplier, setShowcaseView, setShowcaseNoView
*Updated: ShowcaseViewBuilder
- Fixed a bug where ActionViewTarget could bomb with a NPE instead of returning null which is gracefully handled
- Added ability to manually trigger a showcase even if its set to show once and it has already shown. This was done to add support for an on demand showcase trigger. In this case the actionbar overflow has a help button which triggers the appropriate showcaseView suite.
- Moved test libraries into separate folder 'libstest' so they could be given a scope of test. This will prevent their inclusion in the showcaseView project compilation and avoid potential out of memory errors with roboelectric.
- Added Junit library for test project compilation.
- Added a gradle project which can likely be ignored.
- Small cleanup.
- Added Optional Skip button (disabled by default) to the left of the Ok button. The Skip button in this case is a way for the user to opt out of the showcaseView suite.

To Turn on the skip button:

ShowcaseView.ConfigOptions options = new ShowcaseView.ConfigOptions();
options.noSkipButton = false;

Sample Implementation:

```
public class SomeClass {
Activity mActivity;
OnShowcaseEventListener mAnalyticsListener;
ShowcaseView mShowcaseView;
int counter = -1;

public SomeClass(Activity activity) {
mActivity = activity;
initAnalyticsHandler();
}

/**
* some method thats called to either programmatically or
* manually trigger a series of showcase views
*/
public void showcaseSuite(final boolean manualTrigger) {
new Handler().post(new Runnable() {
@Override
public void run() {
try {
mShowcaseView = ShowcaseView.insertShowcaseView(new ViewTarget(R.id.showcase_id, mActivity),
mActivity, R.string.some_title, R.string.some_description,
createConfigOptions(R.id.showcase_id, manualTrigger));
counter = 0;
mShowcaseView.setScaleMultiplier(.50f);
mShowcaseView.overrideOKButtonClick(new View.OnClickListener() {
@Override
public void onClick(View view) {
Log.d(TAG, "showcase ok click counter " + counter);
switch (counter) {
case 0:
mShowcaseView.setShowcase(new ViewTarget(R.id.showcase_id2, mActivity), false);
mShowcaseView.setText(R.string.some_title2, R.string.some_description2);
mShowcaseView.setScaleMultiplier(.35f);
break;
case 1:
markAsShownAndReset();
break;
}
counter++;
}
});
mShowcaseView.overrideSKIPButtonClick(new View.OnClickListener() {
@Override
public void onClick(View v) {
markAsShownAndReset();
}
});
} catch (Exception ex) {
Log.e(TAG, "showcaseSomething", ex);
}
}
});
}

protected ShowcaseView.ConfigOptions createConfigOptions(int id, boolean manualTrigger) {
ShowcaseView.ConfigOptions options = new ShowcaseView.ConfigOptions();
options.hideOnClickOutside = false;
options.shotType = ShowcaseView.TYPE_ONE_SHOT;
options.blockAll = true;
// showcaseId can be used as an id for a suite of showcaseViews
options.showcaseId = id;
options.manualTrigger = manualTrigger;
return options;
}

protected void markAsShownAndReset() {
mShowcaseView.markViewAsShown();
mShowcaseView.hide();
counter = -1;
removeShowcaseViewFromActivity();
}

protected void removeShowcaseViewFromActivity() {
if (mShowcaseView.getConfigOptions().insert == ShowcaseView.INSERT_TO_DECOR) {
Log.d(TAG, "removeShowcaseViewFromActivity Decor");
ViewGroup decorViewGroup = (ViewGroup) mActivity.getWindow().getDecorView();
mShowcaseView.removeShowcaseViews(decorViewGroup);
} else {
Log.d(TAG, "removeShowcaseViewFromActivity View");
ViewGroup contentViewGroup = (ViewGroup) mActivity.findViewById(android.R.id.content);
mShowcaseView.removeShowcaseViews(contentViewGroup);
}
}
```