I'm messing with PropertyAnimations
. For this I have a simple (but verbose) setup to play around with. There are two Views
which switch position on y-Axis
by button click. While this translation, one View will get smaller the other one bigger by scaling the Views.
OK this works! But I discovered a really strange behaviour which surprises me. If I add a additional View
in the layout where the other two View
already are, the animation will change it's behavior!
There will be no normal y-Axis
translation anymore, the animation will now translate the Views
in a circle, means in x-Axis
too. And I would like to know why is adding a simple View changing the whole animation?
I think I can't describe it better, so here is my complete setup to reproduce the problem. Just remove the View with the height of 1dp after your first button press and you will see.
This is my layout with the Views:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.example.inputtest.MainActivity$PlaceholderFragment" >
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:orientation="vertical">
<TextView
android:id="@+id/origin"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="20dp"
android:paddingRight="20dp"
android:text="FOO"/>
<View
android:layout_width="wrap_content"
android:layout_height="1dp"
android:layout_marginTop="20dp"
android:layout_marginBottom="20dp"
android:background="#000000"/>
<TextView
android:id="@+id/destination"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="20dp"
android:paddingRight="20dp"
android:text="BAR"/>
</LinearLayout>
<Button
android:id="@+id/switcher"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="Switch"/>
</LinearLayout>
This is the basic start Activity:
public class MainActivity extends ActionBarActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.add(R.id.container, new PlaceholderFragment()).commit();
}
}
public static class PlaceholderFragment extends Fragment {
public PlaceholderFragment() {}
TextView foo;
TextView bar;
@Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container,
false);
foo = (TextView)rootView.findViewById(R.id.origin);
bar = (TextView)rootView.findViewById(R.id.destination);
Button btn = (Button)rootView.findViewById(R.id.switcher);
btn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
AnimatorSet scale1 = null;
AnimatorSet scale2 = null;
ObjectAnimator translate1 = null;
ObjectAnimator translate2 = null;
if (foo.getTranslationY() == 0) {
translate1 = ObjectAnimator.ofFloat(foo, "translationY", bar.getTop());
translate2 = ObjectAnimator.ofFloat(bar, "translationY", bar.getTop()*(-1));
scale1 = (AnimatorSet)AnimatorInflater.loadAnimator(getActivity(), R.animator.scaler);
scale2 = (AnimatorSet)AnimatorInflater.loadAnimator(getActivity(), R.animator.scaler2);
} else {
translate1 = ObjectAnimator.ofFloat(foo, "translationY", 0);
translate2 = ObjectAnimator.ofFloat(bar, "translationY", 0);
scale1 = (AnimatorSet)AnimatorInflater.loadAnimator(getActivity(), R.animator.scaler2);
scale2 = (AnimatorSet)AnimatorInflater.loadAnimator(getActivity(), R.animator.scaler);
}
translate1.setDuration(500L);
translate2.setDuration(500L);
scale1.setTarget(foo);
scale2.setTarget(bar);
AnimatorSet set = new AnimatorSet();
set.playTogether(scale1, scale2, translate1, translate2);
set.start();
}
});
return rootView;
}
}
}
The scaler.xml for the Animation:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:ordering="sequentially">
<set
android:ordering="together">
<objectAnimator
android:propertyName="scaleX"
android:duration="250"
android:valueTo="2.0"/>
<objectAnimator
android:propertyName="scaleY"
android:duration="250"
android:valueTo="2.0"/>
</set>
<set
android:ordering="together">
<objectAnimator
android:propertyName="scaleX"
android:duration="250"
android:valueTo="1.0"/>
<objectAnimator
android:propertyName="scaleY"
android:duration="250"
android:valueTo="1.0"/>
</set>
</set>
The scaler2.xml for the Animation:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:ordering="sequentially">
<set
android:ordering="together">
<objectAnimator
android:propertyName="scaleX"
android:duration="250"
android:valueTo="0.5"/>
<objectAnimator
android:propertyName="scaleY"
android:duration="250"
android:valueTo="0.5"/>
</set>
<set
android:ordering="together">
<objectAnimator
android:propertyName="scaleX"
android:duration="250"
android:valueTo="1.0"/>
<objectAnimator
android:propertyName="scaleY"
android:duration="250"
android:valueTo="1.0"/>
</set>
</set>