Can';t在android中从Fragment运行ShowcaseView
我使用的是来自的ShowcaseView的最新版本 当我尝试将其用于演示应用程序和活动时,它可以工作,但当我尝试将其用于片段时,它使我的应用程序崩溃,没有出现logcat错误Can';t在android中从Fragment运行ShowcaseView,android,fragment,showcaseview,Android,Fragment,Showcaseview,我使用的是来自的ShowcaseView的最新版本 当我尝试将其用于演示应用程序和活动时,它可以工作,但当我尝试将其用于片段时,它使我的应用程序崩溃,没有出现logcat错误 @override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); final Imag
@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();
}
这里有什么问题
EDIT1:
当我尝试在fragmentactivity中执行相同的操作但不起作用时,但当我执行相同的操作时,却采取了在fragmentactivity中声明的视图,而不是在它起作用的片段中声明的视图
EDIT2:
我设法从日志猫那里得到了错误
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)
我理解错误,但它的原因是什么?根据,ShowcaseView应该内置在
onCreateView()
中,即使您可以将其写在RESUME()中并确保如果您在简历中写作,则必须维护一个标志,以避免在调用OnResume()时在上面构建多个showcase
if (!mShowCaseVisible){
ActionViewTarget target = new ActionViewTarget(getActivity(), ActionViewTarget.Type.HOME);
showcaseView = new ShowcaseView.Builder(getActivity(), true)
.setTarget(target)
.setContentTitle("Home Screen")
.setOnClickListener(this)
.setContentText("Click on top left corner to seemenu.")
.doNotBlockTouches()`enter code here`
.hideOnTouchOutside()
.singleShot(42)
.build();
showcaseView.setButtonText("Next");
mShowCaseVisible = true;
}
这似乎是一个时间问题。如果调用发生在视图在屏幕上实际绘制之前,则无法说明宽度和高度应大于0。这一点从
ShowcaseView
的源代码中可以清楚地看到,在updateBitmap()
函数中,它失败了:
bitmapBuffer = Bitmap.createBitmap(getMeasuredWidth(), getMeasuredHeight(), Bitmap.Config.ARGB_8888);
其中getMeasuredWidth()
和getMeasuredHeight()
在实际绘制之前将为零
解决这一问题的办法是延迟处理。我目前使用它时有5s的延迟,并在处理程序的帮助下从onResume()调用它
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
new ShowcaseView.Builder(mActivity)
.setTarget(new ViewTarget(saveMatchButton))
.setContentTitle("This is a demo")
.build();
}
}, 5000);
我认为更好的解决方案是更改ShowcaseView类(函数updateBitmap())。当getMeasure*返回0时,将任何非零维度值传递给createBitmap()函数将确保创建的位图大小有效。由于updateBitmap()函数将在视图达到实际大小时再次调用,因此这不会带来任何问题
private void updateBitmap()
{
if (bitmapBuffer == null || haveBoundsChanged())
{
if(bitmapBuffer != null)
bitmapBuffer.recycle();
bitmapBuffer = Bitmap.createBitmap(getMeasuredWidth() > 0 ? getMeasuredWidth() : 1,
getMeasuredHeight() > 0 ? getMeasuredHeight() : 1,
Bitmap.Config.ARGB_8888);
}
}
在我看来,最好的解决方案是将代码放在视图的“post”回调中,这样在呈现所有内容时就会执行它
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
view.post(new Runnable() {
@Override
public void run() {
// your showcase initialisation code here
showcase();
}
});
}
我对它进行了测试,效果很好。是否视图
为空?改用vgetActivity
。并添加logcat错误。视图不为空。添加了日志中的错误可能重复我喜欢这个答案,我检查了代码,updateBitmap确实被调用了两次。我不明白为什么第一次调用它,因为它会带来很多麻烦。在LobalLayout上调用一次,在设置Target时调用一次,查看视图树Observer我在使用它时仍然遇到问题。我允许用户再次显示教程,因此当用户单击菜单项时,我调用教程的方法。但它有时会起作用,然后有时会抛出IllegalargumentException,我甚至无法将异常作为解决方法