Android如何实现FAB仅响应长按不响应单击且不变灰
实现方案
实现思路
要实现FAB仅响应长按、点击事件透传下层且无状态变化,核心逻辑如下:
- 禁用FAB默认的点击属性和点击水波纹效果,避免点击时出现状态变更
- 保留系统的长按事件识别能力,仅消费长按事件
- 触摸事件最终返回
false,未被消费的点击事件会自动向下传递给下层的SurfaceView
Kotlin 实现代码
在Activity/Fragment中直接对现有FAB配置即可:
val fab = findViewById<FloatingActionButton>(R.id.your_fab_id) // 禁用默认点击属性与水波纹效果 fab.apply { isClickable = false isFocusable = false rippleColor = Color.TRANSPARENT } // 配置长按事件逻辑 fab.setOnLongClickListener { // 此处填写长按触发的业务逻辑 Toast.makeText(this@YourActivity, "长按触发", Toast.LENGTH_SHORT).show() true } // 配置触摸事件透传 fab.setOnTouchListener { view, motionEvent -> // 交给系统处理长按识别 view.onTouchEvent(motionEvent) // 返回false代表不消费任何触摸事件,点击事件会向下传递给SurfaceView false }
Java 实现代码
FloatingActionButton fab = findViewById(R.id.your_fab_id); // 禁用默认点击属性与水波纹效果 fab.setClickable(false); fab.setFocusable(false); fab.setRippleColor(Color.TRANSPARENT); // 配置长按事件逻辑 fab.setOnLongClickListener(new View.OnLongClickListener() { @Override public boolean onLongClick(View v) { // 此处填写长按触发的业务逻辑 Toast.makeText(YourActivity.this, "长按触发", Toast.LENGTH_SHORT).show(); return true; } }); // 配置触摸事件透传 fab.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { v.onTouchEvent(event); // 返回false代表不消费任何触摸事件,点击事件会向下传递给SurfaceView return false; } });
自定义FAB实现(可选)
如果需要多处复用该特性,可以直接自定义FAB控件:
class LongClickOnlyFab @JvmOverloads constructor( context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = com.google.android.material.R.attr.floatingActionButtonStyle ) : FloatingActionButton(context, attrs, defStyleAttr) { init { // 初始化时直接禁用默认点击效果 isClickable = false isFocusable = false rippleColor = Color.TRANSPARENT } override fun onTouchEvent(ev: MotionEvent?): Boolean { super.onTouchEvent(ev) // 所有触摸事件都不消费,仅由长按回调处理逻辑 return false } }
使用时直接在XML中替换原生FAB即可,长按事件同样通过setOnLongClickListener配置。
内容的提问来源于stack exchange,提问作者user21597761
相关产品推荐
相关产品推荐

