2

我从这里使用最新版本的 ShowcaseView

当我尝试将它与演示应用程序和活动一起使用时,它可以工作,但是当我尝试将它与片段一起使用时,它使我的应用程序崩溃而没有 logcat 错误

     @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();
        }

这里可能是什么问题?

编辑1:

当我尝试在我的fragmentactivity中做同样的事情并且没有工作时,但是当我做了同样的事情但采取了在fragmentactivity中声明而不是在它工作的片段中声明的视图时。

EDIT2: 我设法从 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)

我理解错误,但它的原因是什么?

4

5 回答 5

9

在我看来,最好的解决方案是将代码放在视图的“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();
        }
    });
}

我对其进行了测试,并像魅力一样工作。

于 2014-12-01T09:18:47.080 回答
6

这似乎是一个时间问题。如果调用发生在视图实际绘制在屏幕上之前,它会失败说宽度和高度应该> 0。从函数中的源代码中可以清楚地看到ShowcaseViewupdateBitmap()失败的地方:

bitmapBuffer = Bitmap.createBitmap(getMeasuredWidth(), getMeasuredHeight(), Bitmap.Config.ARGB_8888);

在实际绘图之前,哪里getMeasuredWidth()getMeasuredHeight()将为零。

解决此问题的方法是延迟调用它。我目前使用它有 5 秒的延迟onResume(),并在 a 的帮助下从 调用它Handler

new Handler().postDelayed(new Runnable() {
    @Override
    public void run() {
        new ShowcaseView.Builder(mActivity)
                            .setTarget(new ViewTarget(saveMatchButton))
                            .setContentTitle("This is a demo")
                            .build();
    }
}, 5000);
于 2014-08-26T18:29:10.350 回答
4

我认为更好的解决方案是更改 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);
    }
}
于 2014-08-27T07:47:41.377 回答
1

根据这个答案ShowcaseView应该是内置的onCreateView()

于 2014-05-22T12:16:07.720 回答
0

即使您可以在 RESUME() 中将其写下来,并确保如果您正在写简历,那么您必须维护一个标志,该标志将用于避免在调用 OnResume() 时在上面构建多个展示柜的问题.

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;
}
于 2014-06-25T07:11:00.797 回答