in my ProgressBar I want to display the progress percentage in the 0.0 format. I have this code but the result is always rounded up or down, without displaying the number after the decimal point.
double value = Double.valueOf(data);
value = numero_a / numero_b *100;
final float numero_float = (float) value;
new Thread(new Runnable() {
float progressStatus = 0;
Handler handler = new Handler();
public void run() {
while (progressStatus < numero_float) {
progressStatus += 1;
handler.post(new Runnable() {
public void run() {
tvPercentuale.setText(progressStatus+"%");
mProgress.setProgress((int)progressStatus);
Increase variables by a factor of 10, so:
while(progressStatus < numero_float * 10)
Then increment progressStatus by 10:
progressStatus += 10;
then set text as so:
tvPercentuale.setText("" + progressStatus / 10.0f + "%");
mProgress.setProgress((int)(progressStatus/10));
NumberFormat nf = NumberFormat.getPercentInstance();
//this will make sure the format is in XX.X%
nf.setMaximumFractionDigits(1);
nf.setMinimumFractionDigits(1);
.....
tvPercentuale.setText(nf.format(progressStatus))
EDIT:
int max = mProgress.getMax();
for(int i=0; i<max; i++){
int progress = i;
float progressValue = (float)i/(float)max;
tvPercentuale.setText(nf.format(progressValue))
mProgress.setProgress(progress);
}
Related
I want to make a random number from 0-9 with animation.
I try to use with ValueAnimator, but no luck.
Here is my code without ValueAnimator (works):
final int min = 0;
final int max = 9;
final int random = new Random().nextInt((max - min) + 1) + min;
randomSting = String.valueOf(random);
mNumberView.setText(randomSting);
Here is with ValueAnimator that doesn't work (not works):
animator = ValueAnimator.ofInt(0, 9);
final int min = 0;
final int max = 9;
final int random = new Random().nextInt((max - min) + 1) + min;
randomSting = String.valueOf(random);
cTimer = new CountDownTimer(3000, 1000) {
public void onTick(long millisUntilFinished) {
animator.setDuration(3000);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
public void onAnimationUpdate(ValueAnimator animation) {
mNumberView.setText(animation.getAnimatedValue().toString());
}
});
animator.start();
}
public void onFinish() {
animator.cancel();
mNumberView.setText(randomSting);
}
};
cTimer.start();
mNumberView cannot set text to randomString.
If possible to make number animator with random numbers, not using ValueAnimator
this code will generate random number between 9 and 0 every 1 second.
final int min = 0;
final int max = 9;
final int duration= 1000;
final Handler handler = new Handler();
final Runnable runnable = new Runnable() {
#Override
public void run() {
int random = new Random().nextInt(max - min + 1) + min;
handler.postDelayed(this,duration);
}
};
handler.post(runnable);
I want to generate n no of random no whose sum should be m and these no should always be between x and y.
For eg :- If i say I need 20 no, between 3 and 9 inclusive, whose sum should be 100.
I want to specify the sum and required amount of no as well as the limit between which random no should be generated and it should give me the random no of specified amount. Below is my code which do generates no which are greater than 2 but i am not able to put the max limit. Also, the sum which comes out and the sum of no. which it generates is not equal to specified sum. I am totally confused Please help me out.
TextView textView,randomTotaltxt;
int count0 = 0;
int count1 = 0;
int targetSum = 100;
int numberofDraws = 20;
textView = (TextView) findViewById(R.id.textview);
randomTotaltxt = (TextView) findViewById(R.id.randomTptalText);
Random r = new Random();
ArrayList<Integer> load = new ArrayList<>();
//random no
int sum = 0;
for (int i=0; i<numberofDraws;i++){
int next = r.nextInt(targetSum)+1;
Log.d("No",""+next);
load.add(next);
sum += next;
}
//scale it
double scale = 1d*targetSum/sum;
sum=0;
for (int i=0; i<numberofDraws;i++){
load.set(i, (int)(load.get(i)*scale));
sum += load.get(i);
}
while (load.contains(0)|| load.contains(1)){
for (int i=0; i<load.size();i++) {
if (load.get(i).equals(0)) {
load.set(i, load.get(i) + 2);
count0++;
sum = sum+1;
}
if (load.get(i).equals(1)) {
load.set(i, load.get(i) + 2);
sum += load.get(i);
count1++;
sum = sum+1;
}
}
}
// take rounding
while (sum++ <targetSum){
int i = r.nextInt(numberofDraws);
load.set(i, load.get(i) + 1);
}
textView.setText(""+load);
randomTotaltxt.setText(""+(sum-1));
This might not be the optimal solution but this will do your work as required.
int targetSum = 100;
int numberOfDraws = 20;
int uppr=0;
int countt =0;
ArrayList<Integer> load = new ArrayList<>();
Random random;
TextView textView1,randomTotaltxt1;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
textView1 = (TextView) findViewById(R.id.textview1);
randomTotaltxt1 = (TextView) findViewById(R.id.randomTptalText1);
random = new Random();
//random no
int sum = 0;
for (int i=0; i<numberOfDraws;i++){
int next = random.nextInt(targetSum)+1;
load.add(next);
sum += next;
}
//scale it
double scale = 1d*targetSum/sum;
sum=0;
for (int i=0; i<numberOfDraws;i++){
load.set(i, (int)(load.get(i)*scale));
sum += load.get(i);
}
// take rounding
while (sum++ <targetSum){
int i = random.nextInt(numberOfDraws);
load.set(i, load.get(i) + 1);
Log.d("TAG",""+load);
}
checkForUpperRange();
}
public void checkForUpperRange(){
for (int i=0; i<numberOfDraws;i++){
int n = load.get(i);
if (n > 9){
load.set(i, 9);
uppr = n - 9; // getting the required no.
adjustUpper();
break;
}
checkForLowerRange();
}
}
private void adjustUpper() {
for (int j=0; j<numberOfDraws;j++){
if (load.get(j) > 2){
load.set(j, load.get(j)+uppr); // uppr is added
checkForUpperRange();
break;
}
}
}
public void checkForLowerRange(){
for (int i=0; i<numberOfDraws;i++){
int n = load.get(i);
if (n == 0){
load.set(i, load.get(i)+3); // 3 is added in sum
adjust0();
break;
}
if (n == 1){
load.set(i, load.get(i)+2); // 2 is added in sum
adjust1();
break;
}
if (n == 2){
load.set(i, load.get(i)+1); // 1 is added in sum
adjust2();
break;
}
getCount();
}
}
public void getCount(){
countt = 0;
for (int k=0; k<numberOfDraws;k++){
countt = countt+ load.get(k);
showResult();
}
}
public void showResult(){
textView1.setText(""+load);
randomTotaltxt1.setText(""+countt);
}
public void adjust0(){
for (int j=0; j<numberOfDraws;j++){
if (load.get(j) > 3){
load.set(j, load.get(j)-3); // 3 is subtracted
checkForLowerRange();
break;
}
}
}
public void adjust1(){
for (int j=0; j<numberOfDraws;j++){
if (load.get(j) > 3){
load.set(j, load.get(j)-2); // 2 is subtracted
checkForLowerRange();
break;
}
}
}
public void adjust2(){
for (int j=0; j<numberOfDraws;j++){
if (load.get(j) > 3){
load.set(j, load.get(j)-1); // 1 is subtracted
checkForLowerRange();
break;
}
}
}
I am trying to simulate a buoyant force behavior on a 2D object of an Android application, there is no friction involved. Something is not working correctly: the height of the "bounce" changes in an irregular manner, I think the error should be in the update of the speed but I'm not sure.
Can anyone see the error in my code?
public class MainActivity extends Activity {
Semaphore moveSemaphore = new Semaphore(1);
static WindowManager.LayoutParams params;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
params = new WindowManager.LayoutParams( 80, 80,
WindowManager.LayoutParams.TYPE_APPLICATION,
WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS,
PixelFormat.TRANSPARENT);
final BallView ball = new BallView(this);
addContentView(ball, params);
ball.setX(100);
ball.setY(50);
final Thread move = new Thread(new Runnable(){
double speed = 0;
double G = 9;
double fullBuoyancy = -G * 10;
double prevtime = System.currentTimeMillis();
double elapsed;
double fluidstart = 300;
double objectHeight = 100;
double currPosy = 50;
double p;
#Override
public void run() {
while(true){
try {
moveSemaphore.acquire();
} catch (InterruptedException e) {
e.printStackTrace();
}
runOnUiThread(new Runnable() {
#Override
public void run() {
double currDepth = 0;
long currtime = System.currentTimeMillis();
elapsed = (currtime - prevtime) * 0.01;
prevtime = currtime;
currPosy = ball.getY();
// COMPUTE HOW MUCH OF THE BALL IS INSIDE OF THE FLUID
if (currPosy > (fluidstart + objectHeight/2)){
currDepth = objectHeight;
} else if (currPosy > (fluidstart - objectHeight/2)) {
currDepth = currPosy - fluidstart;
}
p = currDepth / objectHeight; // PERCENTAGE OF THE FULL BUOYANT FORCE TO BE APPLIED
speed = speed + (G + fullBuoyancy * p) * elapsed;
currPosy += speed * elapsed;
ball.setY((float)currPosy);
moveSemaphore.release();
}
});
}
}
});
move.start();
}
}
The problem was in the if-statement, this is the correct solution:
if (currPosy > (fluidstart + objectHeight/2)){//complete submersion
currDepth = objectHeight;
} else if (currPosy > (fluidstart - objectHeight/2)) {//partial submersion
currDepth = (currPosy + objectHeight/2) - fluidstart;
}
The if-statement logic is incorrect.
double emerge = fluidstart - (currPosy - (objectHeight / 2));
if (emerge <= 0) { // complete submersion
currDepth = objectHeight;
} else {
currDepth = objectHeight - emerge;
}
I'm developing a music streaming app which has to have a crossfade function e.g. when there are 5s left to the end of the first song it should start fading out and the next song should start fading in in the very same moment so that for a moment there will be two tracks playing at once.
I was trying to use two MediaPlayer objects but always only one plays. The fade out and fade in effects work perfectly fine if I play just one track.
I check when to start the crossfade in this runnable:
private Runnable mUpdateTimeTask = new Runnable() {
public void run() {
long totalDuration = 0;
long currentDuration = 0;
if(musicPlayer.isPlaying()) {
totalDuration = musicPlayer.getDuration();
currentDuration = musicPlayer.getCurrentPosition();
// Updating progress bar
int progress = (utils.getProgressPercentage(currentDuration, totalDuration));
trackPb.setProgress(progress);
if (!trackDownloaded && currentDuration > 100) {
Log.i(TagsContainer.MUSIC_PLAYER_TAG,"next track download started");
trackDownloaded = true;
new TrackLoader().execute();
}
long crossFadeValue = currentDuration + CROSSFADE_DURATION;
if (crossFadeValue > totalDuration && !fadeStarted && currentDuration > 100) {
fadeStarted = true;
crossFade();
}
// Running this thread after 100 milliseconds
}
mHandler.postDelayed(this, 100);
}
};
Crossfade's functions look like this:
private void crossFade() {
fadeOut(musicPlayer, CROSSFADE_DURATION);
fadeIn(musicPlayer2, CROSSFADE_DURATION);
}
public void fadeOut(final MediaPlayer _player, final int duration) {
final float deviceVolume = getDeviceVolume();
final Handler h = new Handler();
h.postDelayed(new Runnable() {
private float time = duration;
private float volume = 0.0f;
#Override
public void run() {
if (!_player.isPlaying())
_player.start();
// can call h again after work!
time -= 100;
volume = (deviceVolume * time) / duration;
_player.setVolume(volume, volume);
if (time > 0)
h.postDelayed(this, 100);
else {
_player.stop();
_player.release();
}
}
}, 100); // 1 second delay (takes millis)
}
public void fadeIn(final MediaPlayer _player, final int duration) {
final float deviceVolume = getDeviceVolume();
final Handler h = new Handler();
h.postDelayed(new Runnable() {
private float time = 0.0f;
private float volume = 0.0f;
#Override
public void run() {
if (!_player.isPlaying())
_player.start();
// can call h again after work!
time += 100;
volume = (deviceVolume * time) / duration;
_player.setVolume(volume, volume);
if (time < duration)
h.postDelayed(this, 100);
}
}, 100); // 1 second delay (takes millis)
}
I defined different lock positions:
private static final int[] gears = new int[] { 0, 33, 66, 100 };
In the onStopTrackingTouch i calculate which of my lock positions is the closest to the progress state of my SeekBar:
#Override
public void onStopTrackingTouch(final SeekBar seekBar) {
int progress = seekBar.getProgress();
int distance = Math.abs(gears[0] - progress);
int index = 0;
for(int i = 1; i < gears.length; i++) {
int tempDistance = Math.abs(gears[i] - progress);
if(tempDistance < distance) {
index = i;
distance = tempDistance;
}
}
int lock = gears[index];
}
I now need to somehow set the progress state of the SeekBar to my lock position using a smooth animation.
How can i impelement that animation?
EDIT
Thanks to the answer of #bwoogie here the complete working example using a VerticalSeekBar
#Override
public void onStopTrackingTouch(final SeekBar seekBar) {
int progress = seekBar.getProgress();
int distance = Math.abs(gears[0] - progress);
int index = 0;
for(int i = 1; i < gears.length; i++) {
int tempDistance = Math.abs(gears[i] - progress);
if(tempDistance < distance) {
index = i;
distance = tempDistance;
}
}
final int lock = gears[index];
final int tick = 50;
final VerticalSeekBar verticalSeekBar = (VerticalSeekBar)seekBar;
new Thread(new Runnable() {
long now = System.currentTimeMillis();
public void run() {
while(seekBar.getProgress() != lock) {
if(now + tick < System.currentTimeMillis()) {
if(seekBar.getProgress() > lock) {
getActivity().runOnUiThread(new Runnable() {
public void run() {
verticalSeekBar.setMax(100);
verticalSeekBar.setProgressAndThumb(seekBar.getProgress() - 1);
}
});
} else if(seekBar.getProgress() < lock) {
getActivity().runOnUiThread(new Runnable() {
public void run() {
verticalSeekBar.setMax(100);
verticalSeekBar.setProgressAndThumb(seekBar.getProgress() + 1);
}
});
} else {
break;
}
now = System.currentTimeMillis();
}
}
}
}).start();
}
What I would do is create a loop (in a new thread) that checks every few milliseconds if enough time has passed and if so then we can update the seekBar. Here is the basic idea, just throw it into a thread and implement the updateSeekBar() method since its in a thread you wont be able to access the UI thread directly.
int newPos; // the new position we are seeking to
int ticks = 50; //how many milliseconds
long now = System.getCurrentTimeMillis();
while(seekBar.getPosition() != newPos) {
if(now + ticks < System.getCurrentTimeMillis()) {
if(seekBar.getPosition() > newPos) {
updateSeekbar(seekBar.getPosition()--);}
elseif(seekBar.getPosition() < newPos{
updateSeekbar(seekBar.getPosition()++;}
else {
break; // we've reached out goal
}
now = System.getCurrentTimeMillis(); //Edit - forgot to update the time!!
}
}