“Press and hold” button on Android needs to change states (custom XML selector) using onTouchListener

后端 未结 5 1391
北恋
北恋 2020-12-09 17:01

I\'ve got a button graphic which needs to have \"press and hold\" functionality, so instead of using onClickListener, I\'m using onTouchListener so that the app can react to

相关标签:
5条回答
  • 2020-12-09 17:14

    Better solution:

    <?xml version="1.0" encoding="utf-8"?>
    <selector xmlns:android="http://schemas.android.com/apk/res/android" >
        <item android:state_activated="true">
            <bitmap android:src="@drawable/image_selected"/>
        </item>
        <item>
            <bitmap android:src="@drawable/image_not_selected"/>
        </item>
    </selector>
    
    @Override
    public void onClick(View v) {
        if (v.isActivated())
           v.setActivated(false);
        else
           v.setActivated(true);
    }
    
    0 讨论(0)
  • 2020-12-09 17:25

    Make sure to return false at the end of the onTouchListener() function. :)

    0 讨论(0)
  • 2020-12-09 17:29

    I figured it out! Just use view.setSelected() as follows:

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        if(event.getAction() == MotionEvent.ACTION_DOWN){
            yourView.setSelected(true);
            ...
            return true;
        }
        else if(event.getAction() == MotionEvent.ACTION_UP){
            yourView.setSelected(false);
            ...
            return true;
        }
        else 
            return false;
    }
    

    That'll make your selector work even if your view has an onTouch listener :)

    0 讨论(0)
  • 2020-12-09 17:33

    Use the view.setPressed() function to simulate the pressed behavior by yourself.

    You would probably want to enable the Pressed state when you get ACTION_DOWN event and disable it when you get the ACTION_UP event.

    Also, it will be a good idea to disable it in case the user slide out of the button. Catching the ACTION_OUTSIDE event, as shown in the example below:

    @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;
    }
    
    0 讨论(0)
  • 2020-12-09 17:33

    You can just set the button onClickListener and leave its onClick method empty. Your logic implement inside onTouch. That way you'll have the press effect.

    P.S You don't need all those state in the selector you can simply use:

    <?xml version="1.0" encoding="utf-8"?>
    <selector xmlns:android="http://schemas.android.com/apk/res/android" >
    
        <item android:state_pressed="true" android:drawable="@drawable/IMAGE_PRESSED" />
    
        <item android:drawable="@drawable/IMAGE" />
    
    </selector>
    
    0 讨论(0)
提交回复
热议问题