|
| 1 | +### Usage ### |
| 2 | +#### BlurTutorial #### |
| 3 | +The main component of library is the <b>BlurTutorial</b> interface. |
| 4 | + |
| 5 | +```kotlin |
| 6 | + // add list of states to tutorial |
| 7 | + fun addAllStates(states: List<TutorialState>) |
| 8 | + |
| 9 | + // add one state to tutorial |
| 10 | + fun addState(state: TutorialState) |
| 11 | + |
| 12 | + // add one state to position |
| 13 | + fun setState(state: TutorialState, index: Int) |
| 14 | + |
| 15 | + // remove state from tutorial |
| 16 | + fun removeState(state: TutorialState) |
| 17 | + |
| 18 | + // clear all states of tutorial. Cancel tutorial process. |
| 19 | + fun clearStates() |
| 20 | + |
| 21 | + // get current state of tutorial |
| 22 | + fun getCurrentState(): TutorialState? |
| 23 | + |
| 24 | + /* |
| 25 | + * Start tutorial process. |
| 26 | + * |
| 27 | + * Should be called in [Activity.onResume] or [Fragment.onResume] or later. |
| 28 | + * If you also highlight action bar menu items, |
| 29 | + * call it in [Activity.onPrepareOptionsMenu] or [Fragment.onPrepareOptionsMenu] or later. |
| 30 | + */ |
| 31 | + fun start() |
| 32 | + |
| 33 | + // go to next state of tutorial. Finish the current state. |
| 34 | + fun next() |
| 35 | + |
| 36 | + /** |
| 37 | + * Interrupt tutorial process. |
| 38 | + * It can be renewed by calling next() or start() |
| 39 | + */ |
| 40 | + fun interrupt() |
| 41 | + |
| 42 | + // change configuration of current [BlurTutorial] instance. |
| 43 | + fun configure(): TutorialBuilder |
| 44 | + |
| 45 | + // save state of tutorial. Ypu must call it in onSaveInstanceState() of your Fragment or Activity. |
| 46 | + fun onSaveInstanceState(outState: Bundle) |
| 47 | + |
| 48 | + // restore state of tutorial. You must call it in onRestoreInstanceState() of your Fragment or Activity. |
| 49 | + fun onRestoreInstanceState(savedState: Bundle?) |
| 50 | + |
| 51 | + // Release resources. You must call it in onDestroy() of Fragment or Activity. |
| 52 | + fun onDestroy() |
| 53 | +``` |
| 54 | +#### TutorialState #### |
| 55 | +<b>TutorialState</b> is an interface, that describes UI item to explain. There are a few data classes, that implement this interface: |
| 56 | +* <b>ViewState</b> - describes the View to highlight. |
| 57 | +* <b>MenuState</b> - describes the menu item to highlight. |
| 58 | +* <b>RecyclerItemState</b> - describes the RecyclerView item to highlight. |
| 59 | +* <b>PathState</b> - describes the geometric figure to highlight. |
| 60 | +By using this state you can highlight a part of view or a part of visible screen area. |
| 61 | +#### TutorialBuilder #### |
| 62 | +To create an instance of <b>BlurTutorial</b> you have to use <b>TutorialBuilder</b>. |
| 63 | + |
| 64 | +| Builder method name | parameter description | is required | |
| 65 | +|---|---|---| |
| 66 | +| withParent | Root of your layout. Will be blurred or dimmed. | yes | |
| 67 | +| withPopupLayout | Layout of popup window. | yes | |
| 68 | +| withPopupAppearAnimation | Popup appear animation resource | no | |
| 69 | +| withPopupDisappearAnimation | Popup disappear animation resource | no | |
| 70 | +| withPopupAppearAnimator | Popup appear animator resource | no | |
| 71 | +| withPopupDisappearAnimator | Popup disappear animator resource | no | |
| 72 | +| withPopupXOffset | X offset of popup window | no | |
| 73 | +| withPopupYOffset | Y offset of popup window | no | |
| 74 | +| withPopupCornerRadius | Radius of popup corners | no | |
| 75 | +| withBlurRadius | Radius of blur. Must be in a range (0.0; 25.0]. By default, it's 10.0 | no | |
| 76 | +| withOverlayColor | Color of overlay, that will be displayed above blurred or dimmed background. | no | |
| 77 | +| withHighlightType | Type of highlight: Blur or Dim. By default, it's Blur. | no | |
| 78 | +| withListener | Listener of tutorial process | yes | |
| 79 | + |
| 80 | +#### TutorialListener #### |
| 81 | +Also you have to set listener of tutorial process: |
| 82 | + |
| 83 | +```kotlin |
| 84 | +interface TutorialListener { |
| 85 | + |
| 86 | + /* |
| 87 | + Called before state is entered. |
| 88 | + Use it to prepare UI for view highlighting. |
| 89 | + E.g. smoothly scroll to this view. |
| 90 | + */ |
| 91 | + override fun onStateEnter(state: TutorialState) |
| 92 | + |
| 93 | + // Called after state exit. |
| 94 | + override fun onStateExit(state: TutorialState) |
| 95 | + |
| 96 | + // Called on state error. E.g. highlighted view is not visible, etc. |
| 97 | + override fun onStateError(state: TutorialState, error: StateException) |
| 98 | + |
| 99 | + /* |
| 100 | + Called when popup view is inflated. |
| 101 | + Use this method to populate your popup view. |
| 102 | + */ |
| 103 | + override fun onPopupViewInflated(state: TutorialState, popupView: View) |
| 104 | + |
| 105 | + // Called when tutorial process is finished. |
| 106 | + override fun onFinish() |
| 107 | +} |
| 108 | +``` |
| 109 | + |
| 110 | +#### Fragment/Activity usage #### |
| 111 | +```kotlin |
| 112 | +companion object { |
| 113 | + private const val VIEW_ID = 0 |
| 114 | + private const val MENU_ITEM_ID = 1 |
| 115 | + private const val RECYCLER_ITEM_ID = 2 |
| 116 | + private const val PATH_ID = 3 |
| 117 | + |
| 118 | + private const val RECYCLER_ITEM_INDEX = 10 |
| 119 | + ... |
| 120 | +} |
| 121 | +... |
| 122 | + |
| 123 | +private val path = Path().apply { |
| 124 | + addCircle(500F, 500F, 300F, Path.Direction.CCW) |
| 125 | +} |
| 126 | + |
| 127 | +private val states by lazy { |
| 128 | + listOf(ViewState(VIEW_ID, tvHighlight), |
| 129 | + MenuState(MENU_ITEM_ID, tbMenuOwner, R.id.menu_item), |
| 130 | + RecyclerItemState(RECYCLER_ITEM_ID, rvOwner, RECYCLER_ITEM_INDEX), |
| 131 | + PathState(PATH_ID, path) |
| 132 | +} |
| 133 | + |
| 134 | +private var tutorial: BlurTutorial? = null |
| 135 | + |
| 136 | +private val tutorialListener = object : SimpleTutorialListener() { |
| 137 | + |
| 138 | + override fun onPopupViewInflated(state: TutorialState, popupView: View) { |
| 139 | + popupView.run { |
| 140 | + val tvTitle = findViewById<TextView>(R.id.tvTitle) |
| 141 | + |
| 142 | + tvTitle.textResource = when (state.id) { |
| 143 | + VIEW_ID -> R.string.view_title |
| 144 | + MENU_ITEM_ID -> R.string.menu_title |
| 145 | + RECYCLER_ITEM_ID -> R.string.recycler_title |
| 146 | + PATH_ID -> R.string.path_state |
| 147 | + } |
| 148 | + setOnClickListener { tutorial?.next() } |
| 149 | + } |
| 150 | + } |
| 151 | + } |
| 152 | + |
| 153 | + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { |
| 154 | + initTutorial() |
| 155 | + } |
| 156 | + |
| 157 | + override fun onResume() { |
| 158 | + super.onResume() |
| 159 | + tutorial?.start() |
| 160 | + } |
| 161 | + |
| 162 | + override fun onSaveInstanceState(outState: Bundle) { |
| 163 | + super.onSaveInstanceState(outState) |
| 164 | + tutorial?.onSaveInstanceState(outState) |
| 165 | + } |
| 166 | + |
| 167 | + override fun onViewStateRestored(savedInstanceState: Bundle?) { |
| 168 | + super.onViewStateRestored(savedInstanceState) |
| 169 | + tutorial?.onRestoreInstanceState(savedInstanceState) |
| 170 | + } |
| 171 | + |
| 172 | + override fun onDestroy() { |
| 173 | + tutorial?.onDestroy() |
| 174 | + super.onDestroy() |
| 175 | + } |
| 176 | + |
| 177 | + private fun initTutorial() { |
| 178 | + tutorial = TutorialBuilder() |
| 179 | + .withParent(clParent) |
| 180 | + .withListener(tutorialListener) |
| 181 | + .withPopupLayout(R.layout.popup_window) |
| 182 | + .withPopupCornerRadius(POPUP_RADIUS) |
| 183 | + .withBlurRadius(BLUR_RADIUS) |
| 184 | + .build().apply { addAllStates(states) } |
| 185 | + } |
| 186 | +``` |
| 187 | + |
| 188 | +#### Proguard #### |
| 189 | +Also depending on your Proguard config, you have to setup your proguard-rules.pro file: |
| 190 | + |
| 191 | +```proguard |
| 192 | +-keepclassmembers class androidx.appcompat.widget.Toolbar { *; } |
| 193 | + |
| 194 | +-keep class com.google.android.material.bottomnavigation.BottomNavigationView |
| 195 | +-keepclassmembers class com.google.android.material.bottomnavigation.BottomNavigationView { *; } |
| 196 | + |
| 197 | +-keep class com.google.android.material.bottomnavigation.BottomNavigationItemView |
| 198 | +-keepclassmembers class com.google.android.material.bottomnavigation.BottomNavigationItemView { *; } |
| 199 | + |
| 200 | +-keep class androidx.appcompat.view.menu.MenuItemImpl |
| 201 | +-keepclassmembers class androidx.appcompat.view.menu.MenuItemImpl { *; } |
| 202 | + |
| 203 | +-keep class com.google.android.material.navigation.NavigationView |
| 204 | +-keepclassmembers class com.google.android.material.navigation.NavigationView { *; } |
| 205 | + |
| 206 | +-keep class com.google.android.material.internal.NavigationMenuPresenter** { *; } |
| 207 | +-keepclassmembers class com.google.android.material.internal.NavigationMenuPresenter { *; } |
| 208 | + |
| 209 | +-keep class com.google.android.material.bottomappbar.BottomAppBar |
| 210 | +-keepclassmembers class com.google.android.material.bottomappbar.BottomAppBar { *; } |
| 211 | +``` |
0 commit comments