android 蒙版图片带拖动_推荐一个好用小巧的Android引导蒙版(浮层)库
更新:目前該庫(kù)已更新v2.0版本,修改了調(diào)用api,詳細(xì)使用可以看:可能是最好用的Android引導(dǎo)層庫(kù)
前言
每當(dāng)一個(gè)項(xiàng)目開(kāi)發(fā)一個(gè)新功能,總會(huì)想辦法及時(shí)讓用戶得知有這樣一個(gè)新功能,這時(shí)通常會(huì)采用引導(dǎo)頁(yè)或者蒙版(浮層)的方式提心用戶,這里有需要關(guān)注的新內(nèi)容。
遇到這種需求,最簡(jiǎn)單的想法就是將引導(dǎo)的布局直接寫在對(duì)應(yīng)的頁(yè)面中,在首次打開(kāi)時(shí)顯示,之后隱藏。但是用這種做法來(lái)顯示只會(huì)出現(xiàn)一次的布局,顯然有些浪費(fèi)資源。而且很low,完全體現(xiàn)不出OOP的編程思想。我們的項(xiàng)目中原來(lái)使用的是:http://www.jianshu.com/p/5aa96683d0dc
可以看到這是一個(gè)非常好的思路,通過(guò)DecorView來(lái)添加引導(dǎo)層,引導(dǎo)層的相關(guān)代碼就可以從activity中抽離出來(lái)。高亮則是通過(guò)畫筆的setXfermode來(lái)實(shí)現(xiàn)。作者也進(jìn)行了一定的封裝,使用的效果也挺好,但是我始終對(duì)調(diào)用的方法感覺(jué)不舒服:
每次使用時(shí)要判斷是否顯示過(guò)
if(NewbieGuideManager.isNeverShowed(this, NewbieGuideManager.TYPE_COLLECT)) {
new NewbieGuideManager(this, NewbieGuideManager.TYPE_COLLECT).addView
(mCollect, HoleBean.TYPE_CIRCLE).addView(mTitleTv, HoleBean
.TYPE_RECTANGLE).show();
}
通過(guò)下列方法顯示出引導(dǎo)層
new NewbieGuideManager(MainActivity.this,
NewbieGuideManager.TYPE_LIST).addView(view
.getChildAt(0).findViewById(R.id.logo), HoleBean
.TYPE_RECTANGLE).show();
這里還涉及到一個(gè)常量:NewbieGuideManager.TYPE_LIST,需要在manager類中定義,并且設(shè)置對(duì)應(yīng)的布局:
mNewbieGuide.setEveryWhereTouchable(false).addIndicateImg(R.drawable.left_arrow, ScreenUtils.dpToPx(mActivity,
60), ScreenUtils.dpToPx(mActivity, 110)).addMsgAndKnowTv("這個(gè)listview滾動(dòng)到item6后出現(xiàn)新手引導(dǎo)浮層,\n只有點(diǎn)擊我知道啦才會(huì)想消失",
-ScreenUtils.dpToPx(mActivity, 250)).show();
并且每增加一種引導(dǎo)浮層就要重復(fù)上述3步的過(guò)程。
優(yōu)化的NewbieGuide
由于非常介意上述的調(diào)用方式,于是我抽空在上述的思路上自己實(shí)現(xiàn)一個(gè)小巧的庫(kù),主要對(duì)調(diào)用方式進(jìn)行了封裝,通過(guò)鏈?zhǔn)秸{(diào)用,一行代碼就可以實(shí)現(xiàn)引導(dǎo)層的實(shí)現(xiàn)。
Github:https://github.com/huburt-Hu/NewbieGuide
導(dǎo)入
先來(lái)看下如何導(dǎo)入項(xiàng)目中:
項(xiàng)目的build.gradle添加
allprojects {
repositories {
...
maven { url 'https://jitpack.io' }
}
}
module的build.gradle添加
dependencies {
compile 'com.github.huburt-Hu:NewbieGuide:v1.0.2'
}
使用
使用的話非常方便,在需要引導(dǎo)層的地方添加如下代碼:
NewbieGuide.with(this)//傳入activity
.setLabel("guide1")//設(shè)置引導(dǎo)層標(biāo)示,用于區(qū)分不同引導(dǎo)層,必傳!否則報(bào)錯(cuò)
.addHighLight(view, HighLight.Type.RECTANGLE)//添加需要高亮的view
.setLayoutRes(R.layout.view_guide)//自定義的提示layout,不要添加背景色,引導(dǎo)層背景色通過(guò)setBackgroundColor()設(shè)置
.show();//顯示引導(dǎo)層
setLabel(String label)方法需要傳入一個(gè)當(dāng)前引導(dǎo)層的標(biāo)示,用于sp緩存當(dāng)前引導(dǎo)層是否已經(jīng)顯示過(guò),因此是一個(gè)必須的參數(shù),忘了設(shè)置的話會(huì)拋出異常!
addHighLight()方法有三個(gè)重載,第一個(gè)參數(shù)是需要高亮的view(通常是通過(guò)findViewById找到的view),第二個(gè)參數(shù)是高亮的類型,目前有四種:矩形,圓形,橢圓,圓角矩形(如果選擇圓角矩形的話,調(diào)用重載3個(gè)參數(shù)的方法,第三個(gè)參數(shù)是圓角的dp值),默認(rèn)的話是矩形即只有一個(gè)參數(shù)的重載。
setLayoutRes(int resId,int... id)該方法第一個(gè)參數(shù)傳入xml的布局,可以任意編輯,如提示的文字,顏色,位置,圖片等,皆有你來(lái)自定義。第二個(gè)參數(shù)是可變參數(shù),傳入該布局內(nèi)需要點(diǎn)擊消失引導(dǎo)層的view的id。之所以用這種方式是因?yàn)橥ㄟ^(guò)代碼來(lái)調(diào)整視圖非常麻煩,無(wú)法直接看到效果,我在使用中經(jīng)常要部署好多次才會(huì)確定最終位置,遠(yuǎn)沒(méi)有l(wèi)ayout.xml來(lái)實(shí)現(xiàn)布局方便。
效果
效果
當(dāng)然,這只是最簡(jiǎn)單的實(shí)現(xiàn)效果,具體要如何的界面都可以由你來(lái)自定義layout,并通過(guò)setLayoutRes()方法傳入即可。
更多配置
Controller controller = NewbieGuide.with(this)
.setOnGuideChangedListener(new OnGuideChangedListener() {//設(shè)置監(jiān)聽(tīng)
@Override
public void onShowed(Controller controller) {
//引導(dǎo)層顯示
}
@Override
public void onRemoved(Controller controller) {
//引導(dǎo)層消失
}
})
.setBackgroundColor(Color.BLACK)//設(shè)置引導(dǎo)層背景色,建議有透明度,默認(rèn)背景色為:0xb2000000
.setEveryWhereCancelable(false)//設(shè)置點(diǎn)擊任何區(qū)域消失,默認(rèn)為true
.setLayoutRes(R.layout.view_guide, R.id.textView)//自定義的提示layout,第二個(gè)可變參數(shù)為點(diǎn)擊隱藏引導(dǎo)層view的id
.alwaysShow(true)//是否每次都顯示引導(dǎo)層,默認(rèn)false
.build();//構(gòu)建引導(dǎo)層的控制器
controller.resetLabel("guide1");
controller.remove();//移除引導(dǎo)層
controller.show();//顯示引導(dǎo)層
實(shí)現(xiàn)原理
這個(gè)庫(kù)非常的小,總共只有5個(gè)類,一個(gè)接口,一個(gè)工具類。
高亮的實(shí)現(xiàn)是通過(guò)畫筆的setXfermode。即當(dāng)兩個(gè)畫布上都繪制了圖片是,可以控制最終顯示的樣式,有取重疊部分,有去除重疊部分的等等,總共有16中規(guī)則,具體下圖:
setXfermode屬性
我所使用的是clear屬性,即先通過(guò)canvas.drawColor(mBackgroundColor);繪制背景色,然后通過(guò)設(shè)置了clear屬性的畫筆
PorterDuffXfermode xfermode = new PorterDuffXfermode(PorterDuff.Mode.CLEAR);
mPaint.setXfermode(xfermode);
鏤空出需要高亮的view。
view在屏幕的位置可以通過(guò)下述方法獲取:
public RectF getRectF() {
RectF rectF = new RectF();
if (mHole != null) {
int[] location = new int[2];
mHole.getLocationOnScreen(location);
rectF.left = location[0];
rectF.top = location[1];
rectF.right = location[0] + mHole.getWidth();
rectF.bottom = location[1] + mHole.getHeight();
}
return rectF;
}
mHole就是之前傳入的需要高亮的view。
余下就是調(diào)用的封裝了,使用了建造者模式來(lái)保證鏈?zhǔn)秸{(diào)用,有興趣的可以clone代碼看下,也用不了多少時(shí)間。
后記
這個(gè)庫(kù)也是我第一個(gè)公開(kāi)的庫(kù),目前僅僅實(shí)現(xiàn)了基本的功能,后續(xù)也會(huì)不斷維護(hù)和升級(jí)。有什么疑問(wèn)或者建議,或者需要補(bǔ)充的需求都可以回復(fù),留言,感覺(jué)各位閱讀我的文章~
總結(jié)
以上是生活随笔為你收集整理的android 蒙版图片带拖动_推荐一个好用小巧的Android引导蒙版(浮层)库的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 我有1万块钱 想要全能笔记本:该买谁?
- 下一篇: 真无线也玩RGB灯效!魅族 PANDAE