Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

  • setInteractiveGuide(): 인터랙티브 튜토리얼을 설정을 할 수 있는 함수입니다. 파라미터로 InteractiveGuideConfig 클래스의 instance를 받습니다.

  • interactiveGuideCongfig: Interactive guide가 어떻게 보여질지 설정하는 클래스 입니다.

    • Enabled: Interactive guide를 활성화/비활성화 할 수 있습니다.

    • Type: InteractiveGuideConfig.Type.Navigation 으로 설정해야 합니다.

Code Block
public class MainActivity extends Activity {
    ...
    InteractiveGuideConfig interactiveGuideConfig = new InteractiveGuideConfig.Builder()
    .setEnabled(true)
    .setType(InteractiveGuideConfig.Type.Navigation)
    .build();
    BuzzScreen.getInstance().setInteractiveGuide(interactiveGuideConfig);
    ...
}

Customization

아래의 메소드를 사용하여 튜토리얼의 progress bar 및 indicator 색상을 변경할 수 있습니다.

...

각 단계별 설명 문구도 strings.xml 파일에 추가하여 변경가능합니다. 별도로 세팅하지 않는 경우, 기본 문구를 사용하게 됩니다:

Code Block
<string name="bs_guide1_description">위쪽으로 밀어 다음 컨텐츠를 확인해 보세요</string>
<string name="bs_guide2_description">이제 아래쪽으로 밀어 처음 컨텐츠로 돌아가 보세요</string>
<string name="bs_guide3_description">왼쪽으로 밀어 관련된 내용을 읽어 보세요</string>
<string name="bs_guide4_description">마지막으로, 오른쪽으로 밀어 잠금해제 하세요</string>

3. 위젯 튜토리얼 (선택)

위젯 튜토리얼은 각 퍼블리셔마다 앱에서 사용하는 위젯이 다르기 때문에 개별 앱에서 구현해야 합니다. 다음 가이드는 BaseLockerActivity를 상속받는 Activity에서 작성되어야 합니다.

  • setInteractiveGuideListener(): 네비게이션 튜토리얼이 끝나는 시점을 callback으로 받을 수 있도록 리스너를 등록합니다.

  • onInteractiveGuideComplete(): 네비게이션 튜토리얼이 완료되는 즉시 호출됩니다. 즉 유저가 네비게이션 튜토리얼의 마지막 과정인 '잠금 해제'를 끝매녀 호출됩니다. 해당 리스너를 사용하는 쪽에서는 해당 함수가 호출될때 BuzzPreferences에 위젯 부분이 활성화 된 것을 저장합니다.

Code Block
setInteractiveGuideListener(new LockerInteractiveGuideListener() {
    @Override
    public void onInteractiveGuideComplete() {
        BuzzPreferences.edit().putBoolean(KEY_LOCK_INTERACTIVE_TUTORIAL_WIDGET_SHOULD_SHOW, true).apply();
    }

    @Override
    public void onInteractiveGuideStepDone(int step) {
    }
});

onResume()에서는 KEY_LOCK_INTERACTIVE_TUTORIAL_WIDGET_SHOULD_SHOW 값을 확인하여 위젯 튜토리얼 부분을 보여줄지 말지 결정합니다.

Code Block
@Override
protected void onResume() {
    super.onResume();
    if (BuzzPreferences.getBoolean(KEY_LOCK_INTERACTIVE_TUTORIAL_WIDGET_SHOULD_SHOW, false)) {
        // Show Widget part of Interactive guide
    }
}

구현 예시

...

1. 오퍼월 위젯에 대한 가이드를 Fragment로 구현하도록 하겠습니다. 여기서는 오퍼월로 이동하는 버튼과 해당 과정을 넘어가는 스킵 버튼이 존재합니다. 이 Fragment 내부 구성은 작성하는 앱의 기능에 맞춰 자유롭게 변경할 수 있습니다.

...

2. LockscreenGuideFragment.java를 Activity에서 필요한 시점에 생성하여 잠금화면 위에 오버레이 형식으로 노출합니다. 유저가 버튼을 클릭했을 때 해당 액션을 수행합니다. 오퍼월 버튼을 눌렀을 때는 오퍼월 Activity를 실행하고 위젯 튜토리얼 fragment를 종료합니다. 스킵 버튼을 눌렀을 때는 위젯 튜토리얼 fragment를 바로 종료합니다.

Code Block
languagejava
final LockscreenGuideFragment lockscreenGuideFragment = new LockscreenGuideFragment();
lockscreenGuideFragment.setLockscreenGuideListener(new LockscreenGuideFragment.LockscreenGuideListener() {
    @Override
    public void onOfferwallButtonClicked() {
        startActivity(OfferwallActivity.class)
        //remote tutorial fragment
        getSupportFragmentManager().beginTransaction().remove(lockscreenGuideFragment).commit();
        BuzzPreferences.edit().putBoolean(KEY_LOCK_INTERACTIVE_TUTORIAL_SHOULD_SHOW, false).apply();
    }

    @Override
    public void onSkipButtonClicked() {
        //remote tutorial fragment
        getSupportFragmentManager().beginTransaction().remove(lockscreenGuideFragment).commit();
        BuzzPreferences.edit().putBoolean(KEY_LOCK_INTERACTIVE_TUTORIAL_SHOULD_SHOW, false).apply();
    }
});
getSupportFragmentManager().beginTransaction().replace(getRootView().getId(), lockscreenGuideFragment).commitAllowingStateLoss();
Expand
title튜토리얼 UI 레이아웃 파일 참조

layout.xml

Code Block
languagexml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/vGroupParent"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#BF000000">

    <FrameLayout
        android:layout_width="272dp"
        android:layout_height="wrap_content"
        android:layout_gravity="right"
        android:layout_marginTop="-112dp"
        android:layout_marginRight="-72dp"
        android:alpha="0.93"
        android:background="@drawable/circle_white"
        android:backgroundTint="@color/tutorial_color"
        android:paddingBottom="272dp"/>

    <ImageView
        android:id="@+id/btn_offerwall"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="right"
        android:layout_marginTop="32dp"
        android:layout_marginRight="70dp"
        android:src="@drawable/btn_offerwall" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom"
        android:layout_marginLeft="8dp"
        android:layout_marginRight="8dp"
        android:layout_marginBottom="48dp"
        android:background="@drawable/bg_corner_raidus_2dp"
        android:orientation="horizontal"
        android:padding="16dp">

        <FrameLayout
            android:layout_width="48dp"
            android:layout_height="48dp"
            android:layout_marginRight="16dp">

            <ProgressBar
                style="?android:attr/progressBarStyleHorizontal"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:indeterminate="false"
                android:max="100"
                android:progress="100"
                android:progressDrawable="@drawable/circular_progress" />

            <ImageView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:src="@drawable/btn_offerwall"
                android:tint="@color/tutorial_color" />
        </FrameLayout>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@string/interactive_guide_offerwall_subtitle"
                android:textColor="#66000000"
                android:textSize="10sp" />

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@string/interactive_guide_offerwall_title"
                android:textColor="@android:color/black" />

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:gravity="right"
                android:orientation="horizontal">

                <TextView
                    android:id="@+id/skip_button"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:padding="7dp"
                    android:text="@string/interactive_guide_skip"
                    android:textColor="@android:color/black"
                    android:textSize="14sp" />
            </LinearLayout>
        </LinearLayout>
    </LinearLayout>
</FrameLayout>