1

I don't know if using Threads is the practice for what I am trying to achieve so please feel free to amend the code where you wish.

I am trying to implement a feature in my app where a TextView switches to 1 value and thereafter reverts back to the initial value every 5 seconds. I have implemented the following using on a thread:

    layoutDate.setText(firstNumber);

    Thread numberSwitch = new Thread() {
    @Override
    public void run() {
        while(!isInterrupted()) {
            try {

                Thread.sleep(5000);

                runOnUiThread(new Runnable () {
                    @Override
                    public void run() {

                        layoutDate.setText(secondNumber);                   

                    }
                });
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }       
    }
};

numberSwitch.start();

I have tried adding layoutDate.setText(firstNumber) just after the runUiOnThread and also after the nested run but it still doesn't work as I want it to.

I want to achieve something like the following:

Example

Ricardo A.
  • 628
  • 2
  • 8
  • 33
Adam
  • 183
  • 11
  • 1
    Use Handler instead – MilaDroid May 28 '19 at 11:24
  • What is the code doing in the current state? – Ricardo A. May 28 '19 at 11:25
  • 1
    @RicardoA. so `onCreate` it sets `layoutDate.setText(firstNumber)` and thereafter after 5 seconds it sets `layoutDate.setText(secondNumber)`. The issue is it doesn't revert back to the first number regardless of where I add `layoutDate.setText(firstNumber)` within the Thread – Adam May 28 '19 at 11:28
  • Didn't get it. It creates it an sets the initial value, after 5 seconds sets the second value. When you want it to revert to the first? After 5 more seconds? – Ricardo A. May 28 '19 at 11:33
  • 1
    @RicardoA. Yup - that's exactly it. 1. onCreate set firstValue 2. Wait 5 seconds 3. Set secondValue 4. Wait 5 seconds 5. setFirstValue – Adam May 28 '19 at 11:38

2 Answers2

1

You can use Handler with a runnable.

private TextView textView;
private Handler handler;

in your onCreate()

textView = findViewById(R.id.tv_bt_msg);
textView.setText("secondNumber");

handler = new Handler();
//Change the textview after 5 seconds
handler.postDelayed(runnable, 5000);

Runnable to change text every 5 seconds

private Runnable runnable = new Runnable() {
        @Override
        public void run() {
            String currentString = textView.getText().toString();
            if(currentString.equals("secondNumber")){
                currentString = "firstNumber";
            }else{
                currentString = "secondNumber";
            }
            final String tempString = currentString;
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    textView.setText(tempString);
                }
            });
            //Change the textview again after 5 seconds
            handler.postDelayed(runnable, 5000);
        }
    };

Use this to removeCallbacks

handler.removeCallbacks(runnable);
Arun
  • 311
  • 2
  • 8
  • This worked brilliantly @Arun. I'm having one slight issue with the color of the `textView`. Upon setting `secondNumber` I have set the color to change. Is it possible to revert the color back to the original when it switches back to `firstNumber` using your implementation above? – Adam May 29 '19 at 08:43
  • @Adam Change the text color everytime you change the text. Along with `textView.setText()` add a `textView.setTextColor()` and set the color that you want for that text. [Here](https://stackoverflow.com/a/8472374/5523312) is an answer with various options to change the color of text at runtime. – Arun May 29 '19 at 08:53
  • Done. :D I just called `textView.setTextColor()` in the `if else`. Thanks :) – Adam May 29 '19 at 08:57
0

Verify the current number that is in the field and change to the other, you can do this through getting the value layoutDate.getText().toString() or using a new variable to store the value.

layoutDate.setText(firstNumber);

    Thread numberSwitch = new Thread() {
    @Override
    public void run() {
        while(!isInterrupted()) {
            try {

                Thread.sleep(5000);

                runOnUiThread(new Runnable () {
                    @Override
                    public void run() {

                        if(currentNumber == firstNumber){
                            currentNumber = secondNumber;
                        }else{
                            currentNumber = firstNumber;
                        }
                        layoutDate.setText(currentNumber);
                    }
                });
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }       
    }
};

numberSwitch.start();

Or

if(layoutDate.getText().toString().equals(firstNumber+"")){
    layoutDate.set(secondNumber);
}else{
    layoutDate.set(firstNumber);
}
Ricardo A.
  • 628
  • 2
  • 8
  • 33
  • 2
    A better way could be to post the runnable using lambdas to the layoutDate itself, instead of using a new Handler or a new Thread. That way, the runnable will be cleared off as soon as the view is invalidated. – Rahul Shukla May 28 '19 at 12:15