父视图和子视图的点击事件

3
我有一个RelativeLayout和一个ImageView。 以下是布局 -
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/rlMain"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/black" >

<ImageView
    android:id="@+id/ivIcon"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="@drawable/ic_launcher" />

</RelativeLayout>

Activity代码是 -

public class MainActivity extends Activity implements OnClickListener{

private RelativeLayout rlMain;
private ImageView ivIcon;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    rlMain = (RelativeLayout) findViewById(R.id.rlMain);
    ivIcon = (ImageView) findViewById(R.id.ivIcon);
    rlMain.setOnClickListener(this);
    ivIcon.setOnClickListener(this);
}

@Override
public void onClick(View v) {
    switch (v.getId()) {
    case R.id.rlMain:
        Toast.makeText(this, "Relative Layout clicked", Toast.LENGTH_SHORT).show();
        break;

    case R.id.ivIcon:
        Toast.makeText(this, "Image View clicked", Toast.LENGTH_SHORT).show();
        break;
    }

}

}

我已经为RelativeLayout(父)和ImageView(子)都应用了点击监听器。 当单击相对布局时,它会由相对布局的点击处理程序处理。(这似乎是正确的。) 当单击ImageView时,它将由ImageView处理。(这里有些困惑。) 单击ImageView时,父视图(相对布局)和子视图(ImageView)是否都应该处理? 如果只有子视图处理单击事件,那么逻辑上如何解释?

即使您点击图像,RelativeLayoutonClick监听器也将被调用。 - Pramod Ravikant
为什么不从OnCreate()方法中删除.setOnClickListener(对于ImageViewRelativeLayout都是如此)。相反,将android:onClick="onClickFunction"放在两个布局上,并将onClick()重命名为onClickFunction()@Override注释也必须被删除)。这肯定会起作用! - g00dy
@micro.pravi:不,它没有被调用。只有图像视图的点击处理程序被调用了。 - Anukool
这是因为按层级来看,ImageView在上面。所以你想同时调用它们两个? - Pramod Ravikant
无论您在哪里单击,这都可以工作。ImageViewwrap_content,如果它比RelativeLayout小,您也可以单击布局。 - g00dy
setOnClickListener()方法与覆盖视图的OnTouchEvent()(或“OnClick”)方法不同。传递给setOnClickListener的回调将从OnTouchEvent()中调用(OnTouchEvent检查mOnClickListener是否为空,如果不为空则调用)。 - samus
3个回答

3
点击事件将传递到布局层次结构中最低的子元素。如果此元素没有onClick行为,则会将事件传递给其父级,直到处理该事件。
因此,您可以将LinearLayout视为一个单独的块来处理onClick行为。如果您在布局中创建另一个可点击元素,请确保使其足够大,以降低用户错过正确项目的几率。
来源:Does making parent clickable make all child element clickable as well?

0
通常情况下,当要点击的图像尺寸非常小的时候,imageView会被放置在一个布局中,并给予一些填充,然后处理布局的点击事件。这样可以在屏幕上提供足够的区域供用户点击。

0
  1. 重写 dispatchTouchEvent 方法
  2. 获取触摸点
  3. 获取视图位置。您可以使用 getGlobalVisibleRect()getLocalVisibleRect() 根据需要检测视图位置。
  4. 设置简单的 if 语句并找到点的位置是否在 ImageView 中。
  5. 操作应为 MotionEvent.ACTION_DOWN,以仅在用户在屏幕上进行滑动操作的情况下获取第一个触摸。

Kotlin 代码:

override fun dispatchTouchEvent(ev: MotionEvent?): Boolean {
    if(ev?.action == MotionEvent.ACTION_DOWN) {
        val pointX = ev.x
        val pointY = ev.y
        val locationIvIcon = Rect()
        if(iv_icon.getGlobalVisibleRect(locationIvIcon)) {
            if(isInChildView(pointX, pointY, locationSendGiftPopup)) {
                // Do action for ImageView
            } else {
                // Do action for RelativeLayout
            }
        }
    }
    return super.dispatchTouchEvent(ev)
}


private fun isInChildView(x: Float?, y: Float?, location: Rect): Boolean {
        x?.let {
            y?.let {
                return x >= location.left && x <= location.right 
                        && y >= location.top && y <= location.bottom
            }
        }
        return false
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接