I´m new to programming, started in the Lockdown last year with youtube videos and a book. I´m trying to make a button, that starts an fade out animation on an ImageView. which should be repeatable. It´s basically a dice roll and i want the dice to appear and then disappear every time within like 2 seconds after click.
Animation animation = AnimationUtils.loadAnimation(getApplicationContext(),R.anim.fade_out);
dice.setAnimation(animation);
animation.setStartOffset(3000);
animation.setDuration(100);
dice.setVisibility(View.VISIBLE);
dice.animate().alpha(1).setDuration(500);
btnDice.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Animation animation1 =AnimationUtils.loadAnimation(getApplicationContext(),R.anim.fade_out);
dice.setAnimation(animation1);
}
});
this is the content of the fade_out animation:
<alpha
android:duration="2000"
android:fromAlpha="1"
android:interpolator="#android:anim/accelerate_interpolator"
android:toAlpha="0"
/>
and i´ve got this in the top part:
android:fillAfter="true"
this is my dice, its an array with 6 dice pictures in it:
private void changeDice() {
Random random = new Random();
int randomNumber = random.nextInt(6);
dice.setBackgroundResource(dicee.getResourceId(randomNumber, 1));
}
im not sure how to connect all this to make the button appear and disappear each time. it works only once and since i put the dice image to "gone" added this:
dice.setVisibility(View.VISIBLE);
dice.animate().alpha(1).setDuration(500);
i get some weird results, that i cant explain. first animation works, after that the dice appear, animation wont trigger again and on multiple clicks the dice sometimes disappear.
maybe someone might see what i could change to make it work.
Related
I have a RecyclerView on the screen and products with images in it. I'm trying to make an animation where the image of the product from the RecyclerView moves to the floating action button on the screen (both have the same parent layout - a coordinator layout.)
I have tried achieving this with TranslateAnimation and when that didn't work well, I also tried doing it with ObjectAnimator, but with both the animation always either starts from the wrong position or ends in the wrong position on the screen.
This was my attempt to achieve this with TranslateAnimation:
// Get the X and Y position of the ImageView and the FAB
int[] imageViewPos = new int[2];
productImage.getLocationInWindow(imageViewPos);
int[] fabPos = new int[2];
fab.getLocationInWindow(fabPos);
// Calculate the x and the y distance between the FAB and the imageView
xDelta = fabPos[0] - imageViewPos[0];
yDelta = fabPos[1] - smallImageViewPos[1];
productMoveAnimation = new TranslateAnimation(0, xDelta, 0, yDelta);
productMoveAnimation.setDuration(500);
productMoveAnimation.setInterpolator(new AccelerateDecelerateInterpolator());
productImage.startAnimation(productMoveAnimation);
I also tried to use getLocationOnScreen instead of getLocationInWindow, but the productImage still didn't move to the correct position of the FAB.
This was my attempt to achieve this using ObjectAnimator:
pvhX = PropertyValuesHolder.ofFloat("x", imageViewPos[0], fabPos[0]);
pvhY = PropertyValuesHolder.ofFloat("y", imageViewPos[1], fabPos[1]);
productMoveAnim = ObjectAnimator.ofPropertyValuesHolder(productImage, pvhX, pvhY);
productMoveAnim.start();
And with this code instead, the ImageView kept going off the screen in the animation - even though it did start from the correct position. I tried getLocationOnScreen here too, and getLeft and getTop but it didn't fix anything.
I would really appreciate if anyone could help me figure out what I'm missing here, thanks in advance for any help! :)
I have a layout with 2*2/3*3/4*4... ImageView. and some of them randomly colored like this:
For ranodomly colored one of Imageview, I have Use this code:
Random random = new Random();
id = array_image1.get(random.nextInt(array_image1.size()));
ObjectAnimator animator = ObjectAnimator.ofInt(findViewById(id), "backgroundResource", R.drawable.original_img, R.drawable.org_state).setDuration(1500);
animator.setStartDelay(1500);
animator.setEvaluator(new ArgbEvaluator());
animator.start();
And I'm handling some click event on colored ImageView like this:
for (int i = 0; i < array_image11.size(); ++i) {
final int btn = array_image11.get(i);
findViewById(btn).setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
if ((findViewById(id)).equals(findViewById(btn)))
//Inform the user the button has been clicked
{
//forward
findViewById(id).setBackgroundResource(R.drawable.original_img);
}else {
//backward
Toast.makeText(StaticSpatial.this, "wrong", Toast.LENGTH_SHORT).show();
}
});
}
There is no problem till above.
But When I'm adding a random rotate animation code like this:
int n;
int[] a=new int[]{1,2};
final Random rnd = new Random();
n=a[rnd.nextInt(a.length)];
if(n==1)
{
ObjectAnimator rotateAnimator = ObjectAnimator.ofFloat(l4, View.ROTATION, 0, 90);
rotateAnimator.setDuration(2000); // miliseconds
rotateAnimator.start();n);
}
else
{
ObjectAnimator rotateAnimator = ObjectAnimator.ofFloat(l4, View.ROTATION, 0, 90);
rotateAnimator.setDuration(2000); // miliseconds
rotateAnimator.start();
}
After rotation image look like this(i.e. colored Imageview chage it's position):
After adding this rotate animation code my clickEvent not get correct ImageView id.
i.e. when imageview change it's position,their id should be go with that positon. but imageview id ramains at same postion.
So How to get required ImageviewId after rotation
Update:
After using azizbekian's answer(now using animator instead of animation) I found correct image-view id , but only first time.
i.e. first time when Activity starts it works good but when I'm going to a new view(say 3*3) and return back again to this view(2*2),it returns wrong image-view id till Activity restarts again.see my updated code for ref.
Explanation of working and issue:
I have already said that there are many matix of Imageview such as 2*2/3*3/4*4..... So when we start Application first load 2*2 matrix of imageview and when we click the odd colored imageview it goes to 3*3 matrix but when we click other than odd colored imageviewthen it goes to next level say 3*3.So when app start first time when I click on odd colored imageview it goes to 3*3 matrix but when return again on 2*2 after clicking other than odd colored imageview.and then again when we click on colored imageview it not get correct image id. and if any other query plz ask?
How to resolve this issue ?
When ImageView changes it's position, their id should go with that position. But ImageView id remains at same position.
That's because you are using Animation, which in fact doesn't change your View's position. What is does it makes an illusion of animation, so it only changes that view's matrix, but doesn't perform layout changes to the view.
Use Animator API instead of Animation.
Update
Given this animation xml:
<set xmlns:android="schemas.android.com/apk/res/android">
<rotate
android:fromDegrees="0"
android:toDegrees="90"
android:pivotX="50%"
android:pivotY="50%"
android:duration="2000" />
</set>
This can be substituted with following:
ObjectAnimator rotateAnimator = ObjectAnimator.ofFloat(yourView, View.ROTATION, 0, 90);
rotateAnimator.setDuration(2000);
rotateAnimator.start();
Update:
Just set rotation zero at every load of view (or layout) like this:
mylayoutname.setRotation(0);
Because after rotation it doesn't go to zero degree automatically until activity stops.
Maybe instead of using rotation you can store the Ids of the ImageViews in a List or Array and the Id of the currently colored ImageView in a separated variable, and when you have to rotate instead you can simply select one random ImageView from the List/Array (excluding the currently colored one), remove the color from the previous one and color the new one.
By the way, when you have 3x3, 5x5, 7x7 etc. layouts is the middle ImageView never colored? 'Cause in those cases a rotation wouldn't change anything (visually, at least). I mean, a rotation works for choosing a random square in a layout of 2x2 squares, but not in any other case. Do you need to choose the squares randomly or do they need to always be chosen by a rotation? (I hope what I mean is clear...)
once again a newbie needs an advice from you, gracious stranger.
I have some problems that, even after googling them, couldn´t been solved.
I have 2 Stages in my game with a Table in each one that hold Buttons:
The first one stores a Table with ingame buttons : move up/down and pause
the second one stores a Table that represents the pause menu.
if "pause" is clicked (the game pauses and) I want to draw the second stage that now can process input.
I initialized 2 stages:
public void create(){
...
mainStage = new Stage(viewport,batch);
menuStage = new Stage(viewport,batch);
Gdx.input.setInputProcessor(mainStage);
...
the pause Button got an Listener that sets the (enum) STATE to PAUSE
(same for the "resume" Button in the pause menu, that sets the state to RUNNING)
pause.addListener(new ChangeListener() {
#Override
public void changed(ChangeEvent event, Actor actor) {
thisState = STATE.PAUSE;
Gdx.input.setInputProzessor(menuStage);
}
});
then in the render method
switch (gameState) {
case RUNNING:
deltaTime = Gdx.graphics.getDeltaTime();
stateTime += deltaTime; // for the animations
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
batch.setProjectionMatrix(camera.combined);
update(deltaTime);
batch.begin();
... draws the characters
batch.end();
mainStage.act(deltaTime);
mainStage.draw();
break;
case PAUSE:
Gdx.gl.glClearColor(0, 0, 0, 0.6f); I want the background to become slightly darker.
Gdx.app.log("Game State","Game is PAUSED");
menuStage.act(deltaTime);
menuStage.draw();
}
If I start the mainStage Buttons appear, but arent clickable.
What I have noticed is that the game stops if I click in the middle of the screen. Howeverm the "pause" Button´s Listener apparantly doesnt even react to that as there was no notfication on the console, that the game is paused, nor that the Button was clicked.
My Start Screen uses only one Stage and works perfectly with the same setup.
What I think the resons might be:
I used setInputProcessor falsely
I used Viewport falsely (and resize)
I have to somehow let the first stage disappear before drawing a new stage
Help is appreciated a lot! Thank you.
sry for my bad english
.. and for my formating (this is my first Post here)
by your code, gdx is only processing inputs for mainStage, you could swap input processors when showing the menu or use a input multiplexer like this:
public void create(){
[...]
mainStage = new Stage(viewport,batch);
menuStage = new Stage(viewport,batch);
InputMultiplexer multiplexer = new InputMultiplexer();
multiplexer.addProcessor(mainStage);
multiplexer.addProcessor(menuStage);
Gdx.input.setInputProcessor(multiplexer);
[...]
}
I'm attempting to "animate" a die roll in Java. I currently have an icon (called "diceImage") set up that, when a button is clicked (called "diceRoll"), updates to a new random image of a die face. What I would like to do is have it change image (to a random die face) numerous times over a couple of seconds before stopping on a final image.
The problem I have is not with generating a random number, or rolling it numerous times, it's with the updating the image numerous times within a loop. The code below, which rolls the die 10 times is what I have so far:
private void diceRollActionPerformed(java.awt.event.ActionEvent evt) {
for (int i = 1; i <= 10; i++) {
rollDice();
pause(100);
}
}
This links to the following two methods (the first of which generates the random number, and sets the icon image):
private void rollDice() {
Random r = new Random();
int randomNumber = r.nextInt(6) + 1;
diceImage.setIcon(new javax.swing.ImageIcon(getClass().getResource("/Game/Images/Dice " + randomNumber + ".png")));
}
The method below is "supposed" to pause the programme briefly between updating the image (this was taken from a programming course I was on where we had to animate an image of a car moving across the screen):
private void pause(int sleepTime) {
try {
Thread.sleep(sleepTime);
} catch (InterruptedException e) {
System.exit(-1);
}
}
All this programme seems to do is pause and then print the final dice roll. It doesn't show any of the "intermediate" faces. Does anyone have any ideas on why this isn't working?
Any help is greatly appreciated.
This question is asked several times a day. If you sleep in the event dispatch thread, you're preventing it from doing its job: react to events and repaint the screen.
Your animation should be done in another thread. Read the tutorial about concurrency in Swing, and use a Swing Timer.
The pause() you are using is when u need to animate moving stuff like a car for example , but just changing the icon of a JLabel which is the dice here doesn't need pause ( unless you just want it to be delayed a bit) ...
but anyways , to solve your issue , you need to call repaint() on that JLabel or updateGraphics(). Setting the Icon for the JLabel doesn't make the new Icon get displayed , you just need to repaint() it .
of course like JB Nizet said , for the app not to hang you need to call repaint on a new Thread .Thought you have to learn how to use Thread well cuz it can be very tricky at times .
good luck
I'm trying to animate UI elements. I would like to move an editText and a Button from the middle to the top of the screen and display results of an http call below them in a table. It would be great if anyone could point me in the right direction, at this point I don't know wether I should use Java or XML for this.
Thanks in advance.
Use Translation framework to achieve this, this works as:
TranslateAnimation(float fromXDelta, float toXDelta, float fromYDelta, float toYDelta)
So you need to write your code for moving view in y-axis direction, as follows:
mAnimation = new TranslateAnimation(0, 0, 0, 599);
mAnimation.setDuration(10000);
mAnimation.setFillAfter(true);
mAnimation.setRepeatCount(-1);
mAnimation.setRepeatMode(Animation.REVERSE);
view.setAnimation(mAnimation);
Here view may be anything, textview, imageView etc.
accepted answer caused an error inside my code, code snippet below almost identical to accepted answer & worked without causing errors, to slide an object off the screen. i needed gestures tied to keyPad to also 'slide away' , and switched from TranslateAnimation to ObjectAnimator (second block of code below).
final LinearLayout keyPad = (LinearLayout)findViewById(R.id.keyPad);
moveKeyPadUp(keyPad);
private void moveKeyPadUp(LinearLayout keyPad){
Animation animation = new TranslateAnimation(0,0,0,-500);
animation.setDuration(1000);
animation.setFillAfter(true);
keyPad.startAnimation(animation);
}
private void moveKeyPadUpdated(LinearLayout keyPad){
ObjectAnimator mover = ObjectAnimator.ofFloat(keyPad,"translationY",0,-500);
mover.setDuration(300);
mover.start();
}