




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
【移動(dòng)應(yīng)用開發(fā)技術(shù)】如何在Android頁面中使用引導(dǎo)蒙層
今天就跟大家聊聊有關(guān)如何在Android頁面中使用引導(dǎo)蒙層,可能很多人都不太了解,為了讓大家更加了解,在下給大家總結(jié)了以下內(nèi)容,希望大家根據(jù)這篇文章可以有所收獲。public
class
GuideView
extends
RelativeLayout
implements
ViewTreeObserver.OnGlobalLayoutListener
{
private
final
String
TAG
=
getClass().getSimpleName();
private
Context
mContent;
private
List<View>
mViews;
private
boolean
first
=
true;
/**
*
targetView前綴。SHOW_GUIDE_PREFIX
+
targetView.getId()作為保存在SP文件的key。
*/
private
static
final
String
SHOW_GUIDE_PREFIX
=
"show_guide_on_view_";
/**
*
GuideView
偏移量
*/
private
int
offsetX,
offsetY;
/**
*
targetView
的外切圓半徑
*/
private
int
radius;
/**
*
需要顯示提示信息的View
*/
private
View
targetView;
/**
*
自定義View
*/
private
View
customGuideView;
/**
*
透明圓形畫筆
*/
private
Paint
mCirclePaint;
/**
*
背景色畫筆
*/
private
Paint
mBackgroundPaint;
/**
*
targetView是否已測量
*/
private
boolean
isMeasured;
/**
*
targetView圓心
*/
private
int[]
center;
/**
*
繪圖層疊模式
*/
private
PorterDuffXfermode
porterDuffXfermode;
/**
*
繪制前景bitmap
*/
private
Bitmap
bitmap;
/**
*
背景色和透明度,格式
#aarrggbb
*/
private
int
backgroundColor;
/**
*
Canvas,繪制bitmap
*/
private
Canvas
temp;
/**
*
相對于targetView的位置.在target的那個(gè)方向
*/
private
Direction
direction;
/**
*
形狀
*/
private
MyShape
myShape;
/**
*
targetView左上角坐標(biāo)
*/
private
int[]
location;
private
boolean
onClickExit;
private
OnClickCallback
onclickListener;
private
RelativeLayout
guideViewLayout;
public
void
restoreState()
{
Log.v(TAG,
"restoreState");
offsetX
=
offsetY
=
0;
radius
=
0;
mCirclePaint
=
null;
mBackgroundPaint
=
null;
isMeasured
=
false;
center
=
null;
porterDuffXfermode
=
null;
bitmap
=
null;
needDraw
=
true;
//
backgroundColor
=
Color.parseColor("#00000000");
temp
=
null;
//
direction
=
null;
}
public
int[]
getLocation()
{
return
location;
}
public
void
setLocation(int[]
location)
{
this.location
=
location;
}
public
GuideView(Context
context)
{
super(context);
this.mContent
=
context;
init();
}
public
int
getRadius()
{
return
radius;
}
public
void
setRadius(int
radius)
{
this.radius
=
radius;
}
public
void
setOffsetX(int
offsetX)
{
this.offsetX
=
offsetX;
}
public
void
setOffsetY(int
offsetY)
{
this.offsetY
=
offsetY;
}
public
void
setDirection(Direction
direction)
{
this.direction
=
direction;
}
public
void
setShape(MyShape
shape)
{
this.myShape
=
shape;
}
public
void
setCustomGuideView(View
customGuideView)
{
this.customGuideView
=
customGuideView;
if
(!first)
{
restoreState();
}
}
public
void
setBgColor(int
background_color)
{
this.backgroundColor
=
background_color;
}
public
View
getTargetView()
{
return
targetView;
}
public
void
setTargetView(View
targetView)
{
this.targetView
=
targetView;
//
restoreState();
if
(!first)
{
//
guideViewLayout.removeAllViews();
}
}
private
void
init()
{
}
public
void
showOnce()
{
if
(targetView
!=
null)
{
mContent.getSharedPreferences(TAG,
Context.MODE_PRIVATE).edit().putBoolean(generateUniqId(targetView),
true).commit();
}
}
private
boolean
hasShown()
{
if
(targetView
==
null)
return
true;
return
mContent.getSharedPreferences(TAG,
Context.MODE_PRIVATE).getBoolean(generateUniqId(targetView),
false);
}
private
String
generateUniqId(View
v)
{
return
SHOW_GUIDE_PREFIX
+
v.getId();
}
public
int[]
getCenter()
{
return
center;
}
public
void
setCenter(int[]
center)
{
this.center
=
center;
}
public
void
hide()
{
Log.v(TAG,
"hide");
if
(customGuideView
!=
null)
{
targetView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
this.removeAllViews();
((FrameLayout)
((Activity)
mContent).getWindow().getDecorView()).removeView(this);
restoreState();
}
}
public
void
show()
{
Log.v(TAG,
"show");
if
(hasShown())
return;
if
(targetView
!=
null)
{
targetView.getViewTreeObserver().addOnGlobalLayoutListener(this);
}
this.setBackgroundResource(R.color.transparent);
((FrameLayout)
((Activity)
mContent).getWindow().getDecorView()).addView(this);
first
=
false;
}
/**
*
添加提示文字,位置在targetView的下邊
*
在屏幕窗口,添加蒙層,蒙層繪制總背景和透明圓形,圓形下邊繪制說明文字
*/
private
void
createGuideView()
{
Log.v(TAG,
"createGuideView");
//
添加到蒙層
//
if
(guideViewLayout
==
null)
{
//
guideViewLayout
=
new
RelativeLayout(mContent);
//
}
//
Tips布局參數(shù)
LayoutParams
guideViewParams;
guideViewParams
=
new
LayoutParams(LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT);
guideViewParams.setMargins(0,
center[1]
+
radius
+
10,
0,
0);
if
(customGuideView
!=
null)
{
//
LayoutParams
guideViewParams
=
new
LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
if
(direction
!=
null)
{
int
width
=
this.getWidth();
int
height
=
this.getHeight();
int
left
=
center[0]
-
radius;
int
right
=
center[0]
+
radius;
int
top
=
center[1]
-
radius;
int
bottom
=
center[1]
+
radius;
switch
(direction)
{
case
TOP:
this.setGravity(Gravity.BOTTOM
|
Gravity.CENTER_HORIZONTAL);
guideViewParams.setMargins(offsetX,
offsetY
-
height
+
top,
-offsetX,
height
-
top
-
offsetY);
break;
case
LEFT:
this.setGravity(Gravity.RIGHT);
guideViewParams.setMargins(offsetX
-
width
+
left,
top
+
offsetY,
width
-
left
-
offsetX,
-top
-
offsetY);
break;
case
BOTTOM:
this.setGravity(Gravity.CENTER_HORIZONTAL);
guideViewParams.setMargins(offsetX,
bottom
+
offsetY,
-offsetX,
-bottom
-
offsetY);
break;
case
RIGHT:
guideViewParams.setMargins(right
+
offsetX,
top
+
offsetY,
-right
-
offsetX,
-top
-
offsetY);
break;
case
LEFT_TOP:
this.setGravity(Gravity.RIGHT
|
Gravity.BOTTOM);
guideViewParams.setMargins(offsetX
-
width
+
left,
offsetY
-
height
+
top,
width
-
left
-
offsetX,
height
-
top
-
offsetY);
break;
case
LEFT_BOTTOM:
this.setGravity(Gravity.RIGHT);
guideViewParams.setMargins(offsetX
-
width
+
left,
bottom
+
offsetY,
width
-
left
-
offsetX,
-bottom
-
offsetY);
break;
case
RIGHT_TOP:
this.setGravity(Gravity.BOTTOM);
guideViewParams.setMargins(right
+
offsetX,
offsetY
-
height
+
top,
-right
-
offsetX,
height
-
top
-
offsetY);
break;
case
RIGHT_BOTTOM:
guideViewParams.setMargins(right
+
offsetX,
bottom
+
offsetY,
-right
-
offsetX,
-top
-
offsetY);
break;
}
}
else
{
guideViewParams
=
new
LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
guideViewParams.setMargins(offsetX,
offsetY,
-offsetX,
-offsetY);
}
//
guideViewLayout.addView(customGuideView);
this.addView(customGuideView,
guideViewParams);
}
}
/**
*
獲得targetView
的寬高,如果未測量,返回{-1,
-1}
*
*
@return
*/
private
int[]
getTargetViewSize()
{
int[]
location
=
{-1,
-1};
if
(isMeasured)
{
location[0]
=
targetView.getWidth();
location[1]
=
targetView.getHeight();
}
return
location;
}
/**
*
獲得targetView
的半徑
*
*
@return
*/
private
int
getTargetViewRadius()
{
if
(isMeasured)
{
int[]
size
=
getTargetViewSize();
int
x
=
size[0];
int
y
=
size[1];
return
(int)
(Math.sqrt(x
*
x
+
y
*
y)
/
2);
}
return
-1;
}
boolean
needDraw
=
true;
@Override
protected
void
onDraw(Canvas
canvas)
{
super.onDraw(canvas);
Log.v(TAG,
"onDraw");
if
(!isMeasured)
return;
if
(targetView
==
null)
return;
//
if
(!needDraw)
return;
drawBackground(canvas);
}
private
void
drawBackground(Canvas
canvas)
{
Log.v(TAG,
"drawBackground");
needDraw
=
false;
//
先繪制bitmap,再將bitmap繪制到屏幕
bitmap
=
Bitmap.createBitmap(canvas.getWidth(),
canvas.getHeight(),
Bitmap.Config.ARGB_8888);
temp
=
new
Canvas(bitmap);
//
背景畫筆
Paint
bgPaint
=
new
Paint();
if
(backgroundColor
!=
0)
bgPaint.setColor(backgroundColor);
else
bgPaint.setColor(getResources().getColor(R.color.shadow));
//
繪制屏幕背景
temp.drawRect(0,
0,
temp.getWidth(),
temp.getHeight(),
bgPaint);
//
targetView
的透明圓形畫筆
if
(mCirclePaint
==
null)
mCirclePaint
=
new
Paint();
porterDuffXfermode
=
new
PorterDuffXfermode(PorterDuff.Mode.SRC_OUT);//
或者CLEAR
mCirclePaint.setXfermode(porterDuffXfermode);
mCirclePaint.setAntiAlias(true);
if
(myShape
!=
null)
{
RectF
oval
=
new
RectF();
switch
(myShape)
{
case
CIRCULAR://圓形
temp.drawCircle(center[0],
center[1],
radius,
mCirclePaint);//繪制圓形
break;
case
ELLIPSE://橢圓
//RectF對象
oval.left
=
center[0]
-
150;
//左邊
oval.top
=
center[1]
-
50;
//上邊
oval.right
=
center[0]
+
150;
//右邊
oval.bottom
=
center[1]
+
50;
//下邊
temp.drawOval(oval,
mCirclePaint);
//繪制橢圓
break;
case
RECTANGULAR://圓角矩形
//RectF對象
oval.left
=
center[0]
-
150;
//左邊
oval.top
=
center[1]
-
50;
//上邊
oval.right
=
center[0]
+
150;
//右邊
oval.bottom
=
center[1]
+
50;
//下邊
temp.drawRoundRect(oval,
radius,
radius,
mCirclePaint);
//繪制圓角矩形
break;
}
}
else
{
temp.drawCircle(center[0],
center[1],
radius,
mCirclePaint);//繪制圓形
}
//
繪制到屏幕
canvas.drawBitmap(bitmap,
0,
0,
bgPaint);
bitmap.recycle();
}
public
void
setOnClickExit(boolean
onClickExit)
{
this.onClickExit
=
onClickExit;
}
public
void
setOnclickListener(OnClickCallback
onclickListener)
{
this.onclickListener
=
onclickListener;
}
private
void
setClickInfo()
{
final
boolean
exit
=
onClickExit;
setOnClickListener(new
OnClickListener()
{
@Override
public
void
onClick(View
v)
{
if
(onclickListener
!=
null)
{
onclickListener.onClickedGuideView();
}
if
(exit)
{
hide();
}
}
});
}
@Override
public
void
onGlobalLayout()
{
if
(isMeasured)
return;
if
(targetView.getHeight()
>
0
&&
targetView.getWidth()
>
0)
{
isMeasured
=
true;
}
//
獲取targetView的中心坐標(biāo)
if
(center
==
null)
{
//
獲取右上角坐標(biāo)
location
=
new
int[2];
targetView.getLocationInWindow(location);
center
=
new
int[2];
//
獲取中心坐標(biāo)
center[0]
=
location[0]
+
targetView.getWidth()
/
2;
center[1]
=
location[1]
+
targetView.getHeight()
/
2;
}
//
獲取targetView外切圓半徑
if
(radius
==
0)
{
radius
=
getTargetViewRadius();
}
//
添加GuideView
createGuideView();
}
/**
*
定義GuideView相對于targetView的方位,共八種。不設(shè)置則默認(rèn)在targetView下方
*/
enum
Direction
{
LEFT,
TOP,
RIGHT,
BOTTOM,
LEFT_TOP,
LEFT_BOTTOM,
RIGHT_TOP,
RIGHT_BOTTOM
}
/**
*
定義目標(biāo)控件的形狀,共3種。圓形,橢圓,帶圓角的矩形(可以設(shè)置圓角大小),不設(shè)置則默認(rèn)是圓形
*/
enum
MyShape
{
CIRCULAR,
ELLIPSE,
RECTANGULAR
}
/**
*
GuideView點(diǎn)擊Callback
*/
interface
OnClickCallback
{
void
onClickedGuideView();
}
public
static
class
Builder
{
static
GuideView
guiderView;
static
Builder
instance
=
new
Builder();
Context
mContext;
private
Builder()
{
}
public
Builder(Context
ctx)
{
mContext
=
ctx;
}
public
static
Builder
newInstance(Context
ctx)
{
guiderView
=
new
GuideView(ctx);
return
instance;
}
public
Builder
setTargetView(View
target)
{
guiderView.setTargetView(target);
return
instance;
}
public
Builder
setBgColor(int
color)
{
guiderView.setBgColor(color);
return
instance;
}
public
Builder
setDirction(Direction
dir)
{
guiderView.setDirection(dir);
return
instance;
}
public
Builder
setShape(MyShape
shape)
{
guiderView.setShape(shape);
return
instance;
}
public
Builder
setOffset(int
x,
int
y)
{
guiderView.setOffsetX(x);
guiderView.setOffsetY(y);
return
instance;
}
public
Builder
setRadius(int
radius)
{
guiderView.s
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 市政工程專項(xiàng)施工方案
- 河道引流的施工方案
- 被動(dòng)網(wǎng)施工方案
- 硬巖豎井施工方案
- 格柵幕墻施工方案
- 二零二五年度債權(quán)債務(wù)資產(chǎn)保全執(zhí)行合同
- 2025年度離婚財(cái)產(chǎn)分割及子女成長環(huán)境優(yōu)化協(xié)議書
- 二零二五年度美容儀器加盟保證金及售后服務(wù)合同
- 2025年度跨境電商平臺(tái)員工勞動(dòng)合同解除書
- 二零二五年度公益歌曲委托創(chuàng)作與宣傳推廣合同
- 北京服裝學(xué)院招聘考試題庫2024
- DB5101-T 71-2020 成都市電動(dòng)汽車充電設(shè)施 安全管理規(guī)范
- 2025年七臺(tái)河職業(yè)學(xué)院高職單招語文2018-2024歷年參考題庫頻考點(diǎn)含答案解析
- 監(jiān)理人員安全培訓(xùn)考試試卷(答案)
- 2025年北京電子科技職業(yè)學(xué)院高職單招職業(yè)技能測試近5年常考版參考題庫含答案解析
- xxx項(xiàng)目財(cái)務(wù)評價(jià)報(bào)告
- 2024年山東交通職業(yè)學(xué)院高職單招語文歷年參考題庫含答案解析
- 團(tuán)隊(duì)賦能培訓(xùn)
- 2025年廣東廣州市黃埔區(qū)第二次招聘社區(qū)專職工作人員高頻重點(diǎn)提升(共500題)附帶答案詳解
- 第一單元第2課《人工智能應(yīng)用》說課稿 2023-2024學(xué)年浙教版(2023)初中信息技術(shù)八年級(jí)下冊
- 2025年寫人要抓住特點(diǎn)
評論
0/150
提交評論