/
인터렉티브 튜토리얼

인터렉티브 튜토리얼

잠금화면을 처음 사용하는 유저를 위해 L앱이 처음 설치된 시점에 안내를 하는 가이드이며, 유저가 직접 튜토리얼을 따라하며 L앱의 사용 방법을 자연스럽게 익히는 것에 그 목적이 있습니다.

인터랙티브 튜토리얼 기능은 BuzzScreen SDK 1.9.8.0 버전 이상부터 사용할 수 있습니다.

 

1. User Flow

움직이는 손 이미지를 따라 스와이프 하거나 클릭을 통해 진행되는 방식과, 다음을 누르며 진행하는 방식으로 나뉩니다.

크게 두 단계로 구성되어 있습니다:

  1. 네비게이션 튜토리얼

    1. 피드 확인 후 첫화면으로 복귀

    2. 랜딩 후 첫화면으로 복귀

    3. 잠금 해제

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

 

2. 네비게이션 튜토리얼

BuzzScreen.getInstance().activate() 전에 호출해야 하며, 잠금화면이 최초로 활성화 됐을 때 설정한 값에 따라 가이드를 노출합니다.

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

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

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

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

 

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 색상을 변경할 수 있습니다.

<resources> ... <color name="interactive_guide_primary_color">#007DD6</color> ... </resources>

 

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

 

<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에 위젯 부분이 활성화 된 것을 저장합니다.

 

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 값을 확인하여 위젯 튜토리얼 부분을 보여줄지 말지 결정합니다.

 

@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 내부 구성은 작성하는 앱의 기능에 맞춰 자유롭게 변경할 수 있습니다.

 

LockscreenGuideFragment.java

public class LockscreenGuideFragment extends Fragment { private LockscreenGuideListener lockscreenGuideListener; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { return inflater.inflate(R.layout.fragment_lockscreen_guide, container); } @Override public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); view.findViewById(R.id.skip_button).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { if (lockscreenGuideListener != null) { lockscreenGuideListener.onSkipButtonClicked(); } } }); view.findViewById(R.id.btn_offerwall).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { if (lockscreenGuideListener != null) { lockscreenGuideListener.onOfferwallButtonClicked(); } } }); } public void setLockscreenGuideListener(LockscreenGuideListener lockscreenGuideListener) { this.lockscreenGuideListener = lockscreenGuideListener; } public interface LockscreenGuideListener { void onOfferwallButtonClicked(); void onSkipButtonClicked(); } }

 

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

 

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

layout.xml

<?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>

Related content