I'm working with a progress bar and an animation.
progressBar = (ProgressBar)findViewById(R.id.progressBar1);
Animation animation = new RotateAnimation(30, 180);
progressBar.setAnimation(animation);
further down in my method I
set the duration for this animation
progressBar.getAnimation().setDuration(3000);
so for 3 seconds, the animation will run.
if I want to hide the ProgressBar after the animation ends I have to do the following
if(progressBar.getAnimation().getDuration() == 3000){
progressBar.setVisibility(ProgressBar.GONE);
}
What I tried doing was
if(progressBar.getAnimation.hasEnded()){
progressBar.setVisibility(ProgressBar.GONE);
}
this does not work
Could somebody explain why the hasEnded method doesn't seem to return true where I think it should.
you can call set an Animation Listener on the animation object. The Listener calls tree methods, one of which is onAnimationEnd().
animation.setAnimationListener(new AnimationListener() {
#Override
public void onAnimationStart(Animation anim) {
};
#Override
public void onAnimationRepeat(Animation anim) {
};
#Override
public void onAnimationEnd(Animation anim) {
// here your logic
};
});
I think problem is in below line...
if(progressBar.getAnimation.hasEnded()) {
it should be...
if(progressBar.getAnimation().hasEnded()) {
Edit::
That's because you're starting the animation and immediately checking if the animation has ended which is doubtful unless it simply doesn't do anything. What you want to do is implement an AnimationListener callback and set it to that animation.
Related
This Should be easy and simple right?!
So, i have a Gameobject as a Button i reference it on a GamePanel that extents SurfaceView like this :
bby = new Buttons(BitmapFactory.decodeResource(getResources(), R.drawable.babybutton),123 ,114 ,1);
bby is drawn and work fine,
my problem is How can i change the Resource (R.drawble.babybutton) to a different resource for e.g (R.drawble.babybutton2) on Touch?
just like pressing buttons animations!
Thanks in advance
(If my question look stupid please don't dislike! i'm very new to this).
if you want to change the button's drawable on touch on the surfaceview. than you can override this method in your surfaceview class.
#Override
public boolean onTouch(View v, MotionEvent event) {
switch(event.getAction()){
case MotionEvent.ACTION_DOWN:
//here you can set an another drawable to your button or can do something else
break;
}
return true;
}
In your activity set a touchListener on the surfaceview.
after initialize the surfaceView. pass this surfaceview to the
surfaceView.setOnTouchListener(surfaceView)
I may have misunderstood you, but if you want to change the button's rescource, this is how you should do it:
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
runOnUiThread(new Runnable() {
#Override
public void run() {
button.setBackgroundResource(R.drawable.icon);
}
});
}
});
I need to perform an action after onClick method of OnClickListener has run.
Here is my code for onClickListener:
View.OnClickListener imgButton0Handler0 = new View.OnClickListener() {
int identifier=0;
public void onClick(View v) {
//check if tile is found and return if it is
if(isFound[identifier]==true) return;
//set tile as open
checkField[identifier]=1;
//set background on predetermined
button0.setBackgroundResource(tiles[identifier]);
}
};
After this has run, and the background is set I would like to call a method checker(int identifier) which will check for other open tiles and change backgrounds accordingly.
This method needs to be run separately because the background is only displayed after onClick finishes, and I need predetermined background shown for a short time before checker method changes it to something else.
How can I accomplish this?
Have You Tried Post Delayed see this,
View.OnClickListener imgButton0Handler0 = new View.OnClickListener() {
int identifier=0;
public void onClick(View v) {
//check if tile is found and return if it is
if(isFound[identifier]==true) return;
//set tile as open
checkField[identifier]=1;
//set background on predetermined
button0.setBackgroundResource(tiles[identifier]);
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
// This method will be executed once the timer is over
// Start your app main activity
checker(identifier) // your method call
}
}, 3000); // 3 second
}
};
In my project I have a lot of asynctask, which all follow this pattern:
#Override
protected void onPreExecute() {
super.onPreExecute();
crossfade(progressBar, contentView);//hide content, show progress bar
}
#Override
protected Void doInBackground(String... arg0) {
//some work
}
protected void onPostExecute(Void unused) {
crossfade(contentView, progressBar);
}
Code for crossfade:
void crossfade(View contentView, View loadingView){
Runnable r = new Runnable(){
#Override
public void run() {
if(contentView != null){
contentView.setAlpha(0f);
contentView.setVisibility(View.VISIBLE);
contentView.animate()
.alpha(1f)
.setDuration(CROSSFADE_TIME)
.setListener(null);
}
if(loadingView != null){
loadingView.animate()
.alpha(0f)
.setDuration(CROSSFADE_TIME)
.setListener(new AnimatorListenerAdapter() {
#Override
public void onAnimationEnd(Animator animation) {
if(loadingView != null){
loadingView.setVisibility(View.GONE);
}
}
});
}
}
};
runOnUiThread(r);
}
The problem happens when asynctask executes faster than animation time, causing second crossfade call before the first one is finished, resulting in both views being invisible.
I tried queueing runnables to execute them sequentially, but the problem is if user clicks a lot of buttons or many fragments are being loaded(they use crossfade method too), UI thread becomes overloaded and it may crash my app. The only solution I see so far is to add extra delay to all my asynctasks, using Thread.sleep(CROSSFADE_TIME), however it looks like a really dirty hack and I'm not sure if it's a good user experience.
In case someone needs it in future, adding loadingView.animate().cancel() and contentView.animate().cancel() before animation cancels previous animations and everything works ok.
Why are you running the crossfade animation in a separate thread? Try to do the animation without
Runnable r = new Runnable(){ and runOnUiThread(r);
I am using the android developer tools in Eclipse, programming in Java, and I need to make an object move across the screen as long as a button is pressed. I've been doing research for hours, and I cannot find any methods to accomplish this. I've tried running threads, which often crash or seemingly don't execute. I've also tried an onClickListener which reads the button state and uses it to determine whether or not the button is still pressed. I'm currently using a while loop, but this just freezes the program. I believe that this is the best method, and I've tried to use Thread.sleep in order to limit the number of iterations per second, as I believe that this is the reason it is freezing. Am I on the right track or am I way off in left field? Here is a snippet of code:
rightButton.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View arg0)
{
while(arg0.isPressed())
{
mover.updateCoordinates(1, 0);
}
}
});
Would you try this another method?
Firstly declare your button as class variable, declare a Handler and a Runnable:
private Button rightButton; // You will assign this in onCreate() method
private Handler mHandler = new Handler();
private Runnable mRunnable = new Runnable() {
#Override
public void run() {
if(rightButton.isPressed())
{
// If press state is pressed, move your item and recall the runnable in 100 milliseconds.
mover.updateCoordinates(1, 0);
mHandler.postDelayed(mRunnable, 100);
}
}
};
Then your button's onClickListener will looks like this:
rightButton.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View arg0)
{
// Instead of performing a loop here, just call a runnable, do simple press state checking there.
mHandler.postDelayed(mRunnable, 100);
}
});
Create a loop that updates the views, waits, and calls itself after it finishes waiting. Within the loop, have an animation if statement with a boolean field that move on true and does not move on false. Have the onClick method toggle the boolean field's value.
Try:
myView.setOnTouchListener(new OnTouchListener() {
public boolean onTouch(View v, MotionEvent e) {
if (e.getAction() == MotionEvent.ACTION_DOWN) {
// Start your animation here
} else if (e.getAction() == MotionEvent.ACTION_UP) {
// Stop your animation here
}
return false;
}
});
References:
MotionEvent
OnTouchListener
Alternatively, override onKeyUp and onKeyDown of the View class and check for the KEYCODE_ENTER KeyEvent
I have a linearLayout that disappears when I hit a button, it comes back when I press the button again. But it does it so fast, it doesn't look nice.
I do this via:
disappearView.setVisibility(View.GONE);
I would like to add some animation... If I just set visibity to invisible the space where the layout was is still there. So I tried this:
if (disappearView.getVisibility() == View.VISIBLE){
Animation out = AnimationUtils.makeOutAnimation(this, true);
disappearView.startAnimation(out);
disappearView.setVisibility(View.INVISIBLE);
disappearView.setVisibility(View.GONE);
}
else {
Animation in = AnimationUtils.loadAnimation(this, android.R.anim.fade_in);
disappearView.startAnimation(in);
disappearView.setVisibility(View.VISIBLE);
}
This does the animation too fast and disappears. You can't see it at all. Do I need to use a thread to start gone after invisible is set...or a delay? Or is there a better way of doing all this?
I'm not sure exactly what you're trying to accomplish...do you want the LinearLayout to fade out over a little bit of time rather than instantly disappear? And then once it fades out be removed from the parent via View.GONE?
If so, you can use an AlphaAnimation for the fade out and then attach a listener like EvZ posted:
AlphaAnimation fadeOutAnimation = new AlphaAnimation(1, 0); // start alpha, end alpha
fadeOutAnimation.setDuration(1000); // time for animation in milliseconds
fadeOutAnimation.setFillAfter(true); // make the transformation persist
fadeOutAnimation.setAnimationListener(new AnimationListener() {
#Override
public void onAnimationEnd(Animation animation) {
linearLayout.setVisibility(View.GONE);
}
#Override
public void onAnimationRepeat(Animation animation) { }
#Override
public void onAnimationStart(Animation animation) { }
});
linearLayout.setAnimation(fadeOutAnimation);
You can try to use onAnimationEnd : Animation.AnimationListener