I have an ImageButton in my fragment which has its background set to an android drawable icon. In some cases that button needs to be rotated (this works). My problem is that when I come back to the fragment after being in another activity then I want the button to be "reset" to its original position.
Here is how the button is set:
#Override
public void onViewCreated(final View view, Bundle savedInstanceState) {
button = (ImageButton)view.findViewById(R.id.doButtonThing);
button.setOnClickListener(this);
if (condition) {
button.animate().rotation(90f).setInterpolator(new AccelerateDecelerateInterpolator());
}
}
I have tried using:
button.clearAnimation();
button.invalidate();
button.postInvalidate();
inside the onResume() method but none of them work. How can I reset/reload the original button?
The code of clearAnimation()
/**
* Cancels any animations for this view.
*/
public void clearAnimation() {
if (mCurrentAnimation != null) {
mCurrentAnimation.detach();
}
mCurrentAnimation = null;
invalidateParentIfNeeded();
}
which gives me the impression that it clears a currently running animation (Although I'm not sure). Instead of button.clearAnimation();, you can use button.animate().rotation(0.0f); to reverse-rotate the button.
Also instead of onResume(), I suggest you to call the function later on, maybe onStop(). In the lifecycle, onResume() comes after onViewCreated(final View view, Bundle savedInstanceState), calling it in onResume() would invalidate your animation.
Related
I'm using a SharedElementTransition when opening a new Activity. The shared element is in a RecyclerView in ActivityA (starting Activity), and also in a RecyclerView in a Fragment in ActivityB (new Activity). The animation works mostly as expected, except that the shared element is also visible in its final position throughout the animation, which looks pretty terrible.
My ActivityB.onCreate() looks like this:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
<snip>
if (Utils.hasLollipop()) {
postponeEnterTransition();
}
}
In the ViewHolder.onBindViewHolder() for the holder that contains the image I'm using as a shared element, I call this after loading the image data into the view (in a Picasso callback):
#TargetApi(Build.VERSION_CODES.LOLLIPOP)
private void triggerTransition() {
if (!hasTriggeredTransition) {
hasTriggeredTransition = true;
sharedElement.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
#Override
public boolean onPreDraw() {
sharedElement.setTransitionName("sharedElement");
sharedElement.getViewTreeObserver().removeOnPreDrawListener(this);
containingFragment.getActivity().startPostponedEnterTransition();
return true;
}
});
}
}
The image transitions from its location in ActivityA to where it should be in ActivityB, but during the animation, it also appears in the final location. How can I hide the final location until the animation is finished?
Update: In an attempt at simplifying, I've removed the image callbacks. Now, I just set the view to a solid background color and immediately calling triggerTransition(), with the same results.
Relatedly, is there a way to slow down the animation for debugging?
You should be able to slow down the animation for debugging purposes by increasing the duration value in your transition xml file like below:
<transitionSet xmlns:android="http://schemas.android.com/apk/res/android"
android:transitionOrdering="together"
android:duration="250">
You can even change the Ordering to "sequencing" to further analyse..
So,
I have an activity with a layout, and in this layout I only have one button.
when clicking this button, the activity sets the visibility of the button to invisible, and launches a popup window.
I implemented a simple onDismiss function in this popup, which sets the button to visible
pw.setOnDismissListener(new PopupWindow.OnDismissListener() {
#Override
public void onDismiss() {
MainActivity.packButton.setVisibility(View.VISIBLE);
}
});
the problem is that sometimes, not very often, after the popup is dismissed, the button is shown, but only the top part of it, something like 1/5 of the button.
I suspected that the button became visible before the popup dismissed completely, and a sort of a clash happened between them, but on the other hand I made some checks and the popup window and the button are able to be shown at the same time without a problem, so a "layout clash" cannot be the reaon, right?
You can add delay and run this method on a handler.
pw.setOnDismissListener(new PopupWindow.OnDismissListener() {
#Override
public void onDismiss() {
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
MainActivity.packButton.setVisibility(View.VISIBLE);
}
}, 1000);
};
});
I would suggest making the button variable non static and instead call a method of your activity from your listener and in this method set the button visibility. Having the button as a static variable could mean that although it is non null the button isn't added to the activities view at the point when you call to set is visibility.
Hi i have two textViews that i initially set its visibility to gone then animate in and become visible. now i want to make the invisible again but for some reason they're still showing on screen does anyone no why?
in my onCreate() i make the view gone
register = (TextView)findViewById(R.id.register);
register.setVisibility(View.GONE);
forgotpassword = (TextView)findViewById(R.id.forgotpw);
forgotpassword.setVisibility(View.GONE);
then later on i make it visible
public void run()
{
animations();
loginForm.setVisibility(View.VISIBLE);
register.setVisibility(View.VISIBLE);
forgotpassword.setVisibility(View.VISIBLE);
}
and then when a user presses a button i want the text views to become invisible so that they retain their layout but they stay visible on screen
signInBtn = (Button) findViewById(R.id.signin);
signInBtn.setOnClickListener(new View.OnClickListener() {
public void onClick(View arg0) {
signInProcess();
}
});
public void signInProcess() {
register.setVisibility(View.INVISIBLE);
forgotpassword.setVisibility(View.INVISIBLE);
setuploader.setVisibility(View.VISIBLE);
}
In Android when you animate something, It's just drawn somewhere else. The actual element is not moved. So when you animate signInBtn it's drawn somewhere else, but the actual button is not moved from the original position. So when you click the button the click handler is not called.
To avoid this set fillAfter = True in your animation so the button will actually get moved at the end of your animation.
Also, after animating a view in Android make sure you call View.clearAnimation() before trying to change its visibility.
How can I make a page flip like animation when moving from one activity to other? On some ios applications I saw this, but when I searched for android I could not find any tutorials or code snippets for this.
Please help
Yes it is possible . Please look at this tutorial.
Here's a tutorial on how to add an animation when transistioning between two activities. However, instead of using a translate animation like in the article, you'll want to use a rotate animation.
The flip animation for Activity doesn't exist on Android..sorry!
Here is demo code from sdk:
/**
* <p>Example of using a custom animation when transitioning between activities.</p>
*/
public class Animation extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_animation);
// Watch for button clicks.
Button button = (Button)findViewById(R.id.fade_animation);
button.setOnClickListener(mFadeListener);
button = (Button)findViewById(R.id.zoom_animation);
button.setOnClickListener(mZoomListener);
}
private OnClickListener mFadeListener = new OnClickListener() {
public void onClick(View v) {
// Request the next activity transition (here starting a new one).
startActivity(new Intent(Animation.this, Controls1.class));
// Supply a custom animation. This one will just fade the new
// activity on top. Note that we need to also supply an animation
// (here just doing nothing for the same amount of time) for the
// old activity to prevent it from going away too soon.
overridePendingTransition(R.anim.fade, R.anim.hold);
}
};
private OnClickListener mZoomListener = new OnClickListener() {
public void onClick(View v) {
// Request the next activity transition (here starting a new one).
startActivity(new Intent(Animation.this, Controls1.class));
// This is a more complicated animation, involving transformations
// on both this (exit) and the new (enter) activity. Note how for
// the duration of the animation we force the exiting activity
// to be Z-ordered on top (even though it really isn't) to achieve
// the effect we want.
overridePendingTransition(R.anim.zoom_enter, R.anim.zoom_exit);
}
};
}
all code is at apidemo/app/ ,:)
I'm still sort of new with Android, so forgive me if it's an obvious mistake. In this activity I'm using ViewPager to horizontally scroll through three layouts containing an ImageButton that has an animated background depending on its current state. When the button is pressed, it starts a new activity. However, when I hit the back button to go back to the activity containing the animation from the new activity, sometimes the animation freezes or plays back faster than it should. I wrote a method for starting up the animation that I use in onWindowFocusChanged(), and onRestart(). I'm working in Android 2.1 (API 7).
This is my code:
public class CopyOfWorld extends Activity{
MediaPlayer muzak;
Boolean mSwitch = false;
ImageButton holmes;
AnimationDrawable holmesAnimation;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.world);
Preferencer pp = (Preferencer)getApplicationContext();
ViewPagerAdapter adapter = new ViewPagerAdapter();
ViewPager myPager = (ViewPager) findViewById(R.id.viewpager);
myPager.setAdapter(adapter);
myPager.setCurrentItem(1);
if(pp.getMuzak()){
mSwitch = true;
muzak = MediaPlayer.create(CopyOfWorld.this, R.raw.level1);
muzak.setLooping(true);
muzak.start();
}
}
public void clicker(View v){
Intent myIntent = new Intent(CopyOfWorld.this , Subworld.class);
startActivityForResult(myIntent, 0);
}
#Override
public void onWindowFocusChanged(boolean hasFocus){
super.onWindowFocusChanged(hasFocus);
beginRender();
}
#Override
protected void onPause(){
super.onPause();
if(mSwitch){
muzak.release();
}
}
#Override
protected void onRestart(){
super.onRestart();
Preferencer pp = (Preferencer)getApplicationContext();
if(pp.getMuzak()){
muzak = MediaPlayer.create(CopyOfWorld.this, R.raw.level1);
muzak.setLooping(true);
muzak.start();
}
beginRender();
}
public void beginRender(){
ImageButton holmes = (ImageButton) findViewById(R.id.subworlder);
StateListDrawable background = (StateListDrawable) holmes.getBackground();
Drawable current = background.getCurrent();
if(current instanceof AnimationDrawable){
holmesAnimation = (AnimationDrawable) current;
holmesAnimation.start();
}
}
}
I've tried calling the method beginRender() under ()onResume, but then the app simply crashes.
Could anyone point me in the right direction?
EDIT:
I've been tweaking the code here and there, unfortunately to no avail. But I did notice a pattern in the behavior of the animation. When I press down on the ImageButton or hold it so that it goes from its default animation to its pressed or focused animation then move my finger away from the button so that it doesn't start up the new activity, it sometimes behaves very much as I described at the beginning of this post (i.e. it's supposed to return to its default animation, but instead plays back at twice the rate, chokes up, or doesn't play at all.)
Currently the xml that contains these ImageButtons defines their backgrounds as the animations and have no source (src). But when I change the background to transparent and the src to the animations, the app crashes.
Any clues?