Using ShowcaseView to target action bar menu item

d60402 picture d60402 · Oct 27, 2015 · Viewed 7.4k times · Source

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>

Answer

RatneZ picture RatneZ · Mar 22, 2016

Use this code. Its working for me. Here "toolbar" is the id of my toolbar.

      Target homeTarget = new Target() {
        @Override
        public Point getPoint() {
            // Get approximate position of home icon's center
            int actionBarSize = toolbar.getHeight();
            int x = actionBarSize / 2;
            int y = actionBarSize / 2;
            return new Point(x, y);
        }
    };
    new ShowcaseView.Builder(this)
            .setContentTitle("Its My Navigation Drawer")
            .setContentText("Click here and you will get options to navigate to other sections.")
            .setTarget(homeTarget)
            .build();
}