SeekBar 值未在 while 循环中实现
SeekBar value isn't actualized in while loop
我正在尝试创建一个 带有频闪 (闪烁)效果的手电筒应用程序,我可以使用 SeekBar 更改它(以更改频闪的频率)。我的目标是我可以在它打开(闪烁)时更改频率,如果 Seekbar 值变为 0,Flash 应该打开(没有 strobe/blinking)。
我的问题是我可以打开它(使用 Switch Btn,但是如果我增加频率,一旦我无法关闭闪光灯(但闪光灯仍然亮着,不闪烁)使用 Seekbar。如果我将 Seekbar 值设置为 0,它仍然以最低频率闪烁。
如果你能帮助我,我会很高兴
代码:
public class MainActivity 扩展 AppCompatActivity {
Camera cam;
Parameters camParams;
boolean hasCam;
int freq;
StroboRunner sr;
Thread t;
SeekBar seekBar;
Switch mySwitch;
SeekBar skBar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mySwitch = (Switch) findViewById(R.id.mySwitch);
// set the Switch to off
mySwitch.setChecked(false);
//now you need a listener to check changes in state
mySwitch.setOnCheckedChangeListener(new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
turnOnOff(isChecked);
}
});
skBar = (SeekBar) findViewById(R.id.seekBar);
skBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
freq = progress;
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
}
@Override
protected void onResume() {
super.onResume();
try {
cam = Camera.open();
camParams = cam.getParameters();
cam.startPreview();
hasCam = true;
}catch(Exception e){
}
}
private void turnOnOff(boolean on){
if(on) {
if(freq != 0){
sr = new StroboRunner();
t = new Thread(sr);
t.start();
return;
}else{
camParams.setFlashMode(Parameters.FLASH_MODE_TORCH);
}
}else if(!on){
if(t != null){
sr.stopRunning = true;
t =null;
return;
}else{
camParams.setFlashMode(Parameters.FLASH_MODE_OFF);
}
}
cam.setParameters(camParams);
cam.startPreview();
}
private class StroboRunner implements Runnable {
boolean stopRunning = false;
@Override
public void run() {
Camera.Parameters paramsOn = cam.getParameters();
Camera.Parameters paramsOff = camParams;
paramsOn.setFlashMode(Parameters.FLASH_MODE_TORCH);
paramsOff.setFlashMode(Parameters.FLASH_MODE_OFF);
try {
while (!stopRunning) {
cam.setParameters(paramsOn);
cam.startPreview();
Thread.sleep((100 - freq)*1);
cam.setParameters(paramsOff);
cam.startPreview();
Thread.sleep((100 - freq)*1);
}
}catch(Exception e){
}
}
}
}
问题比较简单但容易被忽视:
您有两个名为 freq
的变量,一个在 StroboRunner
中,一个在 MainActivity
中。
MainActivity
里面的总是在进度条变化的时候更新,但是StroboRunner
里面的代码用的是本地的freq
变量。并且只有在您打开频闪灯时才会更新,就在创建新的 StroboRunner
(sr.freq = freq;
) 之后。
这就是为什么在您关闭并再次打开频闪灯后它会再次工作的原因。
如果我没有完全弄错的话,你应该可以通过删除 StroboRunner
class 和行 [=17] 中的 freq
变量来解决这个问题=]
我终于找到了解决方法。现在完美了(手电筒带频闪效果,锁屏也能用!)
我正在尝试创建一个 带有频闪 (闪烁)效果的手电筒应用程序,我可以使用 SeekBar 更改它(以更改频闪的频率)。我的目标是我可以在它打开(闪烁)时更改频率,如果 Seekbar 值变为 0,Flash 应该打开(没有 strobe/blinking)。 我的问题是我可以打开它(使用 Switch Btn,但是如果我增加频率,一旦我无法关闭闪光灯(但闪光灯仍然亮着,不闪烁)使用 Seekbar。如果我将 Seekbar 值设置为 0,它仍然以最低频率闪烁。
如果你能帮助我,我会很高兴
代码: public class MainActivity 扩展 AppCompatActivity {
Camera cam;
Parameters camParams;
boolean hasCam;
int freq;
StroboRunner sr;
Thread t;
SeekBar seekBar;
Switch mySwitch;
SeekBar skBar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mySwitch = (Switch) findViewById(R.id.mySwitch);
// set the Switch to off
mySwitch.setChecked(false);
//now you need a listener to check changes in state
mySwitch.setOnCheckedChangeListener(new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
turnOnOff(isChecked);
}
});
skBar = (SeekBar) findViewById(R.id.seekBar);
skBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
freq = progress;
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
}
@Override
protected void onResume() {
super.onResume();
try {
cam = Camera.open();
camParams = cam.getParameters();
cam.startPreview();
hasCam = true;
}catch(Exception e){
}
}
private void turnOnOff(boolean on){
if(on) {
if(freq != 0){
sr = new StroboRunner();
t = new Thread(sr);
t.start();
return;
}else{
camParams.setFlashMode(Parameters.FLASH_MODE_TORCH);
}
}else if(!on){
if(t != null){
sr.stopRunning = true;
t =null;
return;
}else{
camParams.setFlashMode(Parameters.FLASH_MODE_OFF);
}
}
cam.setParameters(camParams);
cam.startPreview();
}
private class StroboRunner implements Runnable {
boolean stopRunning = false;
@Override
public void run() {
Camera.Parameters paramsOn = cam.getParameters();
Camera.Parameters paramsOff = camParams;
paramsOn.setFlashMode(Parameters.FLASH_MODE_TORCH);
paramsOff.setFlashMode(Parameters.FLASH_MODE_OFF);
try {
while (!stopRunning) {
cam.setParameters(paramsOn);
cam.startPreview();
Thread.sleep((100 - freq)*1);
cam.setParameters(paramsOff);
cam.startPreview();
Thread.sleep((100 - freq)*1);
}
}catch(Exception e){
}
}
}
}
问题比较简单但容易被忽视:
您有两个名为 freq
的变量,一个在 StroboRunner
中,一个在 MainActivity
中。
MainActivity
里面的总是在进度条变化的时候更新,但是StroboRunner
里面的代码用的是本地的freq
变量。并且只有在您打开频闪灯时才会更新,就在创建新的 StroboRunner
(sr.freq = freq;
) 之后。
这就是为什么在您关闭并再次打开频闪灯后它会再次工作的原因。
如果我没有完全弄错的话,你应该可以通过删除 StroboRunner
class 和行 [=17] 中的 freq
变量来解决这个问题=]
我终于找到了解决方法。现在完美了(手电筒带频闪效果,锁屏也能用!)