Android中点击空白区域控件自动隐藏(事件传递机制中的一个小例子)

随着android技术日趋成熟,android应用程序已经由刚开始的单纯效果展示变得越来越艺术话了,各种动画,各种布局层叠,那么由此就产生了一些问题,比如:一个listview的view的item点击时没有反应,界面上罩了层好看的蒙版后,下面的布局中的控件点击时无反应等。

今天我在修改bug的时候就遇到了这样的问题。 一、item点击时没有反应 原因:你的item中有button或者checkbox等控件,默认情况下焦点focus是最先交给这些子控件,而ListView的Item能被选中的基础是它能获取Focus焦点。 解决办法: 1、将item layout的根控件设置属性(android:descendantFocusability=”blocksDescendant”),以下是item的布局 <!-- lang: java --> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#F4F2EE" android:descendantFocusability="blocksDescendants" android:orientation="vertical" android:paddingBottom="2dp" android:paddingLeft="10dp" android:paddingRight="10dp" android:paddingTop="7dp" >

<!-- lang: java -->
   <Button/>
   <ImageView/>
    ........

</LinearLayout > 这样Item Layout就屏蔽了所有子控件获取Focus焦点的权限,不需要针对Item Layout中的每一个控件重新设置focusable属性. 2.将ListView的Item Layout中的所有子控件focusable属性设置为false

二、界面上罩了层好看的蒙版后,下层的布局中的控件点击时无反应 原因:上面罩得那一层蒙版将点击或者触摸事件给拦截掉了,Touchevent 中,返回值是 true ,则说明消耗掉了这个事件,返回值是 false ,则没有消耗掉,会继续传递下去。 在 View 中跟 Touch 相关的事件有 dispatchTouchEvent , interceptTouchEvnet , onTouchEvent 三种。 dispatchTouchEvent 是负责分发事件的,事件从 activity 传递出来之后,最先到达的就是最顶层 view 的 dispatchTouchEvent ,然后它进行分发,如果返回 false ,则交给这个 view 的 interceptTouchEvent 方法来决定是否要拦截这个事件,如果 interceptTouchEvent 返回 true ,也就是拦截掉了,则交给它的 onTouchEvent 来处理,如果 interceptTouchEvent 返回 false ,那么就传递给子 view ,由子 view 的 dispatchTouchEvent 再来开始这个事件的分发。

如果事件传递到某一层的子 view 的 onTouchEvent 上了,这个方法返回了 false ,那么这个事件会从这个 view 往上传递,都是 onTouchEvent 来接收

解决办法:

<!-- lang: java -->
<RelativeLayout 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:background="#F4F2EE"
android:orientation="vertical"
>

<include
    android:id="@+id/title_view"
    layout="@layout/title" />

<RelativeLayout>
</RelativeLayout>
 .......
<FrameLayout
    android:id="@+id/above_fl"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:layout_below="@id/title_view"
    android:background="#00000000" >
</FrameLayout>

</RelativeLayout> 以上FrameLayout就是上面罩得一层透明的罩子,如果不采取任何措施只是将这个罩到布局上面的时候,点击下面的那些控件的时候是无任何响应的,因为这个FrameLayout已经点击或者触摸事件给拦截掉了, 这时候可以使用以下的代码让点击事件穿透这个罩子,见代码

<!-- lang: java -->
private FrameLayout outLineView;

outLineView = (FrameLayout) findViewById(R.id.above_fl);
    outLineView.setOnTouchListener(new OnTouchListener() {

        @Override
        public boolean onTouch(View v, MotionEvent event) {
            if (mPopupWindow.isShowing()) {
                AnimationUtils.rotateDown(title_icon);
                mPopupWindow.dismiss();
            }
            return false;
        }
    });

outLineView的onTouch方法返回false,这样点击或者触摸事件就穿到下面的一层啦。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值