如何使用OnTouch、OnFocus和OnClick实现TextView点击变色与改文本功能
问题根因
- 绑定
OnTouchListener的TextView异常:你在ACTION_UP事件中返回了true,代表完全消费该触摸事件,系统无法继续处理View的按压状态重置、焦点变更逻辑,导致state_pressed状态一直残留,背景无法回弹为白色。 - 绑定
OnClickListener的TextView双击问题:由于你开启了android:focusableInTouchMode="true",触摸模式下默认第一次点击只会触发View获得焦点,第二次点击才会触发OnClickListener回调,因此需要双击才能给currentTextView赋值。 - 额外问题:后两个TextView的XML属性缺失
android:clickable="true"、android:focusable="true",属性不一致会导致行为差异。
修复方案
1. 统一所有TextView的XML属性
给所有四个TextView补充一致的可点击、可聚焦属性,示例如下:
<TextView android:id="@+id/frame1_1" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:background="@drawable/colorchange" <!-- 统一补充三个基础属性 --> android:focusable="true" android:clickable="true" android:focusableInTouchMode="true" android:textAlignment="center" android:textColor="@color/white" android:textSize="20sp" android:textStyle="bold" /> <!-- 其余三个TextView都补充上述三个属性即可 -->
2. 统一事件处理逻辑
不要混用OnTouchListener和OnClickListener,所有TextView复用同一个触摸监听器即可,不要随意消费事件:
private TextView currentFocusTextView; // 初始化所有TextView TextView frame11 = findViewById(R.id.frame1_1); TextView frame12 = findViewById(R.id.frame1_2); TextView frame21 = findViewById(R.id.frame2_1); TextView frame22 = findViewById(R.id.frame2_2); // 统一触摸监听器 View.OnTouchListener tvTouchListener = (view, event) -> { if (event.getAction() == MotionEvent.ACTION_UP) { // 主动请求焦点,触发selector的聚焦状态 view.requestFocus(); // 记录当前选中的TextView currentFocusTextView = (TextView) view; } // 返回false,不消费事件,让系统正常处理按压状态、背景切换逻辑 return false; }; // 给所有TextView设置同一个监听器 frame11.setOnTouchListener(tvTouchListener); frame12.setOnTouchListener(tvTouchListener); frame21.setOnTouchListener(tvTouchListener); frame22.setOnTouchListener(tvTouchListener);
3. 按钮修改文本逻辑
Button modifyBtn = findViewById(R.id.你的按钮ID); modifyBtn.setOnClickListener(v -> { if (currentFocusTextView != null) { currentFocusTextView.setText("需要修改的目标文本"); } });
验证效果
- 单次点击任意TextView,按压时显示灰色,松开后自动切换为紫色聚焦状态,同时记录当前选中的TextView
- 点击修改按钮,直接修改当前选中TextView的文本即可
内容的提问来源于stack exchange,提问作者sagalo1
相关产品推荐
相关产品推荐

