I found that if I call start() right after setBase(SystemClock.elapsedRealtime()) it will start counting from 00:00 (which is fine), see below:
startButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
chronometer.setBase(SystemClock.elapsedRealtime());
chronometer.start();
}
});
However, if I place the setBase(SystemClock.elapsedRealtime()) out of the setOnCLickListener() like this:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
chronometer = findViewById(R.id.main_chronometer);
startButton = findViewById(R.id.main_start_button);
resetButton = findViewById(R.id.main_reset_button);
chronometer.setBase(SystemClock.elapsedRealtime()); //no good here
startButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//chronometer.setBase(SystemClock.elapsedRealtime());
chronometer.start();
}
});
}
It will start counting from the elapsed time since this app launches. Why?
The behavior you describe is caused by the asynchronous nature of user interaction. Your two examples can be broken down as follows:
Calling setBase inside onClick
App launches
UI is configured; click listener is set on button
Time passes...
User clicks button
Chronometer baseline is set to the current time
Chronometer is started
Notice there is no time passing between steps 5 (chronometer baseline is set) and 6 (chronometer is started), which is why the chronometer correctly starts at 0 when you check its value.
Calling setBase inside onCreate and outside onClick
App launches
UI is configured; click listener is set on button
Chronometer baseline is set to the current time
Time passes...
User clicks button
Chronometer is started
In this version, time passes between steps 3 (chronometer baseline is set) and 6 (chronometer is started), which is why the chronometer does not start at 0 when you check its value.
Related
I'm working on making an animation that plays when I press I button. This animation is composed of 3 frames I have made.
As of now, when I press the button, the animation starts, but doesn't stop, it just keeps looping over and over again.
What I would like is the following:
When you press the button, the animation plays once. It doesn't play until you press the button again. HOWEVER, if you press the button while the animation is playing (AKA interrupt the animation before it finishes), the animation will restart.
Here is the code I have that plays the animation when the button is pressed:
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button start = (Button) findViewById(R.id.button);
start.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
ImageView bun = (ImageView)findViewById(R.id.imageView);
bun.setImageResource(R.drawable.buns);
AnimationDrawable buns = (AnimationDrawable)bun.getDrawable();
buns.start();
}
});
}
}
I'm aware that you can write:
buns.setOneShot(true)
and that will cause the animation to play one time and then stop, but this isn't the solution I'm looking for.
Thanks!
Update:
I figured out the solution to this, in case anyone else was having problems.
It seems if I add the line:
buns.setOneShot(true);
after
buns.start()
this will have the intended affect, since the animation will stop after you click it and won't start until you click it again.
Cheers!
Here in my MainActivity.java I have an object MediaPlayer, which plays a sound when you click playB button and pause by pressing pauseB. Everything is working fine. But if you re-open the app and click pauseB, the sound continues to play. How to fix it? How to catch the current playing MediaPlayer?
public class MainActivity extends ActionBarActivity {
Button playB;
Button pauseB;
Context c;
MediaPlayer mp;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final Button playB = (Button) findViewById(R.id.playB);
Button pauseB = (Button) findViewById(R.id.pauseB);
mp = mp.create(this, R.raw.fawaid_1);
playB.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
mp.start();
}
});
pauseB.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
mp.pause();
}
});
}
}
when you re-open the app, onCreate is called again, hence you have a new MediaPlayer object, and from that moment, play and pause buttons will control that new player object instead of a previous one. That's why your pause button will have no effect on the sound that started BEFORE you minimized the app. And if you press play button now, you will have two sounds playing at the same time
one way to overcome this, is to check if media player has already been initialized:
if(mp==null)
mp = MediaPlayer.create(this, R.raw.fawaid_1);
It is advisable to use Service with AIDL in developing music player.
Reasons.
You can retain the control again once you go back in your activity.
It is easy to perform an inter process communication.
Here is a simple music Player that runs on the Background, Music Player
The song I used in this music player is Owned by SnowFlakes
I have a view (button) and am listening to a click event, but in my while loop it won't call the onClick method:
public class Activity_Main extends Activity implements OnClickListener {
Button button1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button1 = (Button)findViewById(R.id.btn_1);
button1.setOnClickListener(this);
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_1:
//do something make boolean false for example
break;
}
}
while(boolean == true) {
//it's not reacting on the click
}
Is there something I am missing?
You are blocking the main thread with that infinite while loop:
while(boolean == true) {
//it's not reacting on the click
}
and it cant execute any other code. You should be more worried about the ANR coming next rather then the click not responding. Put the while loop in a separate thread as suggested and dont overload the main thread's work with excessive tasks.
If you use Handlers and Messages you can start and stop the recording when the user clicks the button. And to check if the button has been clicked, just use onClick method.
I have an app with a home screen and a bunch of buttons on it, and therefore listeners for each. After the user clicks on one of the buttons, a new layout is brought up and that layout has a back button with a listener.
The problem is that whenever the user presses the back button, the home screen layout is brought back up but none of the listeners work for the buttons anymore.
Here is some sample code:
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main); // return to home screen
// sets up a listener for when the GCF main screen button is clicked.
GCFButton.setOnClickListener(new View.OnClickListener()
{
public void onClick(View v)
{
setContentView(R.layout.gcf); // change to the gcf layout
Button back = (Button)findViewById(R.id.btnBack); // set up the back button in the gcf layout
back.setOnClickListener(new View.OnClickListener() // put a listener on back button
{
public void onClick(View v)
{
setContentView(R.layout.main); // return to home screen
}
});
Button GCFCalculate = (Button)findViewById(R.id.btnCalculate); // set up the gcf button in the gcf layout
GCFCalculate.setOnClickListener (new View.OnClickListener() // put listener on gcf button in gcf layout
{
public void onClick(View v)
{
// do stuff
}
});
}
});
}
You should not change a screen with setContentView(). Screens are changed in Android by starting a new Activity with startActivity(new Intent(...)) or with Fragments like recommended by Malimo (which is a bit more difficult to do but much nicer). You call two times setContentView() where one is destroying the other one.
in my opinion you should use fragments for your contentviews. so every fragment will be responsible for its contentview and can add listeners each time it is displayed...
http://developer.android.com/guide/components/fragments.html
I'm sure that there is a method built into Android that allows you to do this, but my first thought is recursion.
The problem is that your listeners are in the onCreate method, which means that after they are run through, they won't repeat. In the back button listener,
when you set the content view to be the home screen again, that won't set up the listeners again, that will just change the content view.
To fix that, you would have to call the onCreate method again, once the back button is clicked, because then it would run your whole code with all the listeners
from the home screen again.
I suggest putting all of the listeners in a listeners() method, and then calling that method recursively when needed. It would need to be called in onCreate(...),
as well as when the back button is clicked:
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
listeners(); // set up all the listeners for the buttons
}
public void listeners()
{
setContentView(R.layout.main); // return to home screen
// sets up a listener for when the GCF main screen button is clicked.
GCFButton.setOnClickListener(new View.OnClickListener()
{
public void onClick(View v)
{
setContentView(R.layout.gcf); // change to the gcf layout
Button back = (Button)findViewById(R.id.btnBack); // set up the back button in the gcf layout
back.setOnClickListener(new View.OnClickListener() // put a listener on back button
{
public void onClick(View v)
{
listeners(); // recursively call the listeners again to 'start over'
}
});
Button GCFCalculate = (Button)findViewById(R.id.btnCalculate); // set up the gcf button in the gcf layout
GCFCalculate.setOnClickListener (new View.OnClickListener() // put listener on gcf button in gcf layout
{
public void onClick(View v)
{
// do stuff
}
});
}
});
}
I would also recommend putting the back button listener in its own method, so that it can be called every time the layout is changed.
hi i am a new developer. i am trying to design an app. In my app i want to calculate the no of touches in a particular button. Is this can be calculated by onTouch process if yes can anyone give me an example or idea.
Try below code
First Create an Global variable
int numberOfClick = 0;
Now for your button try following code
clickButton.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
numberOfClick++;
}
}
now you can get the number of clicks by this variable
A click on a button is sent to the app via the onClick event. So if you have a Button:
Button myButton = (Button) findViewById(R.id.myButton);
myButton.setOnClickListener(myClickListener);
You can set up your onClickListener to do whatever you want when the button is clicked.
// Create an anonymous implementation of OnClickListener
private OnClickListener myClickListener = new OnClickListener() {
public void onClick(View v) {
// increment the counter on click
numberOfClicks++;
}
};