Android上的"按住"按钮需要使用onTouchListener更改状态(自定义XML选择器)

Oct*_*rpe 19 android selector ontouchlistener onclicklistener

我有一个按钮图形,需要"按住"功能,所以我没有使用onClickListener,而是使用onTouchListener,以便应用程序可以对

 MotionEvent.ACTION_DOWN,
Run Code Online (Sandbox Code Playgroud)

 MotionEvent.ACTION_UP
Run Code Online (Sandbox Code Playgroud)

根据触发这两个事件的速度,我可以在两者之间的时间内运行"pressAndHoldHandler".

无论如何,长话短说:我在同一个应用程序中有许多"基本"按钮,不需要按住功能,所以他们使用的是onClickListener.

这些按钮中的每一个都已使用自己的XML选择器文件以图形方式自定义:

<?xml version="1.0" encoding="UTF-8"?>
<selector
    xmlns:android="http://schemas.android.com/apk/res/android">

    <item
        android:state_enabled="false"
        android:drawable="@drawable/btn_chicken_off" />

    <item
        android:state_enabled="true"
        android:state_pressed="true"
        android:drawable="@drawable/btn_chicken_s3" />

    <item
        android:state_enabled="true"
        android:state_focused="true"
        android:drawable="@drawable/btn_chicken_s2" />

    <item
        android:state_enabled="true"
        android:drawable="@drawable/btn_chicken_off" />

</selector>
Run Code Online (Sandbox Code Playgroud)

所以,这里的问题是:使用onTouchListener无法访问上面的选择器.只有onClickListener将使用自己的方法的onClick()部分拉入状态更改,因此这些"按住"按钮永远不会更改状态.对用户来说非常可怕的反馈.

我正在通过执行以下操作,在ACTION_DOWN和ACTION_UP的开关案例中强制执行上述操作:

if (action == MotionEvent.ACTION_DOWN) {
    btn_chicken.setBackgroundResource(R.drawable.btn_chicken_s3);
}
else
    if (action == MotionEvent.ACTION_UP) {
        btn_chicken.setBackgroundResource(R.drawable.btn_chicken_off);
    }
Run Code Online (Sandbox Code Playgroud)

但它似乎是一个黑客,它错过了"专注但没有压力"的阶段.

之前有人绊过这个吗?

Eya*_*ran 44

使用此view.setPressed()功能可以自己模拟按下的行为.

您可能希望在获得事件时启用" 按下"状态,ACTION_DOWN并在获得事件时禁用它ACTION_UP.

此外,如果用户滑出按钮,最好禁用它.捕获ACTION_OUTSIDE事件,如下例所示:

@Override
public boolean onTouch(View v, MotionEvent event) {

    switch (event.getAction() & MotionEvent.ACTION_MASK) {

    case MotionEvent.ACTION_DOWN:
        v.setPressed(true);
        // Start action ...
        break;
    case MotionEvent.ACTION_UP:
    case MotionEvent.ACTION_OUTSIDE:
    case MotionEvent.ACTION_CANCEL:
        v.setPressed(false);
        // Stop action ...
        break;
    case MotionEvent.ACTION_POINTER_DOWN:
        break;
    case MotionEvent.ACTION_POINTER_UP:
        break;
    case MotionEvent.ACTION_MOVE:
        break;
    }

    return true;
}
Run Code Online (Sandbox Code Playgroud)

  • 我不认为ACTION_OUTSIDE实际上被触发了.这似乎是专门用于触摸对话之外的. (2认同)

Lei*_*Lei 5

确保false在 onTouchListener() 函数结束时返回。:)