如何实现点击Floating Action Menu区域时仍可滚动ScrollView?
首先,这个问题的核心原因是:上层的FloatingActionMenu默认会拦截并消费触摸事件,导致下层的滚动控件(你的ScrollView/ViewPager内的列表)无法接收到滚动手势,自然就没法滚动了。
下面给你两种可行的解决方案,你可以根据自己的需求选择:
方案一:自定义FloatingActionMenu,让滚动事件透传给下层控件
我们可以继承原有的FloatingActionMenu,重写触摸相关的方法,当检测到滚动手势时,把事件交给父布局/下层控件处理,同时保留FAB按钮的点击功能。
步骤1:创建自定义类
import android.content.Context; import android.view.GestureDetector; import android.view.MotionEvent; import com.github.clans.fab.FloatingActionMenu; public class ScrollPassFloatingActionMenu extends FloatingActionMenu { private GestureDetector mScrollDetector; public ScrollPassFloatingActionMenu(Context context) { super(context); initDetector(); } public ScrollPassFloatingActionMenu(Context context, AttributeSet attrs) { super(context, attrs); initDetector(); } public ScrollPassFloatingActionMenu(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); initDetector(); } private void initDetector() { mScrollDetector = new GestureDetector(getContext(), new GestureDetector.SimpleOnGestureListener() { @Override public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { // 检测到滚动手势时,让父布局不要拦截事件,让下层滚动控件处理 getParent().requestDisallowInterceptTouchEvent(false); return false; } }); } @Override public boolean onTouchEvent(MotionEvent event) { // 先让滚动检测器处理事件 mScrollDetector.onTouchEvent(event); // 点击事件依然交给原FAB菜单处理 return super.onTouchEvent(event); } @Override public boolean onInterceptTouchEvent(MotionEvent event) { mScrollDetector.onTouchEvent(event); // 只拦截点击事件,不拦截滚动事件 return super.onInterceptTouchEvent(event); } }
步骤2:替换XML中的控件
把原来布局里的com.github.clans.fab.FloatingActionMenu替换成你自定义的类(注意包名要对应):
<com.example.kakaotalk3.ScrollPassFloatingActionMenu android:id="@+id/fam" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="bottom|end" android:layout_margin="16dp"> <!-- 你的FAB按钮保持不变 --> </com.example.kakaotalk3.ScrollPassFloatingActionMenu>
方案二:通过OnTouchListener处理滚动事件
如果你不想自定义控件,也可以在代码中给FloatingActionMenu设置触摸监听,检测滚动手势并传递事件:
import android.view.GestureDetector; import android.view.MotionEvent; import android.view.View; import com.github.clans.fab.FloatingActionMenu; // 在MainActivity的onCreate方法中添加 FloatingActionMenu fam = findViewById(R.id.fam); ViewPager viewPager = findViewById(R.id.viewPager); GestureDetector scrollDetector = new GestureDetector(this, new GestureDetector.SimpleOnGestureListener() { @Override public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { // 让ViewPager可以处理滚动事件 viewPager.requestDisallowInterceptTouchEvent(false); return true; } }); fam.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { scrollDetector.onTouchEvent(event); // 点击事件交给FAB菜单自己处理 return v.onTouchEvent(event); } });
这两种方案都能实现:触摸蓝色的FAB菜单区域时,滚动手势会传递给下层的ScrollView/ViewPager,同时FAB按钮的点击功能不受影响。
内容的提问来源于stack exchange,提问作者조광수
相关产品推荐
相关产品推荐

