为什么这个 MotionEvent 模拟不起作用?

发布于 2024-10-21 08:39:35 字数 1095 浏览 4 评论 0原文

在锻炼应用程序的其中一个视图中,我尝试以编程方式执行文本选择。

我能够(以编程方式)进入“文本选择模式”,该模式由视图左上角的 CursorController(又名手柄)直观地指示。

如果我手动拖动右侧的 CursorController,然后再次单击它(在模拟器中),它会按预期工作(完美),显示一条简短消息:“文本已复制到剪贴板”。

但是当我尝试以编程方式拖动右侧的 CursorController 时,什么也没有发生。

我尝试执行此操作的方法是模拟 MotionEvent。在视图中,我调用:

  event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_DOWN, x, y, 0);
  MainActivity.onTouch(this, event);

在 MainActivity 中,我当然实现 OnTouchListener:

@Override
public boolean onTouch(View v, MotionEvent event) { // called BEFORE button's onTouchEvent()
    Log.v("MainActivity::onTouch()", describeEvent(v, event));
    switch (event.getAction()) { 
        case MotionEvent.ACTION_DOWN: 
        case MotionEvent.ACTION_UP: 
            if (!v.hasFocus()) { 
                v.requestFocus(); 
             } 
             break; 
    } 
    return false; 
}

如果我理解正确,仅通过从 onTouch 返回“false”,Android 就会不断寻找另一个 UI 对象来消耗 MotionEvent 对象,最终到达我的视图

为什么这不会发生?

我一定错过了一些非常基本的东西......

In one of the views in an exercise app, am trying to perform text selection programmatically.

I am able to (programmatically) enter "text selection mode", which is visually indicated by CursorControllers (AKA handles) on the top-left corner of the view.

If I manually drag the right CursorController, then click it again (in the emulator), it works as expected (perfectly), showing a brief message: "Text copied to clipboard".

But when I try to programmatically drag that right CursorController, nothing happens.

The way I try to do this is by simulating a MotionEvent. In the view, I call:

  event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_DOWN, x, y, 0);
  MainActivity.onTouch(this, event);

In the MainActivity I of course implement OnTouchListener:

@Override
public boolean onTouch(View v, MotionEvent event) { // called BEFORE button's onTouchEvent()
    Log.v("MainActivity::onTouch()", describeEvent(v, event));
    switch (event.getAction()) { 
        case MotionEvent.ACTION_DOWN: 
        case MotionEvent.ACTION_UP: 
            if (!v.hasFocus()) { 
                v.requestFocus(); 
             } 
             break; 
    } 
    return false; 
}

If I understand correctly, by mere returning 'false' from onTouch, Android keeps looking for another UI object to consume the MotionEvent object, eventually reaching my view.

Why doesn't this happen?

I must be missing something very fundamental...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

此岸叶落 2024-10-28 08:39:35

由于缺乏可行的解决方案,我只能得出结论,出于安全原因,我一直试图完成的事情在 Android 上是不可能的。可以在以下链接中找到说明:如何通过系统发送合成的MotionEvent?

For lack of a working solution, I can only conclude that what I have been trying to accomplish isn't possible on the Android, for reasons of security. An explanation can be found in the following link: How to send synthesized MotionEvent through the system?

一生独一 2024-10-28 08:39:35

OnTouchListener 在 View 内部从 dispatchTouchEvent 调用,而 dispatchTouchEvent 又从 ViewGroupTouchDelegate 调用。如果您从您的视图调用侦听器,它只会执行您在那里所做的事情,然后返回。它不会神奇地将触摸事件委托到任何地方。

相反,在视图上调用 dispatchTouchEvent() 以获得正确的结果。

对于文本选择等方面的应用程序行为进行单元测试。请参阅 http://developer.android .com/resources/tutorials/testing/activity_test.html

The OnTouchListener is called inside the View from dispatchTouchEvent which in turn has been called from ViewGroup or a TouchDelegate. If you call the listener from your view it simply does what ever you have there and then returns. It doesn't magically delegate the touch event anywhere.

Instead Call dispatchTouchEvent() on your view to get the correct result.

For unit testing your application behavior on text selection etc. See http://developer.android.com/resources/tutorials/testing/activity_test.html

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文