在 onResume() 中处理 ToggleButton

Handle ToggleButton in onResume()

我编写了一个程序,我在其中使用 Timer 并使用 Toggle 状态控制该计时器。

Toggle's 默认状态是 OFF,一旦我将切换状态从 OFF 更改为 ON Timer 开始,当我再次更改时OFF 它根据要求停止 Timer

但是当我的 TimerON 并且我切换到其他 activity 然后又从 come backToggleActivity 然后在将状态从 ON 切换到 OFF - 它仍然运行 Timer...

注:当我用finish()back按下时,代替Intent回到ToggleActivity一切正常,但是当我使用 Intent 时遇到这样的问题..

ToggleActivity.java:

public class ToggleActivity extends Activity implements OnCheckedChangeListener {

    ToggleButton toggleButton;
    TextView text;

    Timer timer;
    TimerTask timerTask;
    final Handler handler = new Handler();

    Button btnSwitchActivity;

    boolean toggleState;
    SharedPreferences sharedPreferences;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);


        setContentView(R.layout.activity_toggle);           

        toggleButton = (ToggleButton) findViewById(R.id.toggleButton);
        text = (TextView) findViewById(R.id.textView1);
        btnSwitchActivity = (Button) findViewById(R.id.btnSwitchActivity);

        sharedPreferences = getApplicationContext().getSharedPreferences("toggleState",0);

        btnSwitchActivity.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                Intent intentSwitchActivity = new Intent(ToggleActivity.this, SwitchActivity.class);
                startActivity(intentSwitchActivity);
                }
            });

        }

        @Override
        public void onCheckedChanged(CompoundButton arg0, boolean isChecked) {      

            if(isChecked)
            {               
                SharedPreferences.Editor editor = sharedPreferences.edit();
                editor.putBoolean("toggleState", true);
                editor.commit();

                text.setText("ON");

                startTimer();

            } else 
            {       

                SharedPreferences.Editor editor = sharedPreferences.edit();
                editor.putBoolean("toggleState", false);
                editor.commit();

                text.setText("OFF");

                if (timer != null) {
                    timer.cancel();
                    timer = null;
                }
            }

        }


        public void startTimer() {

            timer = new Timer();            
            initializeTimerTask();          
            timer.schedule(timerTask, 1000, 5000);

        }

        public void stoptimertask(View v) {

            if (timer != null) {
                timer.cancel();
                timer = null;
            }

        }

        public void initializeTimerTask() {

            timerTask = new TimerTask() {

                public void run() {

                    handler.post(new Runnable() {

                        public void run() {
                            Calendar calendar = Calendar.getInstance();
                            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("dd:MMMM:yyyy HH:mm:ss a");
                            final String strDate = simpleDateFormat.format(calendar.getTime());

                            int duration = Toast.LENGTH_SHORT;  
                            Toast toast = Toast.makeText(getApplicationContext(), strDate, duration);
                            toast.show();
                        }

                    });

                }

            };

        }

        public void onResume() {
            super.onResume();

            toggleState = sharedPreferences.getBoolean("toggleState", false);
            Log.v("toggleState", Boolean.toString(toggleState));

            if (toggleState) {
                toggleButton.setChecked(true);
                text.setText("ON");
            } else {
                toggleButton.setChecked(false);
                text.setText("OFF");
            }

            toggleButton.setChecked(toggleState);
            toggleButton.setOnCheckedChangeListener(this);         
        }

        @Override
         protected void onPause() {
            super.onPause();             
            toggleButton.setOnCheckedChangeListener(null);
          } 

}

SwitchActivity.java

public class SwitchActivity extends Activity {

    Button btnToggleActivity;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_switch);

        btnToggleActivity = (Button) findViewById(R.id.btnToggleActivity);
        btnToggleActivity.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                Intent intent = new Intent(SwitchActivity.this, ToggleActivity.class);
                startActivity(intent);

                /**
                 * if i use finish instead of Intent to switch to ToggleActivity 
                 * my Timer works fine
                 */
                // finish
            }
        });
    }    
}

activity_toggle.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:gravity="center"
    android:background="#ffffff"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:orientation="vertical"
    tools:context=".ToggleActivity" >

    <ToggleButton
        android:id="@+id/toggleButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@drawable/toggle_selector"
        android:checked="false"
        android:text=""
        android:textOff=""
        android:textOn="" />

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"        
        android:layout_marginTop="20dp"
        android:layout_marginBottom="20dp"
        android:text="@string/string_toggle_off"
        android:textAppearance="?android:attr/textAppearanceMedium" />

    <Button 
        android:id="@+id/btnSwitchActivity"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/string_btn_switch"/>

</LinearLayout>

activity_switch.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:background="#ffffff"
    android:orientation="vertical" >

    <Button 
        android:id="@+id/btnToggleActivity"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/string_btn_goback"
        />

</LinearLayout>

你在这里调用 setChecked(true) 意味着 onCheckedChangeListener 会调用,然后也更新首选项,你必须删除侦听器并将侦听器设置为切换按钮,如下所示:

toggleMap.setOnCheckedChangeListener(null);
toggleMap.setChecked(isChecked);
toggleMap.setOnCheckedChangeListener(this);

编辑

    @Override
         protected void onResume() {
            super.onResume();

            tg1pref = preferences.getBoolean("tg1pref", false);
            toggleMap.setOnCheckedChangeListener(null);
            toggleMap.setChecked(tg1pref);
            toggleMap.setOnCheckedChangeListener(this);

               if (!tg1pref) {
                    if (timer != null) {
                         timer.cancel();
                          timer = null;
                        }   
                }
}

@Override
    protected void onPause() {
        toggleMap.setOnCheckedChangeListener(null);
        super.onPause();
    }

检查状态后将侦听器分配给切换按钮。

只需删除:

toggleMap.setOnCheckedChangeListener(this); 

onCreate 并在更新状态后在 onResume 中添加相同的行。

toggleMap.setOnCheckedChangeListener(this); 

并在 onPause() 中:

toggleMap.setOnCheckedChangeListener(null);

像这样:

@Override
protected void onResume() {
    super.onResume();

    tg1pref = preferences.getBoolean("tg1pref", false);
    if (!tg1pref) {
        if (timer != null) {
            timer.cancel();
            timer = null;
        }   
    }
    toggleMap.setChecked(tg1pref);
    toggleMap.setOnCheckedChangeListener(this);
}

和:

@Override
protected void onPause() {
    super.onPause();
    toggleMap.setOnCheckedChangeListener(null);
}

ToggleActivity切换到onPause状态时,不会取消运行Timer。您需要手动取消它。

您可以在 onPause() 方法中添加以下代码片段:

if (timerTask != null)
    timerTask.cancel();
if (timer != null) {
    timer.cancel();
    timer = null;
}

我想这个问题是因为对于 activity 的每个实例都会创建一个计时器实例。因此,当您按下停止键时,只有一个计时器实例会停止,而后台 activity 的计时器实例不会停止。

我通过将计时器设置为静态来解决这个问题

static Timer timer;

并且只启动一个计时器实例

public void startTimer() {
    if (timer == null) {
        timer = new Timer();
        initializeTimerTask();
        timer.schedule(timerTask, 1000, 5000);
    }
}

希望对您有所帮助...

"But problem starts when my Timer is ON and I switch to other activity and then again come back to Toggle activity"...

你别回来了。正如@Fabin Paul 提到的,您只需创建一个 ToggleActivity 的新实例。因此,在您启动应用程序然后移动到 SwitchActivity 并通过单击按钮返回的情况下,back stack 如下所示:

ToggleActivity(1) -> SwitchActivity -> ToggleActivity(2)

"...然后将切换状态从 ON 更改为 OFF - 它仍然运行 Timer..."

您关闭了 ToggleActivity 的第二个实例的计时器。 运行 属于第一个 ToggleActivity 的实例。

"when I use finish(); or back press, in place of Intent to come back to ToggleActivity everything works fine..."

是的,确实如此,因为您没有创建 ToggleActivity 的第二个实例并且您的逻辑工作正常。

获得所需行为的最简单方法是将 android:launchMode="singleInstance" 添加到清单的 ToggleActivity 标记中。