您的位置:首页 > 移动开发 > Android开发

Android Api Demos登顶之路(111)Views-->Seacure View

2015-10-29 07:09 603 查看
/*这个demo演示了filterTouchesWhenObscured属性和 MotionEvent.FLAG_WINDOW_IS_OBSCURED
* 的用法,当有别的窗体覆盖在我们的view之上时,我们可以通过设置该属性屏蔽我们原来的View对事件的响应*/
public class MainActivity extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

Button toastButton = (Button) findViewById(R.id.toast_button);
toastButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// 显示覆盖层
showOverlay();
}
});

Button unSecureButton=(Button) findViewById(R.id.unsecure_button);
setClickedAction(unSecureButton);

Button secureButton=(Button) findViewById(R.id.secure_button);
setClickedAction(secureButton);

Button customSecureButton=(Button) findViewById(R.id.custom_secure_button);
setClickedAction(customSecureButton);
//设置对touch事件进行过滤,当有view覆盖时按钮不再响应点击事件
setTouchFilter(customSecureButton);
}

private void setTouchFilter(Button button) {
button.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
// 如果当前view被其它窗口覆盖,则弹出一个警示对话框
if((event.getFlags() & MotionEvent.FLAG_WINDOW_IS_OBSCURED)!=0){
if(event.getAction()==MotionEvent.ACTION_UP){
new AlertDialog.Builder(MainActivity.this)
.setTitle("警示对话框")
.setMessage("有别的窗口覆盖!")
.setNegativeButton("OK", null)
.show();
}
return true;
}
return false;
}
});
}

private void setClickedAction(Button button) {
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
new AlertDialog.Builder(MainActivity.this)
.setTitle("Oh No")
.setMessage("Do not click!")
.setNeutralButton("OK", null)
.show();
}
});
}

protected void showOverlay() {
OverlayViewGroup overlay = (OverlayViewGroup) getLayoutInflater()
.inflate(R.layout.overlay_layout, null);
overlay.setActivityToSpoof(this);
//以toast的形式显示覆盖层的ViewGroup
Toast toast=new Toast(this);
toast.setGravity(Gravity.FILL, 0, 0);
toast.setView(overlay);
toast.setDuration(Toast.LENGTH_LONG);
toast.show();
}

}


activity_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >

<TextView
android:id="@+id/textview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="点击按钮这个文本将会同样大小的另一个文本覆盖!" />
<Button
android:id="@+id/toast_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="Pop Up Toast"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="这是一个普通的按钮,存在风险,当覆盖在其上的Toast可见时,它仍然可以被点击"/>
<Button
android:id="@+id/unsecure_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="Unsecure Button"
android:textColor="#833"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="这个按钮,在布局文件中设置了filterTouchesWhenObscured属性,当当覆盖在其上的Toast可见时,将不会再响应点击事件!"/>
<Button
android:id="@+id/secure_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:filterTouchesWhenObscured="true"
android:text="Secure Button"
android:textColor="#833"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="这个按钮,也是安全的,它的实现方式是在代码中setTouchFilter来实现的"/>
<Button
android:id="@+id/custom_secure_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="Custom Secure Button"
android:textColor="#833"/>

</LinearLayout>


OverlayViewGroup

/*创建一个ViewGroup,它的子View的大小和位置与MainActivity中的View大小和位置相同,可以刚好覆盖住
* 原窗体中的子View。*/
public class OverlayViewGroup extends ViewGroup {
private MainActivity mActivity;

public OverlayViewGroup(Context context, AttributeSet attrs) {
super(context, attrs);
}

public void setActivityToSpoof(MainActivity activity) {
this.mActivity = activity;
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// 测量所有子View的大小
measureChildren(widthMeasureSpec, heightMeasureSpec);
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}

// 对ViewGroup进行布局
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
spoofLayout(findViewById(R.id.overlay_text),
mActivity.findViewById(R.id.textview));
spoofLayout(findViewById(R.id.overlay_button1),
mActivity.findViewById(R.id.unsecure_button));
spoofLayout(findViewById(R.id.overlay_button2),
mActivity.findViewById(R.id.secure_button));
spoofLayout(findViewById(R.id.overlay_button3),
mActivity.findViewById(R.id.custom_secure_button));
}

private void spoofLayout(View spoof, View original) {
int[] location = new int[2];
// 获取本ViewGroup在屏幕中的绝对位置,相对包括actionbar的整个屏幕的大小
// viewGroup左上角的坐标(起始坐标)被存储在了location数组当中
getLocationOnScreen(location);
int x = location[0];
int y = location[1];

original.getLocationOnScreen(location);
// 获取ViewGroup中的子View在ViewGroup中的相对位置(确保与原View在屏幕中的位置和大小相同)
x = location[0] - x;
y = location[1] - y;

// 布局遮盖层View
spoof.layout(x, y, x + original.getWidth(), y + original.getHeight());
}

}


overlay_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<com.fishtosky.secureview.OverlayViewGroup xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >

<TextView
android:id="@+id/overlay_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="这是覆盖层" />
<Button
android:id="@+id/overlay_button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#383"
android:text="Trust Me"/>
<Button
android:id="@+id/overlay_button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#383"
android:text="Trust Me"/>

<Button
android:id="@+id/overlay_button3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#383"
android:text="Trust Me"/>
</com.fishtosky.secureview.OverlayViewGroup>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: