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.
  • 685
  • 2
  • 8
  • 35
Adam
  • 203
  • 1
  • 14
  • 1
    Use Handler instead – Milad Yarmohammadi 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

3 Answers3

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
  • 321
  • 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.
  • 685
  • 2
  • 8
  • 35
  • 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
0

There is code for XML files

    <com.google.android.material.textview.MaterialTextView
    android:id="@+id/tx_demo"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Hello World!"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent" />

There is code for Java files

  private var txDemo: MaterialTextView? = null
  int count = 0;
private void initView() {
    String[] stringArray = {"Text:-1", "Text:-2", "Text:-3", "Text:-4", "Text:-5"};
    txDemo = findViewById(R.id.tx_demo);
    new Handler().postDelayed(() -> {
        txDemo.setText(stringArray[0]);
        count++;
        if (count == stringArray.length)
            count = 0;

    }, 5000);
}

or kotlin Code

  var count = 0
private fun initView() {
    val stringArray = arrayOf("Text:-1", "Text:-2", "Text:-3", "Text:-4", "Text:-5")
    txDemo = findViewById(R.id.tx_demo)
    Handler().postDelayed({
        txDemo!!.text = stringArray[0]
        count++
        if (count == stringArray.size) count = 0
    }, 5000)
}