假设我有一个控制android服务的开关:当开关处于"on“状态时,它意味着该服务正在运行,而当该开关处于”关闭“位置时,它意味着该服务没有运行。此外,当用户点击交换机时,它应该切换服务(因此切换交换机的显示状态,因为如前所述,开关的显示状态正在跟踪服务的状态)。
方法1:给开关一个onCheckedChanged侦听器,根据新的选中状态打开或关闭服务。
我不喜欢方法1,因为当用户通过点击开关打开服务时,我不希望它在服务真正启动之前看起来是打开的,这可能不是立即启动的(而且它可能根本没有成功启动,但为了简单起见,我将在这里忽略这种可能性)。同样,当用户关闭服务时,我不希望在服务实际关闭之前开关看起来是关闭的。
方法2:使它在不改变显示状态的情况下按下开关切换服务,并且只有在通知服务已成功启动或下降时才切换显示状态。
我也不喜欢方法2(即使我知道如何实现它),因为用户没有立即得到关于tap被识别的反馈,而且如果服务没有成功地改变状态,那么根本就没有反馈。我认为这很糟糕。
方法3:点击开关,立即切换拇指位置,而不是颜色,并切换服务,并使开关的颜色跟踪服务的实际状态。因此,相对于拇指位置的变化,颜色的变化可能被延迟。
这意味着开关将有4种可能的可视状态,而不是2:




我喜欢方法3的想法。实现它的最干净的方法是什么?
在我看来,我可能需要安装两个侦听器:
onCheckedChanged监听器,它允许拇指像往常一样改变位置,但它将开关的颜色设置为与通常相反的颜色(这样它就不会改变颜色),并切换服务我确信我可以知道如何实现服务已经启动或关闭的通知。注意,我不想改变拇指位置的默认行为。所以,我想我需要知道的是:我如何临时改变一个“开关”,使之具有“关闭”颜色,反之亦然?
我的印象是,这可能涉及调用一个或多个开关的方法setTint()、setTintList()、setTintMode()。但我不确定这些电话到底是什么。
我也会欢迎任何其他好的想法,如何使一个开关立即给予反馈,它是“打开”或“关闭”,而不是立即显示为“打开”或“关闭”。
发布于 2017-11-24 09:30:05
我有点喜欢你的主意。我想setTintList会成为你的朋友。
你想做的是这样的事情:
int[][] states = new int[][] {
new int[] {-android.R.attr.state_checked},
new int[] {android.R.attr.state_checked},
};
int[] thumbColors = new int[] {
Color.LIGHTBLUE,
Color.BLUE,
};
int[] trackColors = new int[] {
Color.YELLOW,
Color.RED,
};
DrawableCompat.setTintList(DrawableCompat.wrap(yourSwitchCompatView.getThumbDrawable()), new ColorStateList(states, thumbColors));
DrawableCompat.setTintList(DrawableCompat.wrap(yourSwitchCompatView.getTrackDrawable()), new ColorStateList(states, trackColors));使用此代码,您可以通过编程调整拇指/轨道颜色。您需要为每个不同的状态设置不同的颜色(正如您提到的)。根据收到的状态/回调,您希望相应地更改颜色。应该是这样的。
另一个想法可能是:
发布于 2017-11-24 09:46:34
任何时候你想要switch..use的地方都有以下布局..
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<android.support.v7.widget.SwitchCompat
android:id="@+id/sw_compat"
android:layout_width="100dp"
android:layout_height="50dp"
android:checked="false"
/>
<LinearLayout
android:id="@+id/ll_touch_interceptor"
android:layout_width="100dp"
android:layout_height="50dp"
android:orientation="vertical">
</LinearLayout>
</FrameLayout>现在开始活动,您不需要代码下面的任何onCheckedChangeListeners..use。
sw_compat= (Switch) findViewById(R.id.sw_compat);
ll_touch_interceptor= (LinearLayout) findViewById(R.id.ll_touch_interceptor);
ll_touch_interceptor.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
ProgressDialog dialog = new ProgressDialog(DummyDialog.this);
if (sw_compat.isChecked())
{
dialog.setMessage("Demolishing service");
dialog.show();
//write code to initiate service / operation
//whenever you got feedback that service got successfully initiated then check the switch
if (service_successfully_disabled) {
dialog.dismiss();
sw_compat.setChecked(false);
}
else
{
Toast.makeText(DummyDialog.this, "Sorry! Failed to stop service", Toast.LENGTH_SHORT).show();
}
}
else
{
dialog.setMessage("Initiating service");
dialog.show();
if (service_successfully_enabled) {
dialog.dismiss();
sw_compat.setChecked(true);
}
else
{
Toast.makeText(DummyDialog.this, "Sorry! Failed to start service", Toast.LENGTH_SHORT).show();
}
}
}
});https://stackoverflow.com/questions/47469451
复制相似问题