Prototype7
Prototype7

Reputation: 31

Start loop and stop code with single button click

I want to make a simple button which will start to loop a function every period of time which I can set. But not only it will start the loop, but also stop the loop if I click the button again. Is there anyway I can achieve this with a single button?

Upvotes: 0

Views: 406

Answers (2)

Cole Tustin
Cole Tustin

Reputation: 111

Here's how I'd do it

public class MainActivity extends AppCompatActivity {

    private Button btn;
    private View.OnClickListener runOnClickListener;
    private View.OnClickListener stopOnClickListener;


    void init() {
        Handler handler = new Handler();
        int duration = 5000;

        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                foo();
                handler.postDelayed(this, duration);
            }
        };

        runOnClickListener = view -> {
            runnable.run();
            btn.setOnClickListener(stopOnClickListener);
        };

        stopOnClickListener = view -> {
            handler.removeCallbacks(runnable);
            btn.setOnClickListener(runOnClickListener);
        };

       btn.setOnClickListener(runOnClickListener);
    }

    void foo() {
        Log.i("foo", "foo");
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        btn = findViewById(R.id.btn);

        init();
    }
}

Upvotes: 2

glzlaohuai
glzlaohuai

Reputation: 76

Yeah, give you a simple example.

First, create two constant values and one instance variable:

 //indicate whether or not the loop is running
    private boolean isRunning = false;

    //used for handler to send empty msg
    private final static int MSG_LOOP = 1;
    private final static long LOOP_INTERVAL = 5000;

Then create a Handler instance to handle the loop logic:

Handler handler = new Handler() {
        @Override
        public void handleMessage(@NonNull Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                case MSG_LOOP:
                    doStuff();
                    break;
            }
        }
    };


    private void doStuff() {
        //after what you want to do is done, send another MSG_LOOP msg with delay
        handler.sendEmptyMessageDelayed(MSG_LOOP, LOOP_INTERVAL);
    }

And finally:

button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (isRunning) {
                    //cancel if any in the message queue
                    handler.removeMessages(MSG_LOOP);
                } else {
                    //if you do not want to start the loop immediately, then use: "sendEmptyMessageDelayed"
                    handler.sendEmptyMessage(MSG_LOOP);
                }

            }
        });

Upvotes: 0

Related Questions