I have xxx of type ImageView. If I click it, the event handler animate will be triggered to animate it.
public void animate(View view) {
ImageView xxx= findViewById(R.id.xxx);
xxx.animate().rotation(7200f).setDuration(3000);
}
It works only for the first click but for the subsequent clicks the animation does not work.
Question
How to fix this issue?
Keep in mind that rotation sets the rotation value to the provided float.
You are probably looking for rotationBy if you want to always rotate by that value
Related
In my project I have an expandable recycler view. Almost everything is working properly.
When I expand the view I have a chevron, that I want to perform a 180º rotation and vice versa for the collapsing animation.
I'm using this function to do the rotation view.animate().rotation(180f) for one of the states and for the other I pass 0 to the rotation function.
The icon is rotated the first time with the animation. My problem now is that, the second time I call submitList(List<UIModel>) it doesn't perform the animation itself, but the icon blinks into the 180º state.
One important note is that I'm using MVI, and I added a click listener to the ViewHolder, which is simply a callback for the Fragment, that will pass this info to the ViewModel. The ViewModel will update its state to have that list item as expanded and then submit the list.
Rotation animation works perfectly, if I call the function mentioned above right in the click listener, without calling the submitList() function.
As a summary, this is flow (first time 8th step doesn't apply, and it works properly with the animation):
User clicks on chevron;
callback is called;
fragment notifies view model;
view model updates state;
fragment is notified that there are changes;
fragment submits list calling (submitList());
onBindViewHolder is called, and I perform the rotation animation according to the UIModel isExpanded variable.
rotation is applied, but without any animation, just a flick between both position
Two wild guesses:
Is the rotation value part of the DiffUtil.Callback? (the value or something to indicate that the item changed).
Did you try for the sake of Android to replace view.animate().rotation(180f) with something more silly like:
view.post( ... )
This would perform your animation inside the next rendering frame; I have a suspicion the animation is getting buried there and the final state is shown (the thing rotated already).
I was creating animation between 2 Scenes using TransitionManager.go(Scene,Transition) and everything worked just fine but after the animation finished I was no longer capable of clicking on the button which was moved from the center of the screen to the left side.
Looking around the Internet I found that this animation actually doesn't even move the Views, just animates them so I have to update their positions to new ones.
Isn't there any better way to do this than manually .setLayoutParams for all the Views in the Scene?
I realized that my Views actually were in the right positions after the animation but I had to reset my OnClickListeners every time Scenes changed
Transition.TransitionListener listener = new Transition.TransitionListener() {
#Override
public void onTransitionEnd(Transition transition) {
//get view references from the new Scene and
//reassign on click listeners to them
}
}
I just assigned this listener to my Transition and everything worked fine.
Here is the post that helped me see my mistake.
In my custom View, I'm drawing a rectangle with an alpha of 0. I want that when the user clicks a button, the alpha would change to 100 and redraw. When the mouse button is depressed, alpha should reset to 0. From what I can see, it is not redrawn as 0, but rather on every click it adds 100 without ever going to 0.
if(transparentRightClick){
gameBasePaint.setAlpha(0);
}
else{
gameBasePaint.setAlpha(clickRightColor);
}
nextClicked = new RectF(displayWidth*0.8f,displayWidth*0.91f,displayWidth*1f,displayWidth*1.35f);
gameBaseCanvas.drawRect(nextClicked,gameBasePaint);
This is in the 'onDraw' method. When he clicks the button, the 'if'statement is set to false and 'clickRightColor' changes dynamically (0-100) to give an animation effect. When the mouse button is depressed, the 'if' is set to true again, and it should be redrawn to nothing. Calling invalidate after every action.
My problem turned out to be that the 'gameBaseCanvas' wasn't being reinitialized in the onDraw method so it kept on adding to it and never removing the previous drawings.
I'm developing a game Android app and I have a HorizontalScrollView that is being populated with ImageViews. Each ImageView is clickable to select the level you want to play. I'm using a SavedPreference to keep track of the last played level, and using that to determine which image is on screen when you load the menu. That way, if you're on level 30, you don't have to scroll all the way from level 1 every time.
I'm using a requestFocus() to bring that ImageView onto the screen, and it works fine, except for two relatively minor (but annoying) issues.
Here is what I'm doing in my for loop that populates the { HorizontalScrollView`:
final ImageView iv = new ImageView(LevelSelect.this);
iv.setImageResource(levelImages[i]);
iv.setFocusable(true);
iv.setFocusableInTouchMode(true);
iv.setId(i);
LinearLayout ll= (LinearLayout)findViewById(R.id.levelSelectGallery);
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(300, LinearLayout.LayoutParams.MATCH_PARENT);
and I make it clickable:
String str = getString(R.string.level) + i + getString(R.string.avail);
if (storage.getBoolean(str,false)) { //check if level is available (unlocked)
iv.setClickable(true);
final int finalI = i;
iv.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
editor.putInt(getString(R.string.Current_Level_savepreferences), finalI); //set current level to clicked image
Intent intent = new Intent(LevelSelect.this, LevelStart.class);
LevelSelect.this.startActivity(intent); // begin LevelStart activity
}
});
} else {
iv.setImageResource(lockedImages[i]); // show locked image
}
and outside the loop, I set the focus:
//check if there is a saved level
focusLevel = storage.getInt(getString(R.string.Saved_Level), 5);
//set focus on saved level
findViewById(focusLevel).requestFocus();
This brings the focused item onto the screen, but just at the edge. I would prefer it to be centered if possible. I can live with that though. The main issue is that it seems that by setting the focus, it's now requiring two presses on the image to trigger the onClickListener. I assume the first press is changing the focus and the second is clicking. If I remove the focus related code, it only requires one press.
Is there a better way to scroll the view to the desired image, or something different I should be doing with the focusing?
Why don't you just put focusLevel inside the onClickListener? That way tapping the image focuses it automatically.
So, I haven't found a way around the double press issue when the item is focused, but I did discover a different solution that works for my situation. Instead of using the HorizontalScrollView with a LinearLayout, I've now implemented a ViewPager which centers my ImageViews for me, and also allows me to scroll to an item programatically using setCurrentItem(). I don't have to use focusing at all.
For anyone looking to do the same, Philipp's example here helped me a lot: How to implement a ViewPager with different Fragments / Layouts
I can't provide the code for the moment I'll update the question in the nearest future, but I'll explain the situation and you can tell me what to check first of all.
I have a Gallery with a set of ImageViews.
When ImageView is selected, view.startAnimation(grow); is cast. Everything works perfect.
Then I tap (onTouchEvent starts another animation on the unselected view: view.startAnimation(decrease);)
Everything works fine on the first element.
But when I choose the next imageview, grow animation works fine aswell, but decrease animation works on both of the imageViews. So it seems that startAnimation method runs the animation on all the imageViews that were choosen previously.
I had no luck finding the same question on stackoverflow. Will be very appreciate if you give me some ideas.
It may help someone.
Finally I've found the solution.
I have 2 methods:
animationShow(View view) {
View.startAnimation(animationShow);
}
and
animationHide(View view) {
View.startAnimation(animationHide);
}
I also have 2 views to work with: currently selected view (selectedView) and previously selected view (prevView), so I hide animation on prevView and show it on selectedView.
To avoid gallery issue with hiding animation, I changed animationShow() method:
animationShow(View view) {
View.startAnimation(animationShow);
if (prevView != null) {
prevView.cancelAnimation();
}
}
When new item is selected (and old item was hidden) I just cancel all the animations on the prevView. It helped me. Hope it will help someone else.