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 点击效果动画增强》
private void animateClickView(final View v, final ClickAnimation callback)
ok,这样就完成基本功能。赶紧运行看下效果吧。
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();
}
完整版的多路翻转动画实现效果: