android 翻转动画实现
自己的前几篇文章基本都是简单的把动画实现,能够看看效果。这次带来的翻转动画自然少不了的显示动画效果。
但这次多了实用性、可扩展性的考虑,把翻转动画不仅仅是针对个别iew的动画效果,而是一个可以翻转的layout,并实现接口flipable,具备一定的封装性;方便在添加其它控件,具备一定的扩展性,在例子中,也示例性地改变翻转内容,把layout中默认的textview 改为 由代码填充的imageView。能够在实际代码中使用。
1. 翻转动画的基本实现:
首先,翻转自然需要两个界面,可以是view 也可以是layout ;
然后,使用android的属性动画,rotationX,创建两个动画,分别是为翻转出现/翻转消失。
ObjectAnimator visToInvis = ObjectAnimator.ofFloat(visibleLayout, "rotationX", 0f, 90f); ObjectAnimator invisToVis = ObjectAnimator.ofFloat(invisibleLayout, "rotationX", -90f, 0f);接着,设置在一个动画结束的时候让另一个动画播放,并调用播放,就可以看到效果了。
visToInvis.addListener(new AnimatorListenerAdapter() { public void onAnimationEnd(Animator anim) { visibleLayout.setVisibility(View.GONE); invisToVis.start(); invisibleLayout.setVisibility(View.VISIBLE); } }); visToInvis.start();最后,把这些放到一个函数里,在点击事件里调用,就完成了。
2. 可翻转layout的实现, FlipableLayout 的实现。
首先,设计接口Flipable
public interface Flipable { public void flip(); }然后,设计布局文件flipable_relativelayout.xml,这里面的textview是为了演示设置的默认布局。
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content" > <LinearLayout android:id="@+id/front" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@color/blue" android:orientation="vertical" > <TextView android:id="@+id/text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="visible text" android:textSize="20sp" /> </LinearLayout> <LinearLayout android:id="@+id/back" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@color/yellow" android:orientation="vertical" android:visibility="gone" > <TextView android:id="@+id/text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="invisible text" android:textSize="20sp" /> </LinearLayout> </RelativeLayout>
然后,自定义layout,并添加构造函数,加载布局文件。
public class FlipableRelativeLayout extends RelativeLayout implements Flipable { private LinearLayout mFontLayout; private LinearLayout mBackLayout; public FlipableRelativeLayout(Context context) { super(context, null); inflate(getContext(), R.layout.flipable_relativelayout, this); } public FlipableRelativeLayout(Context context, AttributeSet attrs) { super(context, attrs); inflate(getContext(), R.layout.flipable_relativelayout, this); } public FlipableRelativeLayout(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); inflate(getContext(), R.layout.flipable_relativelayout, this); } @Override protected void onFinishInflate() { super.onFinishInflate(); mFontLayout = (LinearLayout) findViewById(R.id.front); mBackLayout = (LinearLayout) findViewById(R.id.back); }增加set方法,方便扩展
protected void setFront(View v) { mFontLayout.removeAllViews(); mFontLayout.addView(v); invalidate(); } protected void setBack(View v) { mBackLayout.removeAllViews(); mBackLayout.addView(v); invalidate(); }增加flip 方法,实现翻转动画。
@Override public void flip() { // 上文中提到的实现 }
3. 设计演示布局文件,multiple_flip_example.xml
引用刚刚写好的FlipableRelativeLayout
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" > <Button android:id="@+id/button_flip" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="to flip" android:textSize="20sp" /> <Button android:id="@+id/button_change" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="change" android:textSize="20sp" /> </LinearLayout> <com.buptfarmer.devapp.FlipableRelativeLayout android:id="@+id/flip" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </LinearLayout>
初始化布局,
private void initView() { setContentView(R.layout.multiple_flip_example); mFlipButton = (Button) findViewById(R.id.button_flip); mFlipButton.setOnClickListener(this); mChangeButton = (Button) findViewById(R.id.button_change); mChangeButton.setOnClickListener(this); mFlipLayout = (FlipableRelativeLayout) findViewById(R.id.flip); }
设置点击事件,点击flip button 是直接翻转, 点击change button ,修改翻转内容,变为图片。
@Override public void onClick(View v) { animateClickView(v, new ClickAnimation() { @Override public void onClick(View v) { if (v == mFlipButton) { mFlipLayout.flip(); } else if (v == mChangeButton) { ImageView front = new ImageView(getApplicationContext()); front.setImageResource(R.drawable.avatar); front.setVisibility(View.VISIBLE); ImageView back = new ImageView(getApplicationContext()); back.setImageResource(R.drawable.chobber); back.setVisibility(View.VISIBLE); mFlipLayout.setFront(front); mFlipLayout.setBack(back); mFlipLayout.flip(); } } }); }
animateClick 是使用前文中写的点击动画,具体实现参见:《android 点击效果动画增强》http://blog.csdn.net/farmer_cc/article/details/18551657
private void animateClickView(final View v, final ClickAnimation callback)
ok,这样就完成基本功能。赶紧运行看下效果吧。
http://v.youku.com/v_show/id_XNjY0NDA2MDI4.html
4. 实现多路依次翻转
在上述功能实现的基础上,继续加工。实现多个翻转组件的顺序的翻转动画。
增加fliplayout 的getAnimator 方法,和createFlipAnimator方法。
private Animator createFlipAnimator() { //创建过程如上文所示 return mVisToInvis; } public Animator getFlipAnimator() { return createFlipAnimator(); }在example 中增加动画列表
private ArrayList<Animator> mFlipList = new ArrayList<Animator>();并实现获取所有布局flip动画的方法, 通过遍历布局中所有的child,并判断是否是FlipableRelativeLayout ,加入到列表中。
private void collectFlipAnim() { mFlipList.clear(); traversalCollectFlip(mMainLayout); } private void traversalCollectFlip(ViewGroup parent){ if(parent==null){ return; } if(parent.getChildCount()==0 ){ return; } for (int index = 0; index < parent.getChildCount(); index++) { if (parent.getChildAt(index) instanceof FlipableRelativeLayout) { mFlipList.add(((FlipableRelativeLayout) (parent.getChildAt(index))).getFlipAnimator()); continue; } try{ traversalCollectFlip((ViewGroup) parent.getChildAt(index)); }catch(ClassCastException e){ // not a ViewGroup, continue } } }
在点击事件中调用即可。
private void flipAll() { collectFlipAnim(); AnimatorSet animSet = new AnimatorSet(); animSet.playSequentially(mFlipList); animSet.start(); }
完整版的多路翻转动画实现效果:
android 翻转动画完整版 http://v.youku.com/v_show/id_XNjY0NDgwODM2.html