可能是最好用的Android引導層庫

胡奚冰發表於2018-04-18

今天來推薦一個好用遮罩引導庫,這是我持續維護了大半年的開源專案。剛完成第一版的時候,我也記錄了文章,並且有幸推薦到了郭霖大神的公眾號: 推薦一個好用小巧的Android引導蒙版(浮層)庫。第一版的功能還是比較簡單,在後續的持續迭代中,我也新增了好多新功能:fragment支援,多頁連續顯示,切換動畫,anchor等。現在的2.x版本相比第一版,包括呼叫方式,基本已經完全不一樣的。

如果你看過我的上述文章,就知道我為什麼建立這個專案。但隨著我的特意關注下,發現其實有很多類似的輪子,比較有名的有:GuideViewHighlightTourGuide等等。我也一一下載了這些專案,學習它們的原始碼,分析它們的實現。借鑑這些專案之後,我嘗試吸取各個專案的優點,不斷完善自己的專案,以維護專案的方式讓自己成長。

到目前,這個專案擁有大部分上述專案的功能點,並且使用方式更加簡便。具體如何使用還是看下面的介紹吧~

專案地址

NewbieGuide

匯入

專案的build.gradle新增

allprojects {
	repositories {
		...
		maven { url 'https://jitpack.io' }
	}
}
複製程式碼

module的build.gradle新增

 dependencies {
	  compile 'com.github.huburt-Hu:NewbieGuide:v2.0.1'
}
複製程式碼

如果你的專案中使用了appcompat-v7,可以排除此庫對v7的引用,避免版本混淆

 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();
複製程式碼

通過鏈式呼叫,一行程式碼即可實現引導層的顯示,來看下效果:

simple use

其中:

  • 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的方式,自定義擺放位置。使得說明內容高度自定義,不管你是簡單的圖片,還是對話方塊型別的都可以。

like dialog

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,建議設定有透明度的背景色。

anchor

預設的話引導層是新增在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();
複製程式碼

這裡實現了具體顯示引導層。

anchor

引導層其實是一個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

相關文章