android子view点击事件(click)和父view长点击事件(longclick)冲突

在Android开发中,当子View有点击事件而父View有长按事件时,长按子View不会触发父View的长按事件。通过为每个子View设置长按事件或者重写父View的dispatchTouchEvent方法来解决这个问题。本文介绍了一种重写父View事件派发的方法,根据用户点击时间判断是否将事件派发给子View。
摘要由CSDN通过智能技术生成

工作中想要实现这么一个效果:
这里写图片描述
如图中,当child有一个click事件,parent有一个longclick事件,当长按child的时候能够触发parent的longclick。

遇到的问题:
当child设置click事件时,长按child不会触发parent的longclick事件。

解决方案
1.当时我的解决方案是为child设置一个和parent一样的longclick事件,这样能够解决该问题,但是实际应用中,parent不止一个child,会有3个以上的child,那么将要为所有的child设置longclick事件,并且写出的代码不美观。

2.第二种解决方式能否让代码自动识别你的意图,是想要触发parent的longclick还是child的click事件。

接下来说明一下第二种解决方式。

对于android事件的派发机制这里不多说,网上能够找到很多的相关博客。在view的onTouchEvent方法中会看到这么一段代码

 public boolean onTouchEvent(MotionEvent event) {
    ……
    if (((viewFlags & CLICKABLE) == CLICKABLE ||
         (viewFlags & LONG_CLICKABLE) == LONG_CLICKABLE)) {
        ……
        return true;
    }
    return false;
}

其中的判断语句能够很明显的看出来,不论view设置了click还是longclick事件,该view都会消费该点击事件,否则才会把事件再交由父布局的onTouchEvent。需求中,child消费了click事件,所以parent的longclick自然不会被触发。

这里我给出的解决方案是重写parent的dispatchevent方法,根据判断用户点击时间的长短来判断是否将事件派发给child。

public class MyRelativeLayout extends RelativeLayout {
   
    public final static String TAG = "ClickTestActivity";
    Activity mActivity;
    int mTouchSlop; //最短滑动距离
    public MyRelativeLayout(Context context) {
        super(context);
        init(context);
    }

    public MyRelativeLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }

    public MyRelativeLayout(Context context, AttributeSet attrs, 
要实现自定义Toast显示时间,可以通过以下步骤进行: 1. 创建一个自定义的Toast布局文件,比如命名为custom_toast.xml。 2. 在自定义布局文件中添加一个TextView,并设置其显示内容。 3. 在Java代码中实例化该自定义布局文件,并设置其显示时间。 4. 在按事件中触发该自定义Toast显示。 具体的代码实现如下: 1. 创建自定义Toast布局文件custom_toast.xml ``` <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/custom_toast_layout" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="#88000000" android:orientation="horizontal" android:padding="20dp"> <TextView android:id="@+id/custom_toast_text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textColor="#ffffff" android:textSize="18sp" /> </LinearLayout> ``` 2. 在Java代码中实例化该自定义布局文件,并设置其显示时间。 ``` // 实例化自定义布局文件 LayoutInflater inflater = getLayoutInflater(); View layout = inflater.inflate(R.layout.custom_toast, null); // 设置Toast显示的文字内容 TextView text = (TextView) layout.findViewById(R.id.custom_toast_text); text.setText("自定义Toast显示100秒"); // 设置Toast的显示时间为100秒 int toastDurationInMilliSeconds = 100000; Toast toast = new Toast(getApplicationContext()); toast.setDuration(Toast.LENGTH_LONG); toast.setView(layout); toast.show(); ``` 3. 在按事件中触发该自定义Toast显示。 ``` button.setOnLongClickListener(new View.OnLongClickListener() { @Override public boolean onLongClick(View v) { // 在按事件中触发自定义Toast显示 // 实例化自定义布局文件 LayoutInflater inflater = getLayoutInflater(); View layout = inflater.inflate(R.layout.custom_toast, null); // 设置Toast显示的文字内容 TextView text = (TextView) layout.findViewById(R.id.custom_toast_text); text.setText("自定义Toast显示100秒"); // 设置Toast的显示时间为100秒 int toastDurationInMilliSeconds = 100000; Toast toast = new Toast(getApplicationContext()); toast.setDuration(Toast.LENGTH_LONG); toast.setView(layout); toast.show(); return true; } }); ``` 这样就可以在按事件中触发一个自定义Toast,并设置其显示时间为100秒了。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值