I use the last version of ShowcaseView from here
When I tried to use it with demo app and activity it works but when I tried to use it with fragments it crashed my app with no logcat errors
@override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
final ImageButton saveButton = (ImageButton) view.findViewById(R.id.button_Save);
ViewTarget viewTarget = new ViewTarget(saveButton);
showcaseView = new ShowcaseView.Builder(getActivity())
.setTarget(viewTarget)
.setContentTitle("Reset Button")
.setContentText("This will erase all the data in the table except the line that in progress")
.build();
}
what could be the problem here?
EDIT1:
when I tried to do the same thing in my fragmentactivity and didn't work, but when I did the same thing but took a view that declared in the fragmentactivity and not in the fragment it worked.
EDIT2: I managed to get the error from the logcat.
FATAL EXCEPTION: main
java.lang.IllegalArgumentException: width and height must be > 0
at android.graphics.Bitmap.createBitmap(Bitmap.java:724)
at android.graphics.Bitmap.createBitmap(Bitmap.java:703)
at android.graphics.Bitmap.createBitmap(Bitmap.java:670)
at com.github.amlcurran.showcaseview.ShowcaseView.updateBitmap(ShowcaseView.java:169)
at com.github.amlcurran.showcaseview.ShowcaseView.onGlobalLayout(ShowcaseView.java:343)
at android.view.ViewTreeObserver.dispatchOnGlobalLayout(ViewTreeObserver.java:839)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2050)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1249)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6364)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:791)
at android.view.Choreographer.doCallbacks(Choreographer.java:591)
at android.view.Choreographer.doFrame(Choreographer.java:561)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:777)
at android.os.Handler.handleCallback(Handler.java:730)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:176)
at android.app.ActivityThread.main(ActivityThread.java:5419)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:525)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1046)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:862)
at dalvik.system.NativeStart.main(Native Method)
I understand the error but what is the cause for it?
Even you can write it down in RESUME() and make sure if you are writing in resume then you must have to maintain a flag which will be used to avoid issue of building more then one showcase one above on whenever OnResume() will be called.
I think a better solution is to change the ShowcaseView class (Function updateBitmap()). Passing any non-zero dimension values to the createBitmap() function when getMeasure* returns 0 would ensure the bitmap is created with a valid size. Since updateBitmap() function will be called again as soon as the view gets is actual size, this poses no problem.
This appears to be a timing issue. If the call happens before the views are actually drawn on screen, it fails saying the width and height should be > 0. This is clear from the source code of
ShowcaseView
, inupdateBitmap()
function, where it fails:where
getMeasuredWidth()
andgetMeasuredHeight()
will be zero before actually drawing.The work around to this issue is to call this with a good delay. I currently use it with a 5s delay and call it from
onResume()
, with the help of aHandler
In my opinion the best solution is to place the code within the "post" callback of the view, this way it will be executed when everything is rendered.
I tested it and worked like a charm.
According to this answer, the
ShowcaseView
should be built inonCreateView()
.