今天來推薦一個好用遮罩引導庫,這是我持續維護了大半年的開源項目。剛完成初版的時候,我也記錄了文章,而且有幸推薦到了郭霖大神的公衆號: 推薦一個好用小巧的Android引導蒙版(浮層)庫。初版的功能仍是比較簡單,在後續的持續迭代中,我也新增了好多新功能:fragment支持,多頁連續顯示,切換動畫,anchor等。如今的2.x版本相比初版,包括調用方式,基本已經徹底不同的。android
若是你看過個人上述文章,就知道我爲何建立這個項目。但隨着個人特地關注下,發現其實有不少相似的輪子,比較有名的有:GuideView、Highlight、TourGuide等等。我也一一下載了這些項目,學習它們的源碼,分析它們的實現。借鑑這些項目以後,我嘗試吸收各個項目的優勢,不斷完善本身的項目,以維護項目的方式讓本身成長。git
到目前,這個項目擁有大部分上述項目的功能點,而且使用方式更加簡便。具體如何使用仍是看下面的介紹吧~github
項目的build.gradle添加緩存
allprojects {
repositories {
...
maven { url 'https://jitpack.io' }
}
}
複製代碼
module的build.gradle添加bash
dependencies {
compile 'com.github.huburt-Hu:NewbieGuide:v2.0.1'
}
複製代碼
若是你的項目中使用了appcompat-v7,能夠排除此庫對v7的引用,避免版本混淆app
dependencies {
compile ('com.github.huburt-Hu:NewbieGuide:v2.0.0') {
exclude group: 'com.android.support'
}
}
複製代碼
NewbieGuide.with(activity)
.setLabel("guide1")
.addGuidePage(GuidePage.newInstance()
.addHighLight(btnSimple)
.setLayoutRes(R.layout.view_guide_simple))
.show();
複製代碼
經過鏈式調用,一行代碼便可實現引導層的顯示,來看下效果:maven
其中:ide
with
方法能夠傳入Activity或者Fragment,獲取引導頁的依附者。Fragment中使用建議傳入fragment,內部會添加監聽,當依附的Fragment銷燬時,引導層自動消失。setLabel
方法用於設置引導頁的標籤,區別不一樣的引導頁,該方法必須調用設置,不然會拋出異常。內部使用該label控制引導頁的顯示次數。addGuidePage
方法添加一頁引導頁,這裏的引導層能夠有多個引導頁,但至少須要一頁。GuidePage
即爲引導頁對象,表示一頁引導頁,能夠經過.newInstance()
建立對象。並經過addHighLight
添加一個或多個須要高亮的view,該方法有多個重載,能夠設置高亮的形狀,以及padding等(默認是矩形)。setLayoutRes
方法用於引導頁說明佈局,就是上圖的說明文字的佈局。show
方法直接顯示引導層,若是不想立刻顯示可使用build
方法返回一個Controller對象,完成構建。須要顯示得時候再次調用Controller對象的show方法進行顯示。一般狀況下引導頁只在用戶首次打開app的時候顯示,第二次進入時不顯示,所以默認只顯示一次。固然你也能夠經過.setShowCounts(3)
自定義顯示的次數,調試的時候可使用.alwaysShow(true)
設置每次都顯示。佈局
NewbieGuide.with(activity)
.setLabel("guide1")
//.setShowCounts(3)//控制次數
.alwaysShow(true)//老是顯示,調試時能夠打開
.addGuidePage(GuidePage.newInstance()
.addHighLight(btnSimple)
.setLayoutRes(R.layout.view_guide_simple))
.show();
複製代碼
就算設置了.alwaysShow(true)
,內部仍是會記錄顯示得次數,以後改會setShowCounts(3)
可能實際記錄的次數早已超過限制,所以不會再次顯示。使用Controller對象的resetLabel
方法重置次數。(或者清除應用緩存也能重置次數)
着重說明一下setLayoutRes方法,一般其餘的相似的庫都是經過代碼參數來控制說明內容展現在高亮view相對的位置,以下方。常常須要屢次運行才能找到滿意的位置的參數。大多說明內容只能出如今高亮的上下左右,須要庫的支持,自定義的程度不是很高。
我所採用的方式是將說明內容經過xml的方式,自定義擺放位置。使得說明內容高度自定義,無論你是簡單的圖片,仍是對話框類型的均可以。
GuidePage.newInstance()
.addHighLight(btnDialog)
.setEverywhereCancelable(false)//是否點擊任意位置消失引導頁,默認true
.setLayoutRes(R.layout.view_guide_dialog, R.id.btn_ok)
.setOnLayoutInflatedListener(new OnLayoutInflatedListener() {
@Override
public void onLayoutInflated(View view) {
TextView tv = view.findViewById(R.id.tv_text);
}
})
複製代碼
該方法還有一個可變參數setLayoutRes(@LayoutRes int resId, int... id)
,傳入id數組表示在佈局中點擊讓引導頁消失或者進入下一頁的View(例如,Button ok的id)。
setOnLayoutInflatedListener
設置佈局填充完成的監聽,當傳入的xml(R.layout.view_guide_dialog
)填充完成時會回答調用該監聽,用於初始化自定佈局的元素。
引導頁的背景色不要在xml中設置,經過GuidePage.setBackgroundColor()
設置引導頁的背景色,不一樣引導頁能夠有不一樣背景色,默認是0xb2000000,建議設置有透明度的背景色。
默認的話引導層是添加在DecorView中的,我借鑑了Highlight的anchor概念,能夠改變引導層添加到的view,實現局部引導層的顯示。經過調用.anchor(view)
傳入anchorView,即爲引導層的根佈局。
final View anchorView = findViewById(R.id.ll_anchor);
NewbieGuide.with(FirstActivity.this)
.setLabel("anchor") .anchor(anchorView)
.alwaysShow(true)//老是顯示,調試時能夠打開
.addGuidePage(GuidePage.newInstance() .addHighLight(btnAnchor, HighLight.Shape.CIRCLE, 5)
.setLayoutRes(R.layout.view_guide_anchor))
.show();
複製代碼
這裏實現了具體顯示引導層。
引導層實際上是一個FrameLayout,設置anchor以後,引導層的大小就與anchor所佔的位置相同。默認是DecorView,即全屏。setLayoutRes方法設置的說明佈局則會添加到引導層的FrameLayout中。
setOnGuideChangedListener添加引導層的顯示隱藏監聽,一個label表示一個引導層,一個引導層能夠有多個引導頁,引導頁切換不會觸發該監聽。
NewbieGuide.with(FirstActivity.this)
.setLabel("listener")
.alwaysShow(true)//老是顯示,調試時能夠打開
.setOnGuideChangedListener(new OnGuideChangedListener() {
@Override
public void onShowed(Controller controller) {
Toast.makeText(FirstActivity.this, "引導層顯示", Toast.LENGTH_SHORT).show();
}
@Override
public void onRemoved(Controller controller) {
Toast.makeText(FirstActivity.this, "引導層消失", Toast.LENGTH_SHORT).show();
}
})
.addGuidePage(GuidePage.newInstance().addHighLight(btnListener))
.show();
複製代碼
.setOnPageChangedListener(new OnPageChangedListener() {
@Override
public void onPageChanged(int page) {
//引導頁切換,page爲當前頁位置,從0開始
Toast.makeText(MainActivity.this, "引導頁切換:" + page, Toast.LENGTH_SHORT).show();
}
})
.addGuidePage(//添加一頁引導頁
GuidePage.newInstance()//建立一個實例
.addHighLight(button)//添加高亮的view
.addHighLight(tvBottom, HighLight.Shape.RECTANGLE)
.setLayoutRes(R.layout.view_guide)//設置引導頁佈局
.setOnLayoutInflatedListener(new OnLayoutInflatedListener() {
@Override
public void onLayoutInflated(View view) {
//引導頁佈局填充後回調,用於初始化
TextView tv = view.findViewById(R.id.textView2);
tv.setText("我是動態設置的文本");
}
})
.setEnterAnimation(enterAnimation)//進入動畫
.setExitAnimation(exitAnimation)//退出動畫
)
.addGuidePage(
GuidePage.newInstance()
.addHighLight(tvBottom, HighLight.Shape.RECTANGLE, 20)
.setLayoutRes(R.layout.view_guide_custom, R.id.iv)//引導頁佈局,點擊跳轉下一頁或者消失引導層的控件id
.setEverywhereCancelable(false)//是否點擊任意地方跳轉下一頁或者消失引導層,默認true
.setBackgroundColor(getResources().getColor(R.color.testColor))//設置背景色,建議使用有透明度的顏色
.setEnterAnimation(enterAnimation)//進入動畫
.setExitAnimation(exitAnimation)//退出動畫
)
複製代碼
如上面的例子所示,還能夠添加引導頁的切換動畫
Animation enterAnimation = new AlphaAnimation(0f, 1f);
enterAnimation.setDuration(600);
enterAnimation.setFillAfter(true);
Animation exitAnimation = new AlphaAnimation(1f, 0f);
exitAnimation.setDuration(600);
exitAnimation.setFillAfter(true);
GuidePage.setEnterAnimation(enterAnimation)//進入動畫
GuidePage.setExitAnimation(exitAnimation)//退出動畫
複製代碼
查看項目的readme