public void run() {
runOnUiThread(new Runnable() {
public void run() {
tvTimer.setText("timer=" + String.valueOf(TimeCounter));
TimeCounter++;
A.setBackgroundColor(123455+TimeCounter*100000);
}
});
}
}, 0, 1000);
I have created a timer that his role to count the running time of the application, and i want to change the background color as long as the timer goes up. what is wrong with my script?
I think the problem comes from the value that you are passing to the setBackgroundColor method.
From the doc of the class Color we can see that:
The components are stored as follows (alpha << 24) | (red << 16) |
(green << 8) | blue.
In your code, the first value that you are passing (supposing the TimeCounter starts from 0) is 123455 which corresponds to 0x0001E23F in hexadecimal.
By decomposing it, we have:
alpha=0x00
red=0x01
green=0xE2
blue=0x3F
It gives you 0% for the alpha value which means that the color is transparent.
You are adding 100000 to this value every second. So it will take you about 166 seconds (almost 3 minutes) to have a color with an alpha value greater than 0 (but it will still be invisble as the percentage of alpha will be lower than 1%).
To fix it, you can use an offset to each color to set the alpha value to 100%. For that you just have to add 0xff000000 (4 278 190 080) to the color value.
Finally, just be sure that the color value is always lower than the maximum value 0xffffffff (4 294 967 295) and it should work.
Here is a sample code:
private int offsetColor = 0xFF000000; //offset to have 100% in alpha value
public void run() {
runOnUiThread(new Runnable() {
public void run() {
tvTimer.setText("timer=" + String.valueOf(TimeCounter));
TimeCounter++;
if (TimeCounter < 167) {
A.setBackgroundColor(offsetColor+TimeCounter*100000);
} else {
/* You just reach the limit: 0xFFFFFFFF which is White */
}
}
});
}
}, 0, 1000);
With this example you can do 166 iterations (166 seconds). You can change the value that you are adding each second to adjust the duration of your animation.
Problem is the color code set in the A.setBackgroundColor();
I have simple and logical solution of this:
1.make color array like this
int[] colors=new int[]{Color.BLACK,Color.BLUE,Color.GREEN,Color.RED,Color.YELLOW};
int i=0;
set color of array by its index as i increments in Runnable:
public void run() {
runOnUiThread(new Runnable() {
public void run() {
tvTimer.setText("timer=" + String.valueOf(TimeCounter));
TimeCounter++;
A.setBackgroundColor(colors[i]);
i++;
if(i==5){
i=0;
}
}
});
}
}, 0, 1000);
See I have create new application for your color change as you required.:
public class MainActivity extends Activity {
ImageView iv;
int red = 255, green = 0, blue = 0;
int i = 0;
int a = 30;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
iv = (ImageView) findViewById(R.id.imageView1);
// m.postScale(2f, 2f);
Timer t = new Timer();
t.scheduleAtFixedRate(new TimerTask() {
public void run() {
runOnUiThread(new Runnable() {
public void run() {
iv.setBackgroundColor(Color.argb(a, red, green, blue));
Log.d("main", "i: " + i + " a:+ " + a + " red: " + red
+ " green: " + green + " Blue: " + blue);
a = a + 30;
// set 30 to 60 for more difference
if (a > 250) {
a = 30;
i++;
if (i == 1) {
red = 0;
green = 255;
blue = 0;
} else if (i == 2) {
red = 0;
green = 0;
blue = 255;
} else if (i == 3) {
red = 255;
green = 0;
blue = 0;
}
if (i == 3) {
i = 1;
}
}
}
});
}
}, 0, 1000);
}
}
Now Enjoy Good Luck ..
Related
I want to play the audio two times before playing the next item.
This is my class where I want to display the items.
public void startSlides() {
timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
runOnUiThread(new Runnable() {
public void run() {
Intent intent = getIntent();
int setId = intent.getIntExtra("SelectedSetId",0);
databaseAccess.open();
setId = setId + 1;
List<byte[]> audio = databaseAccess.getAudioA(setId);
if (i > audio.size()){
i = 0;
}else{
playAudio(audio.get(i));
playAudio(audio.get(i));
i++;}
List<String> vocab = databaseAccess.getVocabNameA(setId);
textView2.setText(vocab.get(k));
k++;
textView.setText(+j + "/" + vocab.size());
j++;
databaseAccess.close();
if (j == vocab.size() + 1) {
timer.cancel();
}
}
});
}
}, 0, DURATION);
}
I think I have to add something at the playAudio(audio.get(i)), but I have no idea how should I do. If I do this, it plays the audio at the same time. Thanks.
if (i > audio.size()){
i = 0;
}else{
playAudio(audio.get(i));
playAudio(audio.get(i));
i++; }
How is it possible to make an app that changes between color automatically after specific time. My code doesn't work for some reason
Random r = new Random();
Timer t = new Timer();
LinearLayout ll = (LinearLayout) findViewById(R.id.ll);
long m = System.nanoTime();
int seconds = (int) (m/1000);
if(seconds <= 5){
ll.setBackgroundColor(Color.BLACK);
}else{
ll.setBackgroundColor(Color.WHITE);
}
For ex. the screen is black and after specific time white. And that the time decreases itslef, the changing goes faster.
Please try the following code for the color change.
Use the countdown timer for changing the color with condition.
new CountDownTimer(5000,1000)
{
onFinish()
{
if(flag==1)
{
//color set black
flag=0;
//start the countdown timer again.
}
else
{
//color set white
flag=1;
//start the countdown timer again.
}
}
}
Try following the code
Calendar c = Calendar.getInstance();
int seconds = c.get(Calendar.SECOND);
//Adding Log Statement to check
Log.i(Tag, String.valueOf(seconds);
if(seconds % 10 < 5){
ll.setBackgroundColor(Color.BLACK);
}else{
ll.setBackgroundColor(Color.WHITE);
}
You are trying to convert nanoseconds to seconds, but actually you are doing is not the same!!
try
int seconds = (int) (m/1000000000);
to convert to nan0-seconds to seconds
EDIT:
if you just want to keep changing color use this code:
public static int color = 1;
android.os.Handler customHandler = new android.os.Handler();
customHandler.postDelayed(updateTimerThread, 0);
and its definition:
private Runnable updateTimerThread = new Runnable()
{
public void run()
{
//write here whaterver you want to repeat
if(color == 1){
ll.setBackgroundColor(Color.BLACK);
color = 2;
}else{
ll.setBackgroundColor(Color.WHITE);
color = 1;
}
customHandler.postDelayed(this, 5000);// will repeat after 5 seconds
}
};
You can use tread to manage this, try this . thread will be the best way to achieve this, since you want to continuously change the color at regular interval.
Handler handler ;
LinearLayout ll ;
int i = 0;
int colors[] = {Color.BLACK, Color.WHITE, Color.BLUE, Color.GREEN, Color.GRAY};
Runnable runnable = new Runnable() {
#Override
public void run() {
ll.setBackgroundColor(colors[i]);
i++;
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
......
.......
handler = new Handler();
ll = (LinearLayout) findViewById(R.id.ll);
Thread myTread = new Thread(){
public void run() {
try {
while(true){
sleep(3000);
handler.post(runnable);
}
}
catch (InterruptedException e) {}
}
};
myTread.start();
}
the code will change the background color every 3secssleep(3000) as written in the code. also each time it changes it select from a set of pre-define color array.
you can also use random generation of colors. either you randomly generate the rgb values or you can store the colors in an array as i have done and randomly iterate over it
After 3 hours of try i decided to ask here and see if someone can provide me a solution for this error: java.lang.IndexOutOfBoundsException: Invalid index 4, size is 4
Here is my code.
private ProgressBar progressBar;
private int progressStatus = 0;
private Handler handler = new Handler();
--------------------
status.setText(getString(R.string.init));
progressBar.setVisibility(View.VISIBLE);
final Map<String,?> keys = prefs.getAll(); //4 prefs atm inside.
final ArrayList<String> props = new ArrayList<String>();
final ArrayList<String> values = new ArrayList<String>();
if (keys != null) {
for(final Map.Entry<String,?> entry : keys.entrySet()) {
props.add(entry.getKey());
values.add(entry.getValue().toString());
}
final int total = props.size();
progressBar.setMax(total);
new Thread(new Runnable() {
public void run() {
while (progressStatus < total) {
progressStatus += 1;
handler.post(new Runnable() {
public void run() {
progressBar.setProgress(progressStatus);
if (props.get(progressStatus) != null) {
writeProps(props.get(progressStatus), values.get(progressStatus));
status.setText(getString(R.string.writing) + ": " + props.get(progressStatus));
}
}
});
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
} while (progressStatus == total) {
handler.post(new Runnable() {
public void run() {
progressBar.setVisibility(View.GONE);
progressStatus = total + 1;
myVoidOnFinish();
}
});
}
}
}).start();
}
I get the stuck here:
writeProps(props.get(progressStatus), values.get(progressStatus));
status.setText(getString(R.string.writing) + ": " + props.get(progressStatus));
The main problem is here
while (progressStatus < total) {
progressStatus += 1;
}
check value of your progress status it should be not greater than 3 while in you code it is 4 in last while index is only from 0 to 3. please set value of your progress status accordingly.
try this
while (progressStatus < total-1) {
progressStatus += 1;
}
The problem is you are setting the progressstatus value like following
final int total = props.size();
progressBar.setMax(total);
and you in the following line you are trying to get values of props ase
writeProps(props.get(progressStatus), values.get(progressStatus));
see that for the total size of 4 your progressStatus will be 4. But the maximum index of props and values will be 3. So here is the problem
you can set the value to 1 less than the size like
final int total = props.size() - 1;
You are using one extra index as you can use maximum up to 3. So please start it form zero and use less then check instead of less then equal to.
I want the output to be green if the counter is 20 or above and red if it is below 20. this is the code I have so far and it isnt working.
add1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
counter = counter += 1;
if (counter >= 20) {
display.setText(Color.GREEN);
//display.setText("" + counter);
}
else if (counter < 20) {
display.setTextColor(Color.RED);
//display.setText("" + counter);
}
display.setText("" + counter);
}
});
sub1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
counter = counter -= 1;
if (counter >= 20) {
display.setText(Color.GREEN);
//display.setText("" + counter);
}
else if (counter < 20){
display.setTextColor(Color.RED);
//display.setText("" + counter);
}
display.setText("" + counter);
}
});
Couple of issues with your code:
use counter += 1 instead of counter = counter += 1. Same for subtraction.
avoid duplicating code
use setTextColor() instead of setText().
add1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
counter += 1;
updateDisplay();
}
});
sub1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
counter -= 1;
updateDisplay();
}
});
And have this method somewhere:
void updateDisplay () {
display.setTextColor(counter < 20 ? Color.RED : Color.GREEN);
display.setText("" + counter);
}
If you're trying to change the color of the textview called display you need to switch:
display.setText(Color.GREEN);
to
display.setTextColor(Color.GREEN);
Also you can probably make your else if just an else.
Well,
As mentioned in the comments, you are trying to set the text to Color.GREEN which is a constant integer representing the green color, while you should be doing like you did in the RED case
display.setTextColor(Color.GREEN);
On a different matter, You shouldn't be using else if in that statement.
Since your first if asks, is my counter 20 or more, change color to green, and if it's under, change to red.
You only have 2 cases which overlaps the entire "spectrum" of your variable if you will.
You should use if and else in that case
counter = counter += 1;
if (counter >= 20) {
display.setTextColor(Color.GREEN);
//display.setText("" + counter);
}
else { // not 20 or above, meaning < 20
display.setTextColor(Color.RED);
//display.setText("" + counter);
}
display.setText("" + counter);
else if would be useful if you had more cases, for example
counter = counter += 1;
if (counter >= 20) {
display.setText(Color.GREEN);
//display.setText("" + counter);
}
else if (counter < 20 && counter >= 10) { // counter is between 10 and 20, not including 20
display.setTextColor(Color.RED);
//display.setText("" + counter);
}
else { // under 10, not including 10
display.setTextColor(Color.WHITE);
//display.setText("" + counter);
display.setText("" + counter);
It might be good practice to try and always have an else statement to check for an illegal value (especially if it's an input from the user). even only for a sanity check, or error handling and printing.
Below I am posting my code for the thread I am running to animate text in a RelativeLayout on top of the Page Curl activity by harism.
public void startProgress(final int index)
{
runnable = new Runnable()
{
#Override
public void run()
{
mArrWords.removeAll(mArrWords);
mStart.removeAll(mStart);
mEnd.removeAll(mEnd);
words = sentence.split(" ");
for(int i = 0; i < words.length; i++)
{
mArrWords.add(words[i]);
if(i == 0)
{
mStart.add(0);
mEnd.add(words[0].length());
}
else
{
mStart.add(mEnd.get(i-1)+1);
mEnd.add(mStart.get(i)+words[i].length());
}
/*Log.e("words", "" + "" + words[i]);
Log.e("mArrWords", "" + mArrWords);
Log.e("mStart", "" + mStart);
Log.e("mEnd", "" + mEnd);*/
}
for (int i = 0; i < mArrWords.size(); i++)
{
final int value = i;
try
{
Thread.sleep(500);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
mHandler.post(new Runnable()
{
#Override
public void run()
{
currIndex = index;
try
{
if(CurlView.ANIMATE)
tv1.setVisibility(View.VISIBLE);
else
tv1.setVisibility(View.GONE);
final Pattern p = Pattern.compile(mArrWords.get(value));
final Matcher matcher = p.matcher(sentence);
SpannableString spannableTxt = new SpannableString(sentence);
ForegroundColorSpan span = new ForegroundColorSpan(Color.RED);
while(matcher.find())
spannableTxt.setSpan(span, mStart.get(value), mEnd.get(value), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
tv1.setText(spannableTxt);
mHandler.sendEmptyMessage(0);
}
catch (Exception e)
{
e.printStackTrace();
mHandler.sendEmptyMessage(0);
}
}
});
}
}
};
final ScheduledExecutorService worker = Executors.newSingleThreadScheduledExecutor();
worker.schedule(runnable, CurlView.ANIMTIME+50, TimeUnit.MILLISECONDS);
}
Here, I am animating the text over images. I need to change the text for each page I am changing. I am able to change the text, however, when I turn the page, the index values I store in ArrayLists are not getting cleared. I am storing a sentence in an ArrayList named mArrWords and the indexes to refer to each word of sentence are stored in mStart and mEnd.
The problem I am facing is when the text changes, the animation starts with the previous indexes stored in mStart and mEnd ArrayLists I use to store index of a particular word. What I need to know is how do I stop my thread when the page is turned or the index of the page changes. I am calling this function inside the updatePage(final CurlPage page, final int width, final int height, final int index) method of Curl activity. I hope I was able to explain my problem. Thanks!
EDIT: I would like to specify my question more clearly. How do I check if the thread is already running before starting another thread and stop the execution of the previous thread?
removeCallbacks(..) only stops pending messages (Runnables).If runnable is started then u can not stop it in this way. See the following :
removecallbacks-not-stopping-runnable