I am new at android programming and I have a problem to run animation after animation in android studio. The thing is that I don't have specified number of animations I need, it depends on counter.
package com.example.smartpc.memorygame;
import android.graphics.drawable.TransitionDrawable;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationSet;
import android.view.animation.RotateAnimation;
import android.widget.Button;
import android.widget.ImageView;
import java.util.ArrayList;
import java.util.Random;
public class MemoryGame extends AppCompatActivity {
ImageView imgRed;
ImageView imgGreen;
ImageView imgBlue;
Button btnStart;
ArrayList<Integer>array=new ArrayList<>();
int counter=3;
int i=0;
Boolean flag=false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_memory_game);
imgRed=(ImageView)findViewById(R.id.imgRed);
imgGreen=(ImageView)findViewById(R.id.imgGreen);
imgBlue=(ImageView)findViewById(R.id.imgBlue);
btnStart=(Button)findViewById(R.id.btnStart);
final RotateAnimation animation=new RotateAnimation(0f,360f, RotateAnimation.RELATIVE_TO_SELF,0.5f,
RotateAnimation.RELATIVE_TO_SELF,0.5f);
animation.setDuration(1000);
// animation.setRepeatCount(1);
animation.setAnimationListener(new Animation.AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
;
}
#Override
public void onAnimationEnd(Animation animation) {
if (flag==true) {
i++;
Random rand = new Random();
int number = Math.abs(rand.nextInt() % 3);
btnStart.setText(Integer.toString(i) + " " + Integer.toString(number));
if (number == 0) {
imgRed.startAnimation(animation);
} else if (number == 1) {
imgGreen.startAnimation(animation);
} else if (number==2){
imgBlue.startAnimation(animation);
}
if (i == counter - 1) {
i = 0;
flag=false;
return;
}
}
}
#Override
public void onAnimationRepeat(Animation animation) {
;
}
});
imgRed.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
imgRed.startAnimation(animation);
flag=false;
}
});
imgGreen.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
imgGreen.startAnimation(animation);
flag=false;
}
});
imgBlue.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
imgBlue.startAnimation(animation);
flag=false;
}
});
btnStart.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// imgGreen.setImageResource(R.drawable.transition);
// ((TransitionDrawable) imgGreen.getDrawable()).startTransition(3000);
flag=true;
Random rand = new Random();
int number = Math.abs(rand.nextInt() % 3);
if (number == 0) {
imgRed.startAnimation(animation);
}
else if (number == 1) {
imgGreen.startAnimation(animation);
}
else if (number==2) {
imgBlue.startAnimation(animation);
}
// btnStart.setText(Integer.toString(i) + " " + Integer.toString(number));
}
});
}
}
In method onAnimationEnd() is problem. It generates number and starts good animaton, but it also starts another one (random, there's no rule which one). Does anyone have idea how to solve this? Also, counter is not fixed, I want to change it in code later.
I will try my best to explain it.
When the process run into onAnimationEnd(), it does mean the animation is finished. It just like to wait for the onAnimationEnd(). And then you call startAnimation(sameAnimation), we can see the method source code.
/**
* Start the specified animation now.
*
* #param animation the animation to start now
*/
public void startAnimation(Animation animation) {
animation.setStartTime(Animation.START_ON_FIRST_FRAME);
setAnimation(animation);
invalidateParentCaches();
invalidate(true);
}
Notice this code : animation.setStartTime(Animation.START_ON_FIRST_FRAME);
If you set the start time with -1, the animation we have run previously will be reset. Oops, because we said the animation is not really finished, it will rerun as the last time.
Run your progress, if you see there are two images rotating at the same time, one of them must be the last one which has rotated.
If you want to run animation after animation, you may not use the same animation in onAnimationEnd(). Or you can use View.clearAnimation() to clear all animation which attach to the view.
I'm glad if it could help you. And if there is anything wrong, please add a comment.
Related
I got a little problem. I think the solution is very simple but unfortunately I can't find it. I hope someone can help me
I got a while-loop who has to count up to ten and write the number into a TextView.
It still doesn't work ...
Thanks for your help!
Here is the code:
package de.androidnewcomer.animation;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;
import static android.R.attr.button;
import static de.androidnewcomer.animation.R.id.textView;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ImageView ball=(ImageView)findViewById(R.id.ball);
Button button=(Button)findViewById(R.id.button);
button.setOnClickListener(this);
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.button:
count();
break;
}
}
private void count() {
TextView textView=(TextView)findViewById(R.id.textView);
int i;
i=1;
while(i<10) {
i++;
textView.setText(i);
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
Using setText() with an integer value is for setting a string resource reference. To set the text itself, you have to provide a string: Use setText("" + i); and it should work.
The textView.setText(..) needs a string object, but you use a int. You have to convert your int into a string with the following possible options:
You can use String.valueOf(i): textView.setText(String.valueOf(i));
You can use Integer.toString(i): textView.setText(Integer.toString(i));
You can use the empty string literal: textView.setText("" + i);
I prefer the last option. With your code, it should looks like the following code:
private void count() {
TextView textView=(TextView)findViewById(R.id.textView);
int i;
i=1;
while(i<10) {
i++;
textView.setText("" + i);
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
You can use a for loop instead of a while loop, like the following code:
private void count() {
TextView textView=(TextView)findViewById(R.id.textView);
for(int i = 1; i < 11; i++){ // From 1 to 10
textView.setText("" + i);
Thread.sleep(200);
}
}
Use a CountDown because you are blocking the main thread
CountDownTimer countDownTimer = new CountDownTimer(2000 /*amount*/, 200/*step*/) {
public void onTick(long millisUntilFinished) {
textView.setText("what ever you want");
}
public void onFinish() {
textView.setText("Done");
}
};
countDownTimer.start();
Please see attached image and code snippet to aid in explanation.
From the attached image I would like the user to enter a cost, quantity and select either Include Tax or Exclude tax and a new cost is automatically generated where indicated without pressing a Button, but to no avail I am unable to do this. Someone please help. Thanks
See Image Here
After implementing the Changes that were suggested and trying to enter an input in the cost field I was met with the error seen below. Please provide additional feedback. Thanks
Error image
import android.content.Context;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageButton;
import android.widget.EditText;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.util.Locale;
public class Calculator extends Fragment {
private static EditText itemText, editCost, editQuantity, calCost, rTax;
private static RadioGroup rGroup;
private static RadioButton rb;
View gView;
private double bTotal = 0, aTotal = 0, trueCost = 0, taxValue = 16.5, cost = 0, newCost = 0;
private int quantity = 1;
DecimalFormatSymbols symbols = DecimalFormatSymbols.getInstance(Locale.US);
DecimalFormat decimalFormat = new DecimalFormat("###,###.##", symbols);
CalculatorListener activityCommander;
public interface CalculatorListener {
void addtoCart(String itemName, int qty, double beforeTax, double afterTax, double bTotal, double aTotal);
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
try {
activityCommander = (CalculatorListener) context;
} catch (ClassCastException e) {
throw new ClassCastException(context.toString());
}
}
public Calculator() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment
gView = inflater.inflate(R.layout.fragment_calculator, container, false);
editCost = (EditText) gView.findViewById(R.id.editcost);
itemText = (EditText) gView.findViewById(R.id.itemText);
editQuantity = (EditText) gView.findViewById(R.id.editquantity);
calCost = (EditText) gView.findViewById(R.id.calcost);
rTax = (EditText) gView.findViewById(R.id.rtax);
rGroup = (RadioGroup) gView.findViewById(R.id.rgroup);
final ImageButton FieldButton = (ImageButton) gView.findViewById(R.id.FieldButton);
final ImageButton TaxButton = (ImageButton) gView.findViewById(R.id.TaxButton);
final ImageButton CalButton = (ImageButton) gView.findViewById(R.id.CalButton);
rTax.setEnabled(false);
calCost.setEnabled(false);
rGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
rb = (RadioButton)gView.findViewById(checkedId);
}
});
editCost.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
#Override
public void afterTextChanged(Editable s) {
try{
update();
}catch (NumberFormatException e)
{
e.printStackTrace();
}
}
});
editQuantity.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
#Override
public void afterTextChanged(Editable s) {
try{
update();
}catch (NumberFormatException e)
{
e.printStackTrace();
}
}
});
FieldButton.setOnClickListener(
new View.OnClickListener() {
public void onClick(View v) {
clearfield();
}
}
);
TaxButton.setOnClickListener(
new View.OnClickListener() {
public void onClick(View v) {
adjtax();
}
}
);
CalButton.setOnClickListener(
new View.OnClickListener() {
public void onClick(View v) {
//toCart();
}
}
);
return gView;
}
public void clearfield() {
editCost.setText("");
editCost.setBackgroundResource(R.drawable.edittxt);
editQuantity.setText("");
editQuantity.setBackgroundResource(R.drawable.edittxt);
calCost.setText("");
calCost.setBackgroundResource(R.drawable.edittxt);
itemText.setText("");
itemText.setBackgroundResource(R.drawable.edittxt);
rGroup.clearCheck();
}
public void adjtax() {
editCost.setBackgroundResource(R.drawable.edittxt);
editQuantity.setBackgroundResource(R.drawable.edittxt);
calCost.setBackgroundResource(R.drawable.edittxt);
itemText.setBackgroundResource(R.drawable.edittxt);
rTax.setEnabled(true);
rTax.setText("");
rTax.setBackgroundResource(R.drawable.edittxtfocus);
rTax.setOnFocusChangeListener(new View.OnFocusChangeListener() {
#Override
public void onFocusChange(View v, boolean hasFocus) {
if (hasFocus) {
rTax.setEnabled(true);
} else {
rTax.setEnabled(false);
v.setBackgroundResource(R.drawable.edittxt);
}
}
});
}
public void update(){
if (rTax.getText().toString().isEmpty()) {
taxValue = 16.5;
} else if (!rTax.getText().toString().isEmpty()) {
taxValue = Double.parseDouble(rTax.getText().toString());
}
//CHECKS THE TAX VALUE IF IT NEEDS TO BE CONVERTED
if (taxValue > 1) {
taxValue = taxValue / 100;
} else {
taxValue = taxValue * 1;
}
//CUSTOM VALIDATOR FOR QUANTITY FIELD
if (editQuantity.getText().toString().isEmpty()) {
quantity = 1;
} else if (!editQuantity.getText().toString().isEmpty()) {
quantity = Integer.parseInt(editQuantity.getText().toString());
}
if(rb.getText() == "Include Tax"){
newCost = (((cost = Double.parseDouble(editCost.getText().toString())) * taxValue) + cost) * quantity;
calCost.setText(decimalFormat.format(newCost).toString());
}
else if(rb.getText() == "Exclude Tax"){
newCost = ((cost = Double.parseDouble(editCost.getText().toString())) * quantity);
calCost.setText(decimalFormat.format(newCost).toString());
}
trueCost = cost * quantity;
bTotal = trueCost;
aTotal = newCost;
}
}
Move the rgroup.setOnCheckedChangeListener out of the update() method and into the onCreateView(). You should not have to set the listener every time the text has been updated.
The update method called after text entry can probably just update the tax value if a valid value has been entered and either the check boxes have been selected.
Update with another suggestion
I would lookup the radio button by comparing text as you are doing, some time in the future you may want to change the text in the resource file or apply another locale and this code will stop working.
if(rb.getText() == "Include Tax")
I would suggest comparing against the id itself:
if (checkedId == R.id.radio1 )
Another Suggestion:
Consider changing your variable names to lead with a lower case character. Leading with an upper case letter makes it look like either class name or a constant and make the code a bit more difficult to read.
private EditText itemText;
private EditText editCost;
private EditText editQuantity;
private EditText calcost;
private EdtiText rTax;
You can also remove all(some) the focus change listeners you have and set those attributes in the android drawable resources. Take a look here.
Update 9/9/2016 22:22
A bit better, but as you've found out calls to update can throw a null pointer if rb had never been initialized. You should check for a null rb in the update method and give the user a notice to select an option. You could also assign rb to either of the two values from the start in the onCreateView, so it is never null.
You should probably also add a call to update() after setting rb in the radio group callback. This will allow the screen to update as soon as they choose an option.
I've been having this issue for about a month now and I made a different question about it here: https://stackoverflow.com/questions/38005624/activity-stops-after-certain-time?noredirect=1#comment63454873_38005624
The issue appears to be a problem with the UI thread. After a seemingly random time of running, the UI thread appears to stop doing work. Any 'Runnable' objects passed to it with '.post()' or 'runOnUIThead()' do not get run. Even a simple log message. onClickListener objects also do not fire when the issue occurs. I've had runs where it starts happening within 2 seconds of starting, I've had runs where I make it through the entire game with no issue; all on the same code.
Here is my code if you need it:
The Activity:
package edu.rit.jacob.timeturner;
import android.app.ActivityManager;
import android.app.Application;
import android.app.Dialog;
import android.content.Intent;
import android.os.Looper;
import android.provider.ContactsContract;
import android.provider.Settings;
import android.support.annotation.StringRes;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.text.Layout;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.PopupWindow;
import android.widget.ProgressBar;
import android.widget.SeekBar;
import android.widget.TextView;
public class UniverseActivity extends AppCompatActivity {
public static final String TAG = UniverseActivity.class.getSimpleName();
private UniverseThread thread;
public UniverseThread getThread(){ return thread; }
public static int SECTORS_HEIGHT = 3;
public static int SECTORS_WIDTH = 3;
private Galaxy player;
public Galaxy getPlayer() {
return player;
}
//components:
private UniverseView surfaceView;
private ImageView playerSprite;
private ImageView otherSprite;
private TextView testText;
private SeekBar speedBar;
private ProgressBar timebar;
//Pop ups
private Dialog infoPopUp;
private Dialog startScreen;
//other Galaxies
Galaxy[] galaxies = new Galaxy[SECTORS_HEIGHT * SECTORS_WIDTH];
#Override
protected void onCreate(Bundle savedInstanceState) {
//Setup Activity
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
setContentView(R.layout.activity_universe);
Runnable init = new Runnable() {
#Override
public void run() {
initInfoPopUp();
initActivityComponents();
initPlayerAndSprites();
initOtherGalaxies();
initStartScreen();
}
};
runOnUiThread(init);
thread = new UniverseThread(surfaceView.getHolder(), surfaceView);
thread.setRunning(true);
thread.start();
startScreen.setTitle("The Beginning...");
startScreen.show();
Log.d(TAG, "App launched with " + ((ActivityManager)getSystemService(ACTIVITY_SERVICE)).getLargeMemoryClass() + "MB max");
}
#Override
protected void onDestroy() {
super.onDestroy();
boolean retry = true;
while(retry){
try{
thread.join();
retry = false;
}
catch (InterruptedException e){
//try again
}
}
}
private void initStartScreen(){
startScreen = new Dialog(this);
startScreen.setContentView(R.layout.new_game_start);
((TextView)startScreen.findViewById(R.id.textView4)).setText(getString(R.string.start_game_info));
startScreen.findViewById(R.id.buttonStart).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
player.setName("" + ((EditText)startScreen.findViewById(R.id.editText)).getText());
startScreen.dismiss();
}
});
}
private void initInfoPopUp(){
infoPopUp = new Dialog(this);
infoPopUp.setContentView(R.layout.info_popup);
Button infoOption1 = (Button) infoPopUp.findViewById(R.id.option1);
Button infoOption2 = (Button) infoPopUp.findViewById(R.id.option2);
infoOption1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.d(TAG, "Option 1 clicked");
//player.incrementGas(galaxies[player.getSector() - 1].getGas());
player.merge(galaxies[player.getSector() - 1], true);
galaxies[player.getSector() - 1] = null;
infoPopUp.dismiss();
}
});
infoOption2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.d(TAG, "Option 2 clicked");
//player.incrementGas(galaxies[player.getSector() - 1].getGas() / 2);
//galaxies[player.getSector() - 1].incrementGas(-galaxies[player.getSector() - 1].getGas() / 2);
player.merge(galaxies[player.getSector() - 1], false);
infoPopUp.dismiss();
}
});
}
private void initActivityComponents(){
surfaceView = (UniverseView) findViewById(R.id.surfaceView);
testText = (TextView) findViewById(R.id.testText);
speedBar = ((SeekBar)findViewById(R.id.seekBar));
timebar = ((ProgressBar)findViewById(R.id.progressBar));
}
private void initPlayerAndSprites(){
playerSprite = (ImageView) findViewById(R.id.playerGalaxy);
player = new Galaxy("Milky Way", true, new Velocity(), playerSprite, 25.0f, 1, this);
otherSprite = (ImageView) findViewById(R.id.otherGalaxy);
//Tapping on player galaxy
playerSprite.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.d(TAG, "Player sprite clicked, stopping time and bringing up window...");
speedBar.setProgress(0);
infoPopUp.setTitle(player.getName());
infoPopUp.findViewById(R.id.infoPicture).setBackgroundResource(R.drawable.random_temp_galaxy_01);
infoPopUp.findViewById(R.id.option1).setVisibility(View.INVISIBLE);
infoPopUp.findViewById(R.id.option2).setVisibility(View.INVISIBLE);
((TextView)infoPopUp.findViewById(R.id.infoText)).setText(player.toString());
infoPopUp.show();
}
});
//Tapping on other galaxy
otherSprite.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(otherSprite.getVisibility() == View.VISIBLE){
Log.d(TAG, "Other sprite clicked, stopping time and bringing up window...");
speedBar.setProgress(0);
infoPopUp.setTitle(galaxies[player.getSector() - 1].getName());
infoPopUp.findViewById(R.id.infoPicture).setBackgroundResource(R.drawable.random_temp_galaxy_01);
infoPopUp.findViewById(R.id.option1).setVisibility(View.INVISIBLE);
infoPopUp.findViewById(R.id.option2).setVisibility(View.INVISIBLE);
((TextView)infoPopUp.findViewById(R.id.infoText)).setText(galaxies[player.getSector() - 1].toString());
infoPopUp.show();
}
}
});
}
private void initOtherGalaxies(){
for(Galaxy g: galaxies) g = null;
int i = 0, galaxiesNum = 0;
Log.d(TAG, "Populating the universe...");
while(i < galaxies.length){
double rand = Math.random();
if(rand <= 0.25){
galaxies[i] = new Galaxy("Random galaxy", new Velocity(0,0), otherSprite, 25.0f, i + 1, (Math.random()), this);
galaxiesNum += 1;
}
i += 1;
}
Log.d(TAG, "Universe populated with " + galaxiesNum + " galaxies.");
}
public int getSpeed(){
return speedBar.getProgress();
}
public void setTimeProgress(int progress){
try {
if (timebar.getProgress() != progress) {
switch (progress) {
case 10:
//((ProgressBar) findViewById(R.id.progressBar)).getProgress()
progress += 1;
//bring up new popup
break;
case 50:
//do stuff
break;
case 100:
//do end game stuff
boolean retry = true;
while (retry) {
try {
thread.join();
retry = false;
} catch (InterruptedException e) {
//try again
}
}
}
timebar.setProgress(progress);
}
}
catch (NullPointerException e){
Log.d(TAG, "Failed to grab progressBar");
e.printStackTrace();
}
}
public void changeBackground(){
Runnable changeBackground = new Runnable() {
#Override
public void run() {
//Set new background
Log.d(TAG, "Changing to background " + player.getSector());
//surfaceView.setBackgroundResource(R.drawable.background01 + (player.getSector() - 1));
testText.setText("Sector: " + player.getSector());
//Check for other galaxy
if(galaxies[player.getSector() - 1] != null){
otherSprite.setVisibility(View.VISIBLE);
}
else{
otherSprite.setVisibility(View.INVISIBLE);
}
synchronized (this) {
this.notify();
}
}
};
Log.d(TAG, "Passing background runnable to the UI thread");
synchronized (changeBackground){
runOnUiThread(changeBackground);
try {
changeBackground.wait();
}
catch (InterruptedException e){
e.printStackTrace();
}
}
}
public void checkForCollision(){
if(playerSprite.getX() + (playerSprite.getWidth() / 2) >= otherSprite.getX() &&
playerSprite.getX() + (playerSprite.getWidth() / 2) <= otherSprite.getX() + otherSprite.getWidth() &&
playerSprite.getY() + (playerSprite.getHeight() / 2) >= otherSprite.getY() &&
playerSprite.getY() + (playerSprite.getHeight() / 2) <= otherSprite.getY() + otherSprite.getHeight()){
if(otherSprite.getVisibility() == View.VISIBLE){
//switch (player.)
Runnable collide = new Runnable() {
#Override
public void run() {
speedBar.setProgress(0);
otherSprite.setVisibility(View.INVISIBLE);
((TextView)infoPopUp.findViewById(R.id.infoText)).setText("");
//infoPopUp.findViewById(R.id.infoPicture).setBackgroundResource(R.drawable.hubble_merger_01);
infoPopUp.findViewById(R.id.option1).setVisibility(View.VISIBLE);
infoPopUp.findViewById(R.id.option2).setVisibility(View.VISIBLE);
infoPopUp.setTitle("Incoming!");
infoPopUp.show();
}
};
runOnUiThread(collide);
}
}
//Set gauge
Runnable setGauge = new Runnable() {
#Override
public void run() {
((GaugeView)findViewById(R.id.gaugeView)).setTargetValue(player.getGas());
}
};
runOnUiThread(setGauge);
}
}
The Thread:
package edu.rit.jacob.timeturner;
import android.content.Context;
import android.graphics.Canvas;
import android.hardware.*;
import android.hardware.SensorManager;
import android.provider.Settings;
import android.util.Log;
import android.view.SurfaceHolder;
import android.widget.ImageView;
public class UniverseThread extends Thread {
public static final String TAG = UniverseThread.class.getSimpleName();
private double time;
public double getTime(){
return time;
}
private double speed;
public double getSpeed(){
return speed;
}
private boolean running;
public void setRunning(boolean running){
this.running = running;
}
public boolean isRunning(){
return running;
}
//Reference to the UniverseActivity
private SurfaceHolder surfaceHolder;
//Reference to the UniverseView that is the background
private UniverseView universeView;
public UniverseThread(SurfaceHolder surfaceHolder, UniverseView universeView){
super();
this.surfaceHolder = surfaceHolder;
this.universeView = universeView;
running = false;
time = 0;
}
public static float x = 0, y = 0, z = 0;
#Override
public void run(){
Log.d(TAG, "Starting Game Loop");
time = 0.0;
speed = 0.0;
//SensorManager gets SENSOR_SERVICE from android
//Accesses gravity sensor
SensorManager sm = (SensorManager) this.universeView.getContext().getSystemService(Context.SENSOR_SERVICE);
sm.registerListener(new SensorEventListener() {
#Override
public void onSensorChanged(SensorEvent event) {
x = event.values[0];
y = event.values[1];
z = event.values[2];
}
#Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
}, sm.getDefaultSensor(Sensor.TYPE_GRAVITY), SensorManager.SENSOR_DELAY_GAME);
//save player, velocity, and sprite
Galaxy player = ((UniverseActivity)universeView.getContext()).getPlayer();
Velocity vel = player.getVel();
ImageView sprite = player.getSprite();
boolean changeBackground;
float timesRun = 0f;
while(running){
//every 16 milliseconds (~60 Hz)
timesRun += 1;
final String testStr = "Thread has run for " + (timesRun) + " frames.";
Runnable test = new Runnable() {
#Override
public void run() {
Log.d(TAG, testStr);
}
};
if(timesRun % 60 == 0) ((UniverseActivity) universeView.getContext()).runOnUiThread(test);
//increment the time
speed = ((UniverseActivity)universeView.getContext()).getSpeed();
time += (speed / 7200.0);
((UniverseActivity)universeView.getContext()).setTimeProgress((int) time);
//update player's velocity
((UniverseActivity)universeView.getContext()).getPlayer().getVel().incrementXV(-x / 9.81f);
((UniverseActivity)universeView.getContext()).getPlayer().getVel().incrementYV(y / 9.81f);
//update player's position
//move sprite
sprite.setX((float)(sprite.getX() + (vel.getxV() * speed / 400)));
sprite.setY((float)(sprite.getY() + (vel.getyV() * speed / 400)));
changeBackground = false;
//bottom -> top
if (sprite.getY() + (sprite.getHeight() / 2) > universeView.getHeight()) {
sprite.setY(0 - (sprite.getHeight() / 2));
sprite.setX(universeView.getWidth() / 2);
player.updateSector("BOTTOM");
changeBackground = true;
}
//right -> left
if (sprite.getX() + (sprite.getWidth() / 2) > universeView.getWidth()) {
sprite.setY(universeView.getHeight() / 2);
sprite.setX(0 - (sprite.getWidth() / 2));
player.updateSector("RIGHT");
changeBackground = true;
}
//top -> bottom
if (sprite.getY() + (sprite.getHeight() / 2) < 0) {
sprite.setY(universeView.getHeight() - (sprite.getHeight() / 2));
sprite.setX(universeView.getWidth() / 2);
player.updateSector("TOP");
changeBackground = true;
}
//left -> right
if (sprite.getX() + (sprite.getWidth() / 2) < 0) {
sprite.setY(universeView.getHeight() / 2);
sprite.setX(universeView.getWidth() - (sprite.getWidth() / 2));
player.updateSector("LEFT");
changeBackground = true;
}
if(changeBackground)
{((UniverseActivity)universeView.getContext()).changeBackground();}
((UniverseActivity)universeView.getContext()).checkForCollision();
try{
this.sleep(16L);
}
catch (InterruptedException e){
e.printStackTrace();
}
}
Log.d(TAG, "Game Loop terminated");
}
}
To be clear, no exceptions or errors are being thrown during runtime. The only messages in logcat are my own and the system messages for registering a click, for example. The application does not crash and the sprite is still perfectly controllable. The main things that do not work is the changing of backgrounds, checking for a collision, and the onClickListeners.
Has anyone run into something like this before? Any help would be appreciated.
So after having narrowed the problem down to the Runnable objects I was passing to the UI thread, I took steps to minimize the amount of time I called runOnUIThread() at first it didn't seem to have any effect but eventually I stopped having this problem and that's the only thing I can contribute it to. I might eventually do some more testing to be more concrete that that was the problem and respective solution.
This is the source for a small app I'm making in Android Studio. When I call this function its suppose to compare dog,cat, and parrot to each other and then increment int dogCounter by 5. When I run the function however, It does not update the score.
dogCounter= 0;
catCounter = 0;
//check boxes
cutestCheckBoxDog = (CheckBox)findViewById(R.id.CheckboxCutestDog);
cutestCheckBoxCat = (CheckBox)findViewById(R.id.CheckboxCutestCat);
cutestCheckBoxParrot =(CheckBox)findViewById(R.id.CheckboxCutestParrot);
//call methods
processCutest(cutestCheckBoxDog, cutestCheckBoxCat, cutestCheckBoxParrot);
showResultButton= (Button)findViewById(R.id.showResults);
showResultButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(getApplicationContext(),catCounter + " " + dogCounter, Toast.LENGTH_LONG).show();
public void processCutest(CheckBox dog, CheckBox cat, CheckBox parrot){
if (dog.isChecked() && !cat.isChecked() && !parrot.isChecked()){
dogCounter += 5;
}else if (cat.isChecked() && !dog.isChecked() && !parrot.isChecked()){
catCounter += 5;
} else{
//nobody gets points
}
}
edit: Sorry for poor organization. Still pretty new, pointers on that would be nice as well.
package dogorcatperson.ivellapplication.com.dogorcatperson;
import android.content.Intent;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
private RadioGroup canineRadioGroup;
private RadioButton canineRadioButton;
private SeekBar seekBar;
private TextView seekBarTextView;
private CheckBox cutestCheckBoxDog;
private CheckBox cutestCheckBoxCat;
private CheckBox cutestCheckBoxParrot;
private RadioGroup droolRadioGroup;
private RadioButton droolRadioButton;
private Button showResultButton;
private int dogCounter;
private int catCounter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//call setup()
setUp();
//seekbar
seekBar = (SeekBar) findViewById(R.id.seekBarFeline);
seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
seekBarTextView.setText("comfortableness: " + progress + "/" + seekBar.getMax());
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
}
public void setUp(){
dogCounter= 0;
catCounter = 0;
canineRadioGroup =(RadioGroup)findViewById(R.id.radioGroupCanine);
droolRadioGroup = (RadioGroup)findViewById(R.id.RadioGroupDrool);
seekBarTextView = (TextView)findViewById(R.id.seekBarProgressTextView);
//check boxes
cutestCheckBoxDog = (CheckBox)findViewById(R.id.CheckboxCutestDog);
cutestCheckBoxCat = (CheckBox)findViewById(R.id.CheckboxCutestCat);
cutestCheckBoxParrot = (CheckBox)findViewById(R.id.CheckboxCutestParrot);
//call methods
processCutest(cutestCheckBoxDog, cutestCheckBoxCat, cutestCheckBoxParrot);
processDrool(droolRadioGroup);
processCanine(canineRadioGroup);
showResultButton= (Button)findViewById(R.id.showResults);
showResultButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(getApplicationContext(),catCounter + " " + dogCounter, Toast.LENGTH_LONG).show();
// Intent i = new Intent(MainActivity.this, ResultActivity.class);
// i.putExtra("catCounter", catCounter);
// i.putExtra("dogCounter", dogCounter);
// startActivity(i);
}
});
}
public void processCutest(CheckBox dog, CheckBox cat, CheckBox parrot){
if (dog.isChecked() && !cat.isChecked() && !parrot.isChecked()){
dogCounter += 5;
}else if (cat.isChecked() && !dog.isChecked() && !parrot.isChecked()){
catCounter += 5;
} else{
//nobody gets points
}
}
public void processDrool(final RadioGroup radioGroup){
radioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
int radioId= radioGroup.getCheckedRadioButtonId();
droolRadioButton = (RadioButton)findViewById(radioId);
if (droolRadioButton.getText().equals("yes")){
dogCounter+= 5;
}else if (droolRadioButton.getText().equals("no")){
catCounter+= 5;
}
}
});
}
public void processCanine(final RadioGroup radioGroup){
radioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
int radioId= canineRadioGroup.getCheckedRadioButtonId();
canineRadioButton = (RadioButton)findViewById(radioId);
if (canineRadioButton.getText().equals("yes")){
catCounter+= 5;
}else if (canineRadioButton.getText().equals("no")){
dogCounter+= 5;
}
}
});
}
}
I think you just need to change your processCutest call so that it goes inside the onClick method, but before the toast.makeText call. Like this:
showResultButton= (Button)findViewById(R.id.showResults);
showResultButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
processCutest(cutestCheckBoxDog, cutestCheckBoxCat, cutestCheckBoxParrot);
Toast.makeText(getApplicationContext(),catCounter + " " + dogCounter, Toast.LENGTH_LONG).show();
I'm assuming that the actual checkboxes are defined elsewhere. Are your checkboxes showing up? If so you might want to put the processDrool and processCanine calls right there as well.
I am trying to print something out for an android app every minute for ten minutes. I would preferably like to access the phone's clock to have the code start automatically at a specific time. However, I am not exactly sure how to do that part. Here is what I have so far.
So here is my main code I want to add the code below in along with the answer provided below:
package com.example.james.texttospeech;
import android.os.Bundle;
import android.app.Activity;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.view.View;
import android.widget.EditText;
import android.speech.tts.TextToSpeech;
import android.speech.tts.TextToSpeech.OnInitListener;
import android.content.Intent;
import java.util.Locale;
import android.widget.Toast;
public class MainActivity extends Activity implements OnClickListener, OnInitListener {
//TTS object
private TextToSpeech myTTS;
//status check code
private int MY_DATA_CHECK_CODE = 0;
//create the Activity
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//get a reference to the button element listed in the XML layout
Button speakButton = (Button)findViewById(R.id.speak);
Button speakButton1 = (Button)findViewById(R.id.button);
Button speakButton2 = (Button)findViewById(R.id.button2);
//listen for clicks
speakButton.setOnClickListener(this);
speakButton1.setOnClickListener(this);
speakButton2.setOnClickListener(this);
//check for TTS data
Intent checkTTSIntent = new Intent();
checkTTSIntent.setAction(TextToSpeech.Engine.ACTION_CHECK_TTS_DATA);
startActivityForResult(checkTTSIntent, MY_DATA_CHECK_CODE);
}
//respond to button clicks
public void onClick(View v) {
//get the text entered
EditText enteredText = (EditText)findViewById(R.id.enter);
String words = enteredText.getText().toString();
speakWords(words);
}
//speak the user text
private void speakWords(String speech) {
//speak straight away
myTTS.speak(speech, TextToSpeech.QUEUE_FLUSH, null);
}
//act on result of TTS data check
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == MY_DATA_CHECK_CODE) {
if (resultCode == TextToSpeech.Engine.CHECK_VOICE_DATA_PASS) {
//the user has the necessary data - create the TTS
myTTS = new TextToSpeech(this, this);
}
else {
//no data - install it now
Intent installTTSIntent = new Intent();
installTTSIntent.setAction(TextToSpeech.Engine.ACTION_INSTALL_TTS_DATA);
startActivity(installTTSIntent);
}
}
}
//setup TTS
public void onInit(int initStatus) {
//check for successful instantiation
if (initStatus == TextToSpeech.SUCCESS) {
if(myTTS.isLanguageAvailable(Locale.US)==TextToSpeech.LANG_AVAILABLE)
myTTS.setLanguage(Locale.US);
}
else if (initStatus == TextToSpeech.ERROR) {
Toast.makeText(this, "Sorry! Text To Speech failed...", Toast.LENGTH_LONG).show();
}
}
}
import java.util.*;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
public class ClassExecutingTask {
long delay = 10 * 60000; // delay in milliseconds
LoopTask task = new LoopTask();
Timer timer = new Timer("TaskName");
public void start() {
timer.cancel();
timer = new Timer("TaskName");
Date executionDate = new Date(); // no params = now
timer.scheduleAtFixedRate(task, executionDate, delay);
}
private class LoopTask extends TimerTask {
public void run() {
while (delay > 0) {
System.out.println("Formation will form up in " + delay + " minutes");
delay--;
}
}
}
public static void main(String[] args) {
ClassExecutingTask executingTask = new ClassExecutingTask();
executingTask.start();
}
}
<!---->
public void run() {
while (delay > 0) {
System.out.println("Formation will form up in " + delay + " minutes");
delay--;
}
}
<!---->
public static void main(String[] args) {
ClassExecutingTask executingTask = new ClassExecutingTask();
executingTask.start();
}
If you want to do above thing in android then following code will help you add those lines in your onCreate()method
new CountDownTimer(600000, 60000) {//CountDownTimer(edittext1.getText()+edittext2.getText()) also parse it to long
public void onTick(long millisUntilFinished) {
System.out.println("Your message on every minute");
//here you can have your logic to set text to edittext
}
public void onFinish() {
System.out.println("Your message after 10 minute");
}
}
.start();