0

Straight to the point. I am trying to show coachmark series using ShowcaseView library by amlcurran: https://github.com/amlcurran/ShowcaseView

I can't get the coachmark showing. The problem is runCoachMark() method always returning null. runCoachMark() method run right after notifyDatasetChaned() on mMainAdapter.

I have tried to use Handler().postDelayed() and Thread.sleep() with no success.

Anyone can explain why it is happening and some solutions for this problem. Thank you.

private static final int COACHMARK_A = -3;
private static final int COACHMARK_B = -2;
private static final int COACHMARK_C = -1;
// ... some other coachmark type

private static final int END_COACHMARK = 0;

private static final int SCROLL_OFFSET = 56;
private static final long COACHMARK_DELAY = 200L;

private void runCoachMark(int type) {
        if (type == END_COACHMARK) {
            return;
        }
        View v = getCoachMarkView(type);
        if (v == null) {
            return;
        }
    showCoachMark(getActivity(), v, type);
}

@Nullable
private View getCoachMarkView(final int type) {
    safeScrollTo(getPos(type), SCROLL_OFFSET);

    return mMainList.getChildAt(0).findViewById(getCoachMarkId(type));
}

private void safeScrollTo(final int pos, final int offset) {
        mMainList.setLayoutFrozen(true);
        mLayoutManager.scrollToPositionWithOffset(pos, offset);
        mMainList.setLayoutFrozen(false);
}

private int getCoachMarkId(int type) {
    int id;
    switch (type) {
        case COACHMARK_A:
            id = R.id.A;
            break;
        case COACHMARK_B:
            id = R.id.B;
            break;
        case COACHMARK_C:
            id = R.id.C;
            break;
        // ... some other types
        default:
            id = 0;
            break;
    return id;
}

private int getPos(int type) {
        int pos;
        switch (type) {
            case COACHMARK_A:
                pos = 1;
                break;
            case COACHMARK_B:
                pos = 4;
                break;
            case COACHMARK_C:
                pos = 5;
                break;
// ... some other cases
            default:
                pos = 0;
                break;
        }
        return pos;
}

private void showCoachMark(final Context context, final View v, final int type) {
        new ShowcaseView.Builder(getActivity())
                        .setTarget(new ViewTarget(v.getId(), (Activity) context))
                        .setContentTitle(getTitle(type))
                        .setContentText(getDescription(type))
                        .setShowcaseDrawer(new CustomShowcaseView(v))
                        .setShowcaseEventListener(new OnShowcaseEventListener() {
                            @Override
                            public void onShowcaseViewHide(ShowcaseView showcaseView) {

                            }

                            @Override
                            public void onShowcaseViewDidHide(ShowcaseView showcaseView) {
                                new Handler().postDelayed(new Runnable() {
                                    @Override
                                    public void run() {
                                        runCoachMark(type++);
                                    }
                                }, COACHMARK_DELAY);
                            }

                            @Override
                            public void onShowcaseViewShow(ShowcaseView showcaseView) {

                            }

                            @Override
                            public void onShowcaseViewTouchBlocked(MotionEvent motionEvent) {

                            }
                        })
                        .build();
            }
}
Wellsen
  • 325
  • 1
  • 3
  • 9

1 Answers1

1

I would share with you a new way to use showcaseview dynamically with recursive method

1) Create your ViewTargets, for example 4 targets (you can create n targets) and put targets into an array declared as a private attribute in your Activity class : private ViewTarget[] targets;

    final ViewTarget target1 = new ViewTarget(textview1);
    final ViewTarget target2 = new ViewTarget(textview2);
    final ViewTarget target3 = new ViewTarget(textview3);
    final ViewTarget target4 = new ViewTarget(textview4);
    targets = new ViewTarget[] { target1, target2,target3,target4};

2) Create the recursive method :

private void toStep(final String title, final String description,Target target, final int i) {
        final ShowcaseView.Builder showCaseBuilder = new ShowcaseView.Builder(ShowCaseActivity.this);
        showCaseBuilder.setTarget(targets[i]);
        showCaseBuilder.setContentTitle(title.replace("[i]", ""+i));
        showCaseBuilder.setContentText(description.replace("[i]", ""+i));
        showCaseBuilder.setShowcaseEventListener(new OnShowcaseEventListener() {
            @Override
            public void onShowcaseViewTouchBlocked(MotionEvent motionEvent) {
            }

            @Override
            public void onShowcaseViewShow(ShowcaseView showcaseView) {
            }

            @Override
            public void onShowcaseViewHide(ShowcaseView showcaseView) {
                try {
                    toStep(title, description, targets[i+1], i+1);
                } catch(Exception ex) {

                }
            }
            @Override
            public void onShowcaseViewDidHide(ShowcaseView showcaseView) {
            }
        });
        showCaseBuilder.build();
    }

3) Finally you can call the method that displays Showcases :

toStep("Title for showcase [i]", " Description for showcase [i] ",targets[0], 0);

I hope this will be helpful for you :)

azamani
  • 121
  • 1
  • 3