LinearLayout获取焦点并响应点击事件监听

本文介绍如何使用LinearLayout实现获取焦点时的样式变化,并解决点击控件时先获取焦点再响应点击事件的问题。通过自定义toggle_fillet.xml文件来设置不同状态下的背景样式,同时通过实现View.OnTouchListener来正确响应点击事件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

LinearLayout控件

 <LinearLayout
            android:id="@+id/gj_recruit"
            android:layout_width="match_parent"
            android:layout_height="50dip"
            android:layout_marginBottom="17dip"
            android:background="@drawable/toggle_fillet"
            android:focusableInTouchMode="true"
            android:clickable="true"
            android:orientation="horizontal"
            android:padding="7dip">
1、通过background切换获取焦点和失去焦点的样式,在drawable中新建一个toggle_fillet.xml。

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:state_focused="true">
        <shape>
            <solid android:color="@color/gj_green" />
            <corners android:bottomLeftRadius="25dp" android:bottomRightRadius="25dp" android:topLeftRadius="25dp" android:topRightRadius="25dp" />
            <stroke android:width="1dp" android:color="#46c37b" />
        </shape>
    </item>

    <item>
        <shape>
            <solid android:color="@color/grid_state_pressed" />
            <corners android:bottomLeftRadius="25dp" android:bottomRightRadius="25dp" android:topLeftRadius="25dp" android:topRightRadius="25dp" />
            <stroke android:width="1dp" android:color="@color/gj_green" />
        </shape>
    </item>
</selector>
没有属性的item为默认的样式,state_fouchsed为获取焦点时的样式(item属性参考:点击打开链接)。

2、设置focusableInTouchMode和clickable为true,但是设置focusableInTouchMode为true的时候会存在一个问题,第一次点击控件的时候,它将取得焦点,第二次点击的时候才去响应点击事件。解决方案:implements View.OnTouchListener,继承touch事件,当松开的时候去执行点击事件。

2.1、判断touch事件的状态,松开时执行点击事件:

 @Override
    public boolean onTouch(View v, MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_UP){
            onClick(v);
        }
        return false;
    }










### Android Activity 获取焦点方法 在 Android 中,`Activity` 的焦点管理是一个重要的概念。当 `Activity` 获得或失去焦点时,可以通过特定的生命周期方法来处理这些事件。 #### 使用 `onWindowFocusChanged()` 方法 每当窗口的焦点状态发生变化时,系统会调用 `Activity.onWindowFocusChanged(boolean hasFocus)` 方法[^1]。通过重写该方法,可以检测响应 `Activity` 是否获得了焦点: ```java @Override public void onWindowFocusChanged(boolean hasFocus) { super.onWindowFocusChanged(hasFocus); if (hasFocus) { // 当前 Activity 已经获得焦点 } else { // 当前 Activity 失去了焦点 } } ``` #### 设置 `Activity` 可聚焦属性 为了确保 `Activity` 能够正常获取焦点,需确认其布局文件中的根视图设置了可聚焦属性。通常情况下,默认设置即可满足需求,但如果遇到特殊情况,可能需要手动调整 XML 文件中的配置: ```xml <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:focusableInTouchMode="true" android:focusable="true"> </LinearLayout> ``` 上述代码片段中,`focusableInTouchMode` 属性允许触摸模式下自动聚焦于指定控件[^4]。 #### 配合 SurfaceView 或其他组件使用 如果应用涉及自定义绘制(如 `SurfaceView`),则需要注意,在某些场景下,`SurfaceHolder` 的回调函数可能会受到焦点变化的影响。例如,当 `Activity` 失去焦点时,`surfaceDestroyed()` 将会被调用;而重新获取焦点时,则会触发 `surfaceCreated()`。 因此,在设计此类功能时,应合理安排资源释放与初始化逻辑,以避免潜在问题。 #### 测试焦点状态 除了监听焦点变更外,还可以利用 JavaScript 类似的思路验证某个具体 UI 组件是否处于激活状态。比如借助 `document.activeElement` 来判定当前哪个 HTML 元素正在接收输入[^3]。不过这适用于 Web 开发环境而非原生 Android 应用开发,请注意区分适用范围。 ### 注意事项 尽管 PopupWindow 和常规 Activity 均能实现类似悬浮窗的效果,但两者的工作机制存在本质区别。对于前者而言,它本质上属于 ViewGroup 子类的一个特殊形式;而对于后者来说,则完全遵循标准的任务栈管理模式[^2]。所以在实际项目里选用何种方案取决于业务需求以及用户体验考量因素。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值