我已经在我的片段中编写了一段代码,该代码将在Toast
上由用户选择的特定时间显示Time Picker
消息。通过从时间选择器时间(以毫秒为单位)减去当前时间(以毫秒为单位)来计算时间延迟。
但是没有显示toast消息,我在logcat中也没有收到任何错误。
以下是代码段:
public class ManualControlsFragment extends Fragment {
private TimePicker tp;
private Calendar calendar;
Handler mHandler;
private Runnable scheduledTask;
long pickedTimeInMillis=0;
//some fragment methods
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
tp = (TimePicker) view.findViewById(R.id.lightTimePickerStart);
tp.setIs24HourView(true);
calendar = Calendar.getInstance();
//get time picked in milliseconds
tp.setOnTimeChangedListener(new TimePicker.OnTimeChangedListener() {
@Override
public void onTimeChanged(TimePicker view, int hourOfDay, int minute) {
calendar.set(Calendar.HOUR_OF_DAY, hourOfDay);
calendar.set(Calendar.MINUTE, minute);
pickedTimeInMillis= calendar.getTimeInMillis();
}
});
//Calendar instance to get current time
Calendar cal = Calendar.getInstance();
//get the difference to get the delay
long timeDifference = pickedTimeInMillis - cal.getTimeInMillis();
mHandler = new Handler();
mHandler.postDelayed(scheduledTask, timeDifference);
scheduledTask = new Runnable() {
String text= "Bulb is now on";
@Override
public void run() {
Toast.makeText(
getActivity(), text, Toast.LENGTH_LONG).show();
}
};
return view;
}
在阅读完评论和答案后,我编写了代码:
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
new Handler().postDelayed(new Runnable() {
String text= "Bulb is now on";
@Override
public void run() {
//Do something after 1 second
Toast.makeText(getActivity().getApplicationContext(), text, Toast.LENGTH_LONG).show();
}
}, timeDifference);
}
});
然而,只有当我启动应用程序时才会显示toast(当我启动它时,时间选择器上的时间是当前时间,这就是为什么我认为它会显示吐司的原因)。当我在应用程序运行时在时间选择器上设置时间时,不显示toast。
答案 0 :(得分:1)
正如我在评论中所说,您需要更改代码中的顺序,以使其按您的意愿执行。
首先,在Handler的postDelayed()方法中初始化scheduledTask 之前,否则你所做的只是发布一个null Runnable。你的代码应该是:
scheduledTask = new Runnable() {
String text= "Bulb is now on";
@Override
public void run() {
Toast.makeText(
getActivity(), text, Toast.LENGTH_LONG).show();
}
};
mHandler.postDelayed(scheduledTask, timeDifference);
其次,下面的代码(在onCreateView()方法内部):
Calendar cal = Calendar.getInstance();
//get the difference to get the delay
long timeDifference = pickedTimeInMillis - cal.getTimeInMillis();
会立即触发Toast,因为pickedTimeInMillis将 0 所以时间差将为负,这将向上舍入为0(因此立即执行)。如果你想要这个,请保留这部分代码,否则从onCreateView()中删除它。
第三,您需要在用户更改时间时发布Runnable 并调用OnTimeChangedListener侦听器。所以监听器中的代码应该是:
@Override
public void onTimeChanged(TimePicker view, int hourOfDay, int minute) {
calendar.set(Calendar.HOUR_OF_DAY, hourOfDay);
calendar.set(Calendar.MINUTE, minute);
pickedTimeInMillis= calendar.getTimeInMillis();
// at this point get the current time
Calendar cal = Calendar.getInstance();
// now calculate the difference as the user actually selected a time
long timeDifference = pickedTimeInMillis - cal.getTimeInMillis();
// register the Runnable to run
mHandler.postDelayed(scheduledTask, timeDifference);
}
此外,不需要runOnUiThread(),因为您声明的Handler将在主线程上运行。
答案 1 :(得分:0)
您正在另一个线程上运行Toast
,但您只能从主线程更新UI。请尝试更新Runnable run()
中的代码,例如使用runOnUiThread()
方法。