android 如何侦听SwitchCompat小工具中的状态更改?

ctehm74n  于 2023-03-16  发布在  Android
关注(0)|答案(7)|浏览(189)

如何监听SwitchCompat小部件的点击?我想在切换开关时执行一些语句。
寻找一个相当于

button.setOnClickListener(new View.OnClickListener() {
    @Override
        public void onClick(View view) {
        //Do something
    }
});
mzmfm0qo

mzmfm0qo1#

static Boolean isTouched = false;

switchButton.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View view, MotionEvent motionEvent) {
                isTouched = true;
                return false;
            }
        });

switchButton.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener()
    {
        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
        {
            if (isTouched) {
                isTouched = false;
                if (isChecked) {
                }
                else {
                }
            }
        }
    });

试试这个!

px9o7tmv

px9o7tmv2#

您只需执行以下操作(setOnTouchListener是不必要的):

switchButton.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener()
    {
        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
        {

                if (isChecked) {
                     //if 'isChecked' is true do whatever you need...
                }
                else {
                }
            }
        }
    });
puruo6ea

puruo6ea3#

带有Butterknife开关兼容状态更改

@OnCheckedChanged(R.id.switchCompat)
  public void onCheckedChanged(SwitchCompat switchCompat, boolean isChecked) {
    Log.i("skh", "check:" + isChecked);

    if (isChecked) {
        // Log.i("skh","check:"+isChecked);
    } else {

    }
}
waxmsbnn

waxmsbnn4#

现在可以在同一个回调中使用isPressed方法进行检查。

switchCompat.setOnCheckedChangeListener { buttonView, isChecked ->
        if (buttonView?.isPressed == true) {
            // todo
        } else {
            
        }
    }
c86crjj0

c86crjj05#

我有同样的问题Slay解释的评论接受的答案。这里的解决方案!
我的解决方案,使用SwitchCompat和Kotlin。在我的情况下,只有当用户通过UI触发更改时,我才需要对更改作出React。事实上,我的开关对LiveData作出React,这使得setOnClickListenersetOnCheckedChangeListener都不可用。setOnClickListener实际上对用户交互作出正确React,但如果用户拖动拇指越过开关,则不会触发它。如果以编程方式切换开关,则另一端的setOnCheckedChangeListener也会触发(例如通过观察者)。现在在我的情况下开关存在于两个片段上,等等,RestoreInstanceState在某些情况下将触发具有覆盖正确值的旧值的开关。
因此,我查看了SwitchCompat的代码,并能够成功地模仿它在区分点击和拖动方面的行为,并使用它来构建一个自定义的touchlistener,它应该工作。

/**
 * This function calls the lambda function passed with the right value of isChecked
 * when the switch is tapped with single click isChecked is relative to the current position so we pass !isChecked
 * when the switch is dragged instead, the position of the thumb centre where the user leaves the
 * thumb is compared to the middle of the switch, and we assume that left means false, right means true
 * (there is no rtl or vertical switch management)
 * The behaviour is extrapolated from the SwitchCompat source code
 */
class SwitchCompatTouchListener(private val v: SwitchCompat, private val lambda: (Boolean)->Unit) :  View.OnTouchListener {
    companion object {
        private const val TOUCH_MODE_IDLE = 0
        private const val TOUCH_MODE_DOWN = 1
        private const val TOUCH_MODE_DRAGGING = 2
    }

    private val vc = ViewConfiguration.get(v.context)
    private val mScaledTouchSlop = vc.scaledTouchSlop
    private var mTouchMode = 0
    private var mTouchX = 0f
    private var mTouchY = 0f

    /**
     * @return true if (x, y) is within the target area of the switch thumb
     * x,y and rect are in view coordinates, 0,0 is top left of the view
     */
    private fun hitThumb(x: Float, y: Float): Boolean {
        val rect = v.thumbDrawable.bounds
        return x >= rect.left && x <= rect.right && y >= rect.top && y <= rect.bottom
    }

    override fun onTouch(view: View, event: MotionEvent): Boolean {
        if (view == v) {
            when (MotionEventCompat.getActionMasked(event)) {
                MotionEvent.ACTION_DOWN -> {
                    val x = event.x
                    val y = event.y
                    if (v.isEnabled && hitThumb(x, y)) {
                        mTouchMode = TOUCH_MODE_DOWN;
                        mTouchX = x;
                        mTouchY = y;
                    }
                }
                MotionEvent.ACTION_MOVE -> {
                    val x = event.x
                    val y = event.y
                    if (mTouchMode == TOUCH_MODE_DOWN &&
                        (abs(x - mTouchX) > mScaledTouchSlop || abs(y - mTouchY) > mScaledTouchSlop)
                    )
                        mTouchMode = TOUCH_MODE_DRAGGING;
                }
                MotionEvent.ACTION_UP,
                MotionEvent.ACTION_CANCEL -> {
                    if (mTouchMode == TOUCH_MODE_DRAGGING) {
                        val r = v.thumbDrawable.bounds
                        if (r.left + r.right < v.width) lambda(false)
                        else lambda(true)
                    } else lambda(!v.isChecked)
                    mTouchMode = TOUCH_MODE_IDLE;
                }
            }
        }
        return v.onTouchEvent(event)
    }
}

使用方法:
实际的触摸监听器,它接受lambda和要执行的代码:

myswitch.setOnTouchListener(
    SwitchCompatTouchListener(myswitch) {
        // here goes all the code for your callback, in my case
        // i called a service which, when successful, in turn would 
        // update my liveData 
        viewModel.sendCommandToMyService(it) 
    }
)

为了完整起见,下面是状态switchstate(如果有)的观测器:

switchstate.observe(this, Observer {
    myswitch.isChecked = it
})
vx6bjr1n

vx6bjr1n6#

实际上,你只需要这个

if (yourSwitchButton.isChecked()) {
//do what you want here
} else{
//do what you want here
}

就这样!

vi4fp9gy

vi4fp9gy7#

在Kotlin,你要做的就是:

switcher.setOnCheckedChangeListener { buttonView: CompoundButton, isChecked: Boolean ->
    if (isChecked) {
        // Do something
    } else {
       // Do another thing
    }
}

这是因为,即使''方法需要OnCheckedChangeListener接口的示例,在Kotlin中,当一个函数接收到一个只有一个函数作为参数的接口时,你可以表示给定的函数。
当然,你可以删除显式lambda参数类型:

switcher.setOnCheckedChangeListener { buttonView, isChecked ->

}

此外,如果您只想使用isChecked值,则可以将buttonView替换为_ like,如下所示:

switcher.setOnCheckedChangeListener { _, isChecked ->

}

相关问题