Transition animator works in Activity but not fragment - android

I've been trying to follow the android flip card tutorial. As instructed, I created four custom animator sets
card_flip_right_in.xml:
<set xmlns:android="http://schemas.android.com/apk/res/android">
<objectAnimator
android:valueFrom="1.0"
android:valueTo="0.0"
android:propertyName="alpha"
android:duration="0" />
<objectAnimator
android:valueFrom="180"
android:valueTo="0"
android:propertyName="rotationY"
android:interpolator="#android:interpolator/accelerate_decelerate"
android:duration="300" />
<objectAnimator
android:valueFrom="0.0"
android:valueTo="1.0"
android:propertyName="alpha"
android:startOffset="150"
android:duration="1" />
</set>
card_flip_right_out.xml:
<set xmlns:android="http://schemas.android.com/apk/res/android">
<objectAnimator
android:valueFrom="0"
android:valueTo="-180"
android:propertyName="rotationY"
android:interpolator="#android:interpolator/accelerate_decelerate"
android:duration="300" />
<objectAnimator
android:valueFrom="1.0"
android:valueTo="0.0"
android:propertyName="alpha"
android:startOffset="150"
android:duration="1" />
</set>
card_flip_left_in.xml:
<set xmlns:android="http://schemas.android.com/apk/res/android">
<objectAnimator
android:valueFrom="1.0"
android:valueTo="0.0"
android:propertyName="alpha"
android:duration="0" />
<objectAnimator
android:valueFrom="-180"
android:valueTo="0"
android:propertyName="rotationY"
android:interpolator="#android:interpolator/accelerate_decelerate"
android:duration="300" />
<objectAnimator
android:valueFrom="0.0"
android:valueTo="1.0"
android:propertyName="alpha"
android:startOffset="150"
android:duration="1" />
</set>
card_flip_left_out.xml:
<set xmlns:android="http://schemas.android.com/apk/res/android">
<objectAnimator
android:valueFrom="0"
android:valueTo="180"
android:propertyName="rotationY"
android:interpolator="#android:interpolator/accelerate_decelerate"
android:duration="300" />
<objectAnimator
android:valueFrom="1.0"
android:valueTo="0.0"
android:propertyName="alpha"
android:startOffset="150"
android:duration="1" />
</set>
And, I have this in my fragment:
public class ContestantInfoFragment extends Fragment {
private Context context;
private String cName, cCountry, cDesc;
private TextView contestant_name, contestant_country, contestant_desc;
private ImageButton flip_btn;
public ContestantInfoFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_contestant_info, container, false);
context = inflater.getContext();
Bundle bundle = this.getArguments();
if(bundle != null) {
cName = bundle.getString("NAME", "Problem loading contestant's name");
cCountry = bundle.getString("COUNTRY", "Problem loading contestant's country");
cDesc = bundle.getString("DESC", "Problem loading contestant's description");
contestant_name = (TextView) v.findViewById(R.id.contestant_name);
contestant_country = (TextView) v.findViewById(R.id.contestant_country);
contestant_desc = (TextView) v.findViewById(R.id.contestant_desc);
contestant_name.setText(cName);
contestant_country.setText(cCountry);
contestant_desc.setText(cDesc);
}
flip_btn = (ImageButton) v.findViewById(R.id.contestant_flip_btn);
flip_btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
getActivity().getSupportFragmentManager()
.beginTransaction()
.setCustomAnimations(R.animator.card_flip_right_in, R.animator.card_flip_right_out,
R.animator.card_flip_left_in, R.animator.card_flip_left_out)
.replace(R.id.mainContent, new ContestantsFragment())
.addToBackStack(null)
.commit();
}
});
return v;
}
}
However, I got syntax errors (red zip lines) for using
.setCustomAnimations(R.animator.card_flip_right_in, R.animator.card_flip_right_out,
R.animator.card_flip_left_in, R.animator.card_flip_left_out)
The feedback I got was "Expected resource of type anim"
I did realize if I did inside of an activity, the error warning would go away, but not when I implement in a fragment.
Anyone has any idea why this is not working? And how do I make it work in a fragment?

Related

What's the difference between AnimatorSet's and Object/ValueAnimator's duration?

I have a AnimatorSet with couple of ObjectAnimators. I can not see the difference between their duration time. Can anyone explain this to me?
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:ordering="together">
<objectAnimator
android:propertyName="translationY"
android:duration="1000"
android:interpolator="#android:interpolator/bounce"
android:repeatCount="3"
android:valueFrom="0.0"
android:valueTo="-600.0"
android:repeatMode="reverse"
android:valueType="floatType"/>
<objectAnimator
android:propertyName="alpha"
android:duration="1000"
android:interpolator="#android:interpolator/linear"
android:repeatCount="3"
android:valueFrom="1.0"
android:valueTo="0.0"
android:repeatMode="reverse"
android:valueType="floatType"
/>
</set>
val rocketAnimatorSet = AnimatorInflater.loadAnimator(this, R.animator.jump_and_blink) as AnimatorSet
val dogeAnimatorSet = AnimatorInflater.loadAnimator(this, R.animator.jump_and_blink) as AnimatorSet
rocketAnimatorSet.setTarget(rocket)
dogeAnimatorSet.setTarget(doge)
val animatorSet = AnimatorSet()
animatorSet.playTogether(rocketAnimatorSet, dogeAnimatorSet)
animatorSet.duration =9000L
animatorSet.start()

Rotation is working while translation is not working at same time in android

First of all, please don't declare it as duplicate because i have been spending time on stackoverflow since last five days and i have read a lot of answers but still not able to achieve this.
I want card flip animation in my application. I tried https://developer.android.com/training/animation/cardflip.html also but exit animation is not being played there for me.
So i used two frame layouts for two fragments in a Linear Layout and then tried to rotate and translate first frame layout towards left out of screen while rotating and translating next frame layout in from right.First frame is rotating as required but translation is not there.
Please help to make frame layout translate also with rotation so that next fragment could enter the screen.
My code is:
activity_card.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.Toolbar
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/toolbar"
android:background="#color/colorPrimary"
>
</android.support.v7.widget.Toolbar>
<LinearLayout
android:layout_height="match_parent"
android:layout_width="match_parent"
android:orientation="horizontal"
>
<FrameLayout
android:id="#+id/frame_layout1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:animateLayoutChanges="true"
>
</FrameLayout>
<FrameLayout
android:id="#+id/frame_layout2"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:animateLayoutChanges="true"
>
</FrameLayout>
</LinearLayout>
</LinearLayout>
card_flip_left_out.xml:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Rotate. -->
<objectAnimator
android:valueFrom="0"
android:valueTo="180"
android:propertyName="rotationY"
android:interpolator="#android:interpolator/accelerate_decelerate"
android:startOffset="0"
android:duration="1000" />
<!-- Half-way through the rotation (see startOffset), set the alpha to 0. -->
<objectAnimator
android:valueFrom="1.0"
android:valueTo="0.0"
android:propertyName="alpha"
android:startOffset="0"
android:duration="800" />
<objectAnimator
android:propertyName="translationX"
android:valueTo="-200"
android:interpolator="#android:interpolator/accelerate_decelerate"
android:startOffset="0"
android:duration="1000"
/>
</set>
card_flip_right_in.xml:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Before rotating, immediately set the alpha to 0. -->
<objectAnimator
android:valueFrom="1.0"
android:valueTo="0.0"
android:propertyName="alpha"
android:duration="0" />
<!-- Rotate. -->
<objectAnimator
android:valueFrom="180"
android:valueTo="0"
android:propertyName="rotationY"
android:interpolator="#android:interpolator/accelerate_decelerate"
android:duration="1000" />
<!-- Half-way through the rotation (see startOffset), set the alpha to 1. -->
<objectAnimator
android:valueFrom="0.0"
android:valueTo="1.0"
android:propertyName="alpha"
android:startOffset="0"
android:duration="800" />
<objectAnimator
android:propertyName="translationX"
android:valueTo="0"
android:interpolator="#android:interpolator/accelerate_decelerate"
android:startOffset="0"
android:duration="1000"
/>
</set>
CardActivity.java:
public class CardActivity extends AppCompatActivity implements
Toolbar.OnMenuItemClickListener {
FragmentTransaction fragmentTransaction;
FrameLayout layout1, layout2;
String visibleFragment;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_card);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
toolbar.setTitle("Digital card");
toolbar.setTitleTextColor(Color.WHITE);
toolbar.inflateMenu(R.menu.menu);
toolbar.setOnMenuItemClickListener(this);
layout1 = (FrameLayout) findViewById(R.id.frame_layout1);
layout2 = (FrameLayout) findViewById(R.id.frame_layout2);
fragmentTransaction = getFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.frame_layout1, GeneralDetailsFragment.newInstance());
fragmentTransaction.replace(R.id.frame_layout2, AddMoreDetailsFragment.newInstance());
visibleFragment = "layout1";
fragmentTransaction.commit();
}
#Override
public boolean onMenuItemClick(MenuItem item) {
Animator anim1 = AnimatorInflater.loadAnimator(this,R.animator.card_flip_left_out);
Animator anim2 = AnimatorInflater.loadAnimator(this,R.animator.card_flip_right_in);
if(visibleFragment.equals("layout2"))
{
anim1.setTarget(layout2);
anim2.setTarget(layout1);
anim1.start();
anim2.start();
visibleFragment = "layout1";
}
else
{
anim1.setTarget(layout1);
anim2.setTarget(layout2);
anim1.start();
anim2.start();
visibleFragment = "layout2";
}
return true;
}
}
Try this way:
below is xml file for animation (left to right with rotation) and start animation on view. And make changes as per you need.
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="#android:anim/linear_interpolator">
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="500"
android:fromDegrees="0"
android:pivotX="50%"
android:pivotY="50%"
android:repeatCount="5"
android:toDegrees="359" />
<translate
xmlns:android="http://schemas.android.com/apk/res/android"
android:fromXDelta="0%p" //For Y - android:fromYDelta="0%p" also -value
android:toXDelta="100%p" //For Y - android:toYDelta="50%p"
android:repeatCount="0"
android:duration="3000">
</translate>
</set>
Hope this will help you.
I found a different and pretty simple way to achieve card flip animation here . This animation is not for replacing or adding fragment using FragmentTransaction but for two frame layouts which already contain corresponding Fragment.
Sample code is:
public void flip(final View front, final View back, final int duration) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
AnimatorSet set = new AnimatorSet();
set.playSequentially(
ObjectAnimator.ofFloat(front, "rotationY", 90).setDuration(duration / 2),
ObjectAnimator.ofInt(front, "visibility", View.GONE).setDuration(0),
ObjectAnimator.ofFloat(back, "rotationY", -90).setDuration(0),
ObjectAnimator.ofInt(back, "visibility", View.VISIBLE).setDuration(0),
ObjectAnimator.ofFloat(back, "rotationY", 0).setDuration(duration / 2)
);
set.start();
}
else {
front.animate().rotationY(90).setDuration(duration / 2).setListener(new AnimatorListenerAdapter() {
#Override
public void onAnimationEnd(Animator animation) {
front.setVisibility(View.GONE);
back.setRotationY(-90);
back.setVisibility(View.VISIBLE);
back.animate().rotationY(0).setDuration(duration / 2).setListener(null);
}
});
}
}

finish Animation on Back Button Pressed

I am working on Fragments translate animation by following link :
http://trickyandroid.com/fragments-translate-animation/
But i want to start slide down animation by pressing back button rather finishing slide up animation by pressing Action bar button .
Slide_down.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<objectAnimator
android:interpolator="#android:anim/accelerate_decelerate_interpolator"
android:propertyName="yFraction"
android:valueType="floatType"
android:valueFrom="0.58"
android:valueTo="1.0"
android:duration="#android:integer/config_mediumAnimTime"/>
<objectAnimator
android:interpolator="#android:anim/accelerate_decelerate_interpolator"
android:propertyName="alpha"
android:valueType="floatType"
android:valueFrom="1"
android:valueTo="0"
android:duration="#android:integer/config_mediumAnimTime"/>
</set>
Slide.up.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<objectAnimator
android:interpolator="#android:anim/accelerate_decelerate_interpolator"
android:propertyName="yFraction"
android:valueType="floatType"
android:valueFrom="1.0"
android:valueTo="0.58"
android:duration="#android:integer/config_mediumAnimTime"/>
<objectAnimator
android:interpolator="#android:anim/accelerate_decelerate_interpolator"
android:propertyName="alpha"
android:valueType="floatType"
android:valueFrom="0.58"
android:valueTo="1.0"
android:duration="#android:integer/config_mediumAnimTime"/>
</set>
Code for Animation in Main Activity:
Fragment f = getFragmentManager().findFragmentByTag(LIST_FRAGMENT_TAG);
if (f != null) {
getFragmentManager().popBackStack();
} else {
getFragmentManager().beginTransaction()
.setCustomAnimations(R.anim.slide_up,
R.anim.slide_down,
R.anim.slide_up,
R.anim.slide_down)
.add(R.id.list_fragment_container, SlidingListFragment
.instantiate(this, SlidingListFragment.class.getName()),
LIST_FRAGMENT_TAG
)
.addToBackStack(null) .commit();
googleMap.getUiSettings().setAllGesturesEnabled(false);
}
}
Please help me to increase my knowledge regarding this .
Handler can be used as a lightweight timer. The key is animation will be clear as soon as activity start performing a finish, so you have to delay the finish in order to see the animation completely.
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
MainActivity.super.onBackPressed();
}
}, getResources().getInteger(android.R.integer.config_mediumAnimTime));

Difficulty reversing fragment animation with backstack

I am currently trying to implement a custom animation when changing fragments.
The custom animation only works one way and does not work when back is pressed. On back press the correct fragment is shown but with no animation.
My code for the fragment transaction:
FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.setCustomAnimations(R.anim.slide_in_left, R.anim.slide_out_right, R.anim.slide_in_right, R.anim.slide_out_left);
transaction.replace(R.id.frame_container, fragment, FragmentTag);
transaction.addToBackStack(null);
transaction.commit();
My code for the anim XML files:
//Slide in left
<?xml version="1.0" encoding="utf-8"?>
<set>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:propertyName="x"
android:valueType="floatType"
android:valueFrom="-1280"
android:valueTo="0"
android:duration="500"/>
</set>
//Slide out right
<?xml version="1.0" encoding="utf-8"?>
<set>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:propertyName="x"
android:valueType="floatType"
android:valueFrom="0"
android:valueTo="-1280"
android:duration="500"/>
</set>
//Slide in Right
<?xml version="1.0" encoding="utf-8"?>
<set>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:propertyName="x"
android:valueType="floatType"
android:valueFrom="-1280"
android:valueTo="0"
android:duration="500"/>
</set>
//Slide out Left
<?xml version="1.0" encoding="utf-8"?>
<set>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:propertyName="x"
android:valueType="floatType"
android:valueFrom="0"
android:valueTo="-1280"
android:duration="500"/>
</set>
The code for onBackPressed()
#Override
public void onBackPressed()
{
super.onBackPressed();
}
Any ideas where I'm going wrong? Thanks for any help
Use this code for onBackPressed:
if (getFragmentManager().getBackStackEntryCount() > 0) {
getFragmentManager().popBackStack();
} else {
super.onBackPressed();
}

How to add animation to DialogFragment?

How can I add animation to DialogFragment. My animations are:
out anim:
<scale
android:duration="200"
android:fillAfter="false"
android:fromXScale="1.0"
android:fromYScale="1.0"
android:interpolator="#android:anim/linear_interpolator"
android:pivotX="50%"
android:pivotY="-90%"
android:startOffset="200"
android:toXScale="0.5"
android:toYScale="0.5" />
<translate
android:duration="300"
android:fromXDelta="0"
android:fromYDelta="0"
android:toXDelta="-200"
android:toYDelta="-200" />
in anim:
<scale
android:duration="200"
android:fillAfter="false"
android:fromXScale="0.5"
android:fromYScale="0.5"
android:interpolator="#android:anim/linear_interpolator"
android:pivotX="50%"
android:pivotY="-90%"
android:toXScale="1.0"
android:toYScale="1.0" />
<translate
android:duration="300"
android:fromXDelta="-200"
android:fromYDelta="-200"
android:toXDelta="0"
android:toYDelta="0" />
and my code:
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.setCustomAnimations(R.anim.jump_in, R.anim.jump_out, R.anim.jump_in, R.anim.jump_out);
ft.add(layer_frag, "layer frag");
ft.show(layer_frag).commit();//layer_frag is a class whitch extends DialogFragment
I must miss something because it appears as it appears before.
#Override
public Dialog onCreateDialog(Bundle savedInstanceState)
{
final Dialog dialog = super.onCreateDialog(savedInstanceState);
dialog.getWindow().getAttributes().windowAnimations = R.style.detailDialogAnimation;
return dialog;
}
The answer was from stackoverflow.com/a/13537234/969325 but You have to set the style at onCreateDialog function.

Categories

Resources