I'm trying to integrate ShowcaseView (v5.2.3) into an app, but when I try to target an action bar menu item, the app crashes with the runtime exception message "insertShowcaseViewWithType cannot be used when the theme has no ActionBar". The activity absolutely has an action bar with menu items. This occurs on both Android v5.1.1 and v4.4.2
The stack trace from the crash is as follows...
java.lang.RuntimeException: insertShowcaseViewWithType cannot be used when the theme has no ActionBar
at com.github.amlcurran.showcaseview.targets.ActionBarReflector.getHomeButton(ActionBarReflector.java:43)
at com.github.amlcurran.showcaseview.targets.ActionBarReflector.getActionBarView(ActionBarReflector.java:36)
at com.github.amlcurran.showcaseview.targets.ActionItemTarget.setUp(ActionItemTarget.java:49)
at com.github.amlcurran.showcaseview.targets.ActionItemTarget.getPoint(ActionItemTarget.java:43)
at com.github.amlcurran.showcaseview.ShowcaseView$1.run(ShowcaseView.java:176)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5254)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
The app module build.gradle is as follows...
apply plugin: 'com.android.application'
android {
compileSdkVersion 23
buildToolsVersion "23.0.1"
defaultConfig {
applicationId "com.d60402.myappname"
minSdkVersion 15
targetSdkVersion 23
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:23.1.0'
compile 'com.github.amlcurran.showcaseview:library:5.2.3'
}
My activity is as follows...
package com.d60402.myappname;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Menu;
import com.github.amlcurran.showcaseview.ShowcaseView;
import com.github.amlcurran.showcaseview.targets.ActionItemTarget;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu
getMenuInflater().inflate(R.menu.main_menu, menu);
boolean ret = super.onCreateOptionsMenu(menu);
ActionItemTarget target = new ActionItemTarget(this, R.id.action_settings);
new ShowcaseView.Builder(this)
.setTarget(target)
.setContentTitle("Settings menu")
.setContentText("Tap here to view and set the app settings")
.hideOnTouchOutside()
.build();
return ret;
}
}
The main_menu.xml is as follows...
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item android:id="@+id/action_settings"
android:title="@string/action_settings"
android:orderInCategory="100"
app:showAsAction="always|withText"/>
</menu>
The AndroidManifest.xml is as follows...
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.d60402.myappname" >
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme" >
<activity android:name=".MainActivity" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
And the styles.xml is as follows...
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style>
</resources>
From the ShowcaseView developer (amicurran)...
As you might realise, there is no API in AppCompat for getting a reference to a MenuItem view, and as such this call requires reflection. And basically every time Google change AppCompat, this breaks ShowcaseView.
I don't have any current plans to support the new AppCompat (which is what this crash is coming from). However, if you use an AppCompat Toolbar, then you can quite easily showcase an item on it. See the demo activity, and the new target for more info.