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>
相关文章推荐
- Android 关于“NetworkOnMainThreadException”出错提示的原因及解决办法
- Android笔记(四十四) Android中的数据存储——SQLite(六)整合
- Android学习之保存 Activity 的状态
- android 群英传读书笔记---listview使用技巧(一)
- Android Studio安装完后,遇到了sdk manager无法更新问题
- Android Activity启动模式分析
- MSF android apk动态分析
- IT蓝豹强烈推荐:符合1-2年工作经验,开发中的难点及相关优化:
- Fragment的简单用法
- 记录Android 资源镜像
- Android开发高薪之路 蜂窝教育与您同行
- Android设置字体
- Android的Bitmap与Drawable
- 给 Android 开发者的 RxJava 详解(转载)
- 贝塞尔曲线的实现
- android netty5局域网通讯(客户端+服务端)
- Android 软键盘弹起引起布局的变化
- Android多个Activity切换时其生命周期中的方法执行顺序
- android 66 sharedperference的使用
- Android(6)RadioButton