I'm creating a simple app with two NumberPickers used to select a certain number of minutes and seconds. There isn't too much code so I will post it here:
public class MainActivity extends Activity implements OnClickListener {
private static final String TAG = "Interval Trainer";
private CountDownTimer countDownTimer;
private boolean timerHasStarted = false;
private Button startButton;
public TextView text;
private final long interval = 1 * 1000;
//Create NumberPickers
NumberPicker numberPicker1 = (NumberPicker) findViewById(R.id.numberPicker1);
NumberPicker numberPicker2 = (NumberPicker) findViewById(R.id.numberPicker2);
#Override
protected void onCreate(Bundle savedInstanceState) {
Log.i(TAG,"Entering onCreate()");
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
startButton = (Button) this.findViewById(R.id.button);
startButton.setOnClickListener(this);
text = (TextView) this.findViewById(R.id.timer);
//Set min and max values for NumberPickers
numberPicker1.setMaxValue(100);
numberPicker1.setMinValue(0);
numberPicker2.setMaxValue(59); //This is the seconds picker
numberPicker2.setMinValue(0);
Log.i(TAG,"Exiting onCreate()");
}
#Override
public void onClick(View v) {
//Calculate total time from NumberPickers in seconds
long startTime = (numberPicker1.getValue() * 60) + numberPicker2.getValue();
//Create CountDownTimer with values from NumberPickers
countDownTimer = new MyCountDownTimer(startTime, interval);
text.setText(text.getText() + String.valueOf(startTime / 1000)); //should be removed
if(!timerHasStarted) {
countDownTimer.start();
timerHasStarted = true;
startButton.setText("STOP");
} else {
countDownTimer.cancel();
timerHasStarted = false;
startButton.setText("RESTART");
}
//Disable the NumberPickers after 'Start' is pressed
numberPicker1.setEnabled(false);
numberPicker2.setEnabled(false);
}
public class MyCountDownTimer extends CountDownTimer {
public MyCountDownTimer(long startTime, long interval) {
super(startTime, interval);
}
#Override
public void onFinish() {
text.setText("Time's up!");
//re-enable the NumberPickers once countdown is done
numberPicker1.setEnabled(true);
numberPicker2.setEnabled(true);
}
#Override
public void onTick(long millisUntilFinished) {
text.setText("" + millisUntilFinished / 1000);
//Changes the value of the NumberPickers after each tick
}
}
}
I have a feeling the crash is related to me declaring the two NumberPickers outside of any methods (this would automatically make them static?). Originally I had these two lines of code in my onCreate() but since I needed them in my inner class and other methods I moved it outside. Is this what is causing the crash? If so, how do I do this correctly and still have access to numberPicker1 and 2 all around my class (including inner class)?
Thank you!
You cant intiate object like this
//Create NumberPickers
NumberPicker numberPicker1 = (NumberPicker) findViewById(R.id.numberPicker1);
NumberPicker numberPicker2 = (NumberPicker) findViewById(R.id.numberPicker2);
after onCreate only you layout loads so you dont have you object yet initialized.
You can initlize you object in onCreate after
setContentView(R.layout.activity_main);
For example
// init variable
NumberPicker numberPicker1 = null;
NumberPicker numberPicker2 = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
setContentView(R.layout.activity_main);
// After here only your Activity gets the layout objects
numberPicker1 = (NumberPicker) findViewById(R.id.numberPicker1);
numberPicker2 = (NumberPicker) findViewById(R.id.numberPicker2);
}
You should put your findViewById inside onCreate method and create local variables:
// init variable
NumberPicker numberPicker1, numberPicker2;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// ...
numberPicker1 = (NumberPicker) findViewById(R.id.numberPicker1);
numberPicker2 = (NumberPicker) findViewById(R.id.numberPicker2);
}
Then, you will able to call these variables inside other methods. According to this reference:
Non-static nested classes (InnerClasses) have access to other members of the enclosing class, even if they are declared private. Static nested classes do not have access to other members of the enclosing class. [...] InnerClass has direct access to the methods and fields of its enclosing instance.
Related
I want to reset my horizontal progressbar to 0 every night at 12.
Here is my code.
public class MainActivity extends AppCompatActivity {
private TextView textView;
Button btn;
private int Counter counter;
Progressbar progressbar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = findViewById(R.id.txtvw);
progressbar = findViewById(R.id.progressbar_Horizontal);
progressbar.setMax(10);
btn = findViewById(R.id.btn_clc);
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
counter++;
textView.setText(String.valueOf(counter));
progressbar.setProgress(counter)
}
});
Calendar calendar = Calendar.getInstance();
int hour = 23;
int minute = 59;
int second = 59;
int curHour = calendar.get(Calendar.HOUR_OF_DAY);
int curMinute = calendar.get(Calendar.MINUTE);
int curSecond = calendar.get(Calendar.SECOND);
if (hour==curHour && minute==curMinute && second==curSecond) {
progressbar.setProgress(0);
}
}
}
In this method at the output there is no response to the progressbar! Is this the right way to do or is there any other way?
You don't get any response because you're defining the action in OnCreate method. This method is executed one time when you enter the Activity. So this action defined only works if you launch your Ativity exactly at 23:59:59.
If you want to do it right, implement AlarmManager. You can set the time you want (23:59:59) and do whatever you want (reset the bar) at that moment. You can implement it also when the app is closed, in the background or when the screen is off.
Take a look at this: Alarm Manager Example
This class extends my main Activity.
public class Numbers extends MainActivity{
public ArrayList<ImageView> getNumbers () {
ArrayList<ImageView> numbers = new ArrayList<>();
ImageView one = (ImageView) findViewById(R.id.one);
numbers.add(one);
return numbers;
}
And I've done some digging but can figure out why my variable "one" is coming back null.
My MainActivity has a ContentView set.
This is the content of my onCreate in MainActivity
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ImageView start = (ImageView) findViewById(R.id.start);
sceneRoot = (ViewGroup) findViewById(R.id.scene_root);
questionView = findViewById(R.id.questionView);
startView = findViewById(R.id.startView);
gameOverView = findViewById(R.id.gameOver);
animSlide = AnimationUtils.loadAnimation(getApplicationContext(), R.anim.slide);
animSlide.setAnimationListener(this);
animZoom = AnimationUtils.loadAnimation(getApplicationContext(), R.anim.zoom_fade);
animZoom.setAnimationListener(this);
set.addTransition(new Fade())
.addTransition(new Slide(Gravity.RIGHT));
start.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
getQuestion();
TransitionManager.beginDelayedTransition(sceneRoot, set);
startView.setVisibility(View.GONE);
questionView.setVisibility(View.VISIBLE);
}
});
}
public void getQuestion (){
time = (TextView) findViewById(R.id.timeBar);
time.startAnimation(animSlide);
}
I don't call getNumbers() until after start has been clicked and the animation has started.
public void onAnimationStart(Animation animation){
if(animation == animSlide) {
final Questions questions = new Questions();
Numbers n = new Numbers();
for (int i = 0; i < n.getNumbers().size(); i++) {
n.getNumbers().get(i).setVisibility(View.GONE);
n.getNumbersTen().get(i).setVisibility(View.GONE);
}
n.getNumbers().get(0).setVisibility(View.VISIBLE);
EDIT:
If anyone was wondering, I got it to work by extending the class as a Fragment instead of my MainActivity. Then I just used the fragment in my xml.
Because you extended an Activity class doesn't mean setContentView gets called for that class also. It will only do so if properly started and you call super.onCreate(bundle) from your own implementation of onCreate within Numbers
Basically, you should never new any Activity. It has no life-cycle, and therefore no content view, so findViewById just won't work.
Numbers n = new Numbers();
You could not extend anything and have a data-only class around your list of images.
public class Numbers {
private List<ImageView> numbers = new ArrayList<ImageView>();
public Numbers() {}
public void addNumber(ImageView v) { numbers.add(v); }
public List<ImageView> getNumbers() { return numbers; }
}
And from MainActivity you can find and add as you want.
Number n = new Numbers();
n.addNumber((ImageView) findViewById(R.id.one));
However, I don't know if that is useful, really...
Maybe a Fragment would serve a better purpose if you want a "sub-view" of your Activity, but it's hard to tell.
I am working through a Udemy course and we're building a basic "Higher or Lower" app. My app essentially works, however the random number it chooses for us to guess is always the same no matter how many times I destroy and relaunch the activity.
My MainActivity.java:
//mad import statements here
public class MainActivity extends AppCompatActivity {
int correctNumber;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
int correctNumber = generateNum();
}
protected int generateNum(){
Random rand = new Random();
int randNum = rand.nextInt(100);
return randNum;
}
protected void numberEval(View view) {
EditText enteredNumber = (EditText) findViewById(R.id.numberEntry);
String numberString = enteredNumber.getText().toString();
Button pressMe = (Button) findViewById(R.id.button);
int numToEval = Integer.parseInt(numberString);
String result;
TextView showWinLose = (TextView) findViewById(R.id.winLoseText);
if (numToEval > correctNumber) {
result = "Too high!";
} else if (numToEval < correctNumber) {
result = "Too Low!";
}else {
result = "You guessed it!";
}
showWinLose.setText(result);
}
}
Super super basic, yes? Originally, my numberEval() method called generateNum(), but then I realized it was generating a new number to guess every time I pressed the button. So I set it the way it was here, where onCreate() generates correctNumber only once and correctNumber is now a class variable. Now it doesn't generate a new number every button click, but it won't seem to generate a new number at all. It's stuck at 0 no matter how any times I launch, close, relaunch, etc. the app.
How can I fix this? Thanks in advance.
public class MainActivity extends AppCompatActivity {
int correctNumber;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
int correctNumber = generateNum();
}
// ...
}
The last line in onCreate() declares a local variable named correctNumber. This hides the class field with the same name and is only available inside onCreate(). To fix the problem, remove int from this line so that you use the class field instead.
Can anyone help me work out where I'm going wrong here. On the button click the media player plays one of the mfiles at random and I'm trying to set a textview depending on which file was played. Currently the setText if statements only match the audio playing half the time. Really not sure where I'm going wrong here.
private final int SOUND_CLIPS = 3;
private int mfile[] = new int[SOUND_CLIPS];
private Random rnd = new Random();
MediaPlayer mpButtonOne;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mfile[0] = R.raw.one;
mfile[1] = R.raw.two;
mfile[2] = R.raw.three;
//Button setup
Button bOne = (Button) findViewById(R.id.button1);
bOne.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
final TextView textOne = (TextView)findViewById(R.id.textView1);
mpButtonOne = MediaPlayer.create(MainActivity.this, mfile[rnd.nextInt(SOUND_CLIPS)]);
if (mpButtonOne==null){
//display a Toast message here
return;
}
mpButtonOne.start();
if (mfile[rnd.nextInt(SOUND_CLIPS)] == mfile[0]){
textOne.setText("one");
}
if (mfile[rnd.nextInt(SOUND_CLIPS)] == mfile[1]){
textOne.setText("two");
}
if (mfile[rnd.nextInt(SOUND_CLIPS)] == mfile[2]){
textOne.setText("three");
}
mpButtonOne.setOnCompletionListener(new soundListener1());
{
}
So just to clarify the problem I am having is that the setText only matches the audio occasionally, not on every click. The rest of the time it displays the wrong text for the wrong audio.
You are choosing another random file
mfile[rnd.nextInt(SOUND_CLIPS)]
set that to a variable in onClick() then check against that variable in your if statement
public void onClick(View v) {
int song = mfile[rnd.nextInt(SOUND_CLIPS)];
final TextView textOne = (TextView)findViewById(R.id.textView1);
mpButtonOne = MediaPlayer.create(MainActivity.this, song);
if (song == mfile[0]){
textOne.setText("one");
}
Edit
To make it a member variable so you can use it anywhere in the class, just declare it outside of a method. Usually do this before onCreate() just so all member variables are in the same place and it makes your code more readable/manageable.
public class SomeClass extends Activity
{
int song;
public void onCreate()
{
// your code
}
then you can just initialize it in your onClick()
public void onClick(View v) {
song = mfile[rnd.nextInt(SOUND_CLIPS)];
final TextView textOne = (TextView)findViewById(R.id.textView1);
mpButtonOne = MediaPlayer.create(MainActivity.this, song);
Well as the title states, anytime I try (in my java class) to settext of a TextView by directing it set the text of a string listed in "strings.xml" my program crashes, If i remove that call then the program runs fine. Below is an example.
MediaPlayer dus;
String Stat;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.main);
final TextView T = (TextView) findViewById(R.id.Status);
dus = MediaPlayer.create(DialUpDroidActivity.this, R.raw.dus);
Timer timer;
timer = new Timer();
dus.start();
Stat = getString(R.string.Dial);
TimerTask TxtTimer = new TimerTask() {
public void run() {
T.setText(Stat);
}
};
timer.schedule(TxtTimer, 7000);
}
So as you can see i tried to do T.setText(Stat); but the program crashed. I've tried T.setTextView(R.string.Dial); and T.setTextView("Hello") Both methods crashed. What am I doing wrong?
Have you initiliazed your textview?
TextView T = (TextView)findViewById(R.id.yourId);
Where is
T = (TextView)findById(...)
?
Use
getString(R.string.XXX)