上一篇文章我們簡單分析實現了Yalantis公司的SliderMenu,這次我們還是來寫寫它家的另一個動畫
ContextMenu
github地址:https://github.com/Yalantis/Context-Menu.Android
效果如下
話不多說,同樣我們來簡單分析下
- 首先還是2個動畫集合 :顯示動畫集合和隱藏動畫集合
- 顯示動畫裏面有2種動畫,一種是第一個沿Y軸打開,第二種其他的沿X軸打開
- 隱藏動畫裏面比較特別,要觀察仔細就可以發現裏面有三種不同的動畫,第一種前半部分是沿X軸向下收,第二種就是中間那個(也就是點擊的那個)沿Y軸向裏收,第三種下半部分是沿X軸向上收,和上半部分相反,還有一個重要的是上半部分和下半部分是同時播放 播放完後再執行中間那個
額 大家看明白了麼 要多看幾遍 仔細觀察分析 複雜的動畫其實都是由簡單的動畫組成的,不要被嚇倒。
ok ,開始動手了,佈局爲了簡單還是沿用上一篇文章的佈局 如下
好的開始寫各個不同的動畫了
首先我們來寫顯示動畫集合裏面的2種動畫
//Y show 打開-第一個
private ObjectAnimator createFlipYShowAnim(final View target) {
target.setPivotX(0);
target.setPivotY(target.getHeight() / 2);
ObjectAnimator invisToVis = ObjectAnimator.ofFloat(target, "rotationY", 90f, 0f);
invisToVis.setDuration(DURATION);
invisToVis.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
super.onAnimationStart(animation);
target.setVisibility(View.VISIBLE);
}
});
return invisToVis;
}
//x show 打開-下半部(第一個之外的)
private ObjectAnimator createFlipXShowAnim(final View target) {
target.setPivotX(target.getWidth() / 2);
target.setPivotY(0);
ObjectAnimator invisToVis = ObjectAnimator.ofFloat(target, "rotationX", -90f, 0f);
invisToVis.setDuration(DURATION);
invisToVis.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
super.onAnimationStart(animation);
target.setVisibility(View.VISIBLE);
}
});
return invisToVis;
}
再來寫隱藏的三種動畫
//x hidden before 隱藏-上半部
private ObjectAnimator createFlipXBeforeHiddenAnim(final View target, int i) {
target.setPivotX(target.getWidth() / 2);
target.setPivotY(target.getHeight());
ObjectAnimator visToInvis = ObjectAnimator.ofFloat(target, "rotationX", 0f, 90f);
if (i == 0) {
visToInvis.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
//播放完後恢復位置
target.setVisibility(View.INVISIBLE);
target.setPivotX(target.getWidth() / 2);
target.setPivotY(target.getHeight());
ObjectAnimator openAnim = ObjectAnimator.ofFloat(target, "rotationX", 90f, 0f);
openAnim.start();
}
});
}
visToInvis.setDuration(DURATION);
return visToInvis;
}
//Y hidden 隱藏-中間(點擊部分)
private ObjectAnimator createFlipYHiddenAnim(final View target) {
target.setPivotX(0);
target.setPivotY(target.getHeight() / 2);
ObjectAnimator visToInvis = ObjectAnimator.ofFloat(target, "rotationY", 0f, 90f);
visToInvis.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
target.setVisibility(View.INVISIBLE);
target.setPivotX(0);
target.setPivotY(target.getHeight() / 2);
ObjectAnimator openAnim = ObjectAnimator.ofFloat(target, "rotationY", 90f, 0f);
openAnim.start();
}
});
visToInvis.setDuration(DURATION);
return visToInvis;
}
//x hidden after 隱藏-下半部
private ObjectAnimator createFlipXAfterHiddenAnim(View target) {
target.setPivotX(target.getWidth() / 2);
target.setPivotY(0);
ObjectAnimator visToInvis = ObjectAnimator.ofFloat(target, "rotationX", 0f, -90f);
visToInvis.setDuration(DURATION);
return visToInvis;
}
註釋都加上了 沒有什麼特別的地方
現在我們開始把它們加到動畫集合裏面
顯示動畫集合
private AnimatorSet initShowAnim(ViewGroup parent) {
ArrayList<Animator> visAnimList = new ArrayList<Animator>();
for (int i = 0; i < parent.getChildCount(); i++) {
ObjectAnimator itemAnim = null;
if (i == 0) {//第一個動畫
itemAnim = createFlipYShowAnim(parent.getChildAt(i));
} else {
itemAnim = createFlipXShowAnim(parent.getChildAt(i));
}
visAnimList.add(itemAnim);
}
AnimatorSet anim = new AnimatorSet();
anim.playSequentially(visAnimList);
return anim;
}
隱藏動畫
隱藏動畫稍微多點 因爲它有多種動畫 代碼裏面的MIDDLE我們假定爲3 就是點擊的哪個按鈕位置
private Animator initHiddenAnim(ViewGroup parent) {
AnimatorSet beforAnim = new AnimatorSet();
AnimatorSet middleAnim = new AnimatorSet();
AnimatorSet afterAnim = new AnimatorSet();
ArrayList<Animator> beforeAnimList = new ArrayList<Animator>();
ArrayList<Animator> middleAnimList = new ArrayList<Animator>();
ArrayList<Animator> afterAnimList = new ArrayList<Animator>();
for (int i = 0; i < parent.getChildCount(); i++) {
if (i < MIDDLE) {
ObjectAnimator itemAnim = createFlipXBeforeHiddenAnim(parent.getChildAt(i), i);
beforeAnimList.add(itemAnim);
} else if (i > MIDDLE) {
ObjectAnimator itemAnim = createFlipXAfterHiddenAnim(parent.getChildAt(i));
afterAnimList.add(itemAnim);
} else {
ObjectAnimator itemAnim = createFlipYHiddenAnim(parent.getChildAt(i));
middleAnimList.add(itemAnim);
}
}
beforAnim.playSequentially(beforeAnimList);
middleAnim.playSequentially(middleAnimList);
Collections.reverse(afterAnimList);
afterAnim.playSequentially(afterAnimList);
AnimatorSet anim = new AnimatorSet();
anim.play(beforAnim).with(afterAnim).before(middleAnim);
return anim;
}
點擊執行直接調用上面的方法了
initShowAnim(parent).start();//顯示動畫執行
initHiddenAnim(parent).start();//隱藏動畫執行
爲了理解簡單 上面的代碼並沒有嚴格規範和優化,大家根據自己習慣自行調整了
ok 我們看一下最後的效果了 ( ps:錄屏真是挺麻煩的 不知道有什麼簡單好用工具推薦)