某天看到京東商城首頁的滑動廣告的banner,在流動切換的時候有立體的動畫效果,感覺很有意思,然後研究了下如何實作.
廢話不多說,接下來我會講述如何實作這種效果,以及如何根據需求自定義出新的動畫效果進行擴充實作.
首先還是看一下京東商城上的效果:
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIml2ZuETM5YzX4kDNyYTOygzMx8CX4IzLcBTMzEDMy8CXzRWYvxGc19CX0Vmbu4GZzNmL51mLn1Wavw1LcpDc0RHaiojIsJye.gif)
像一般做這種效果怎麼辦呢?我的建議還是先在github或者google code上搜尋開源庫. 一來開源庫一般做得比較成熟,api封裝得較好,耦合性比較低. 二來項目比較利于維護.
(并不是說全自己實作的就不好,畢竟每個人實作的思路并不一樣,相對于開源庫來說,閱讀别人的曆史代碼就相對比較麻煩,有bug或者有新需求的話,會很影響開發的效率)
下面還是直接上項目, 如上所示的效果已經有開源庫的實作,而且還有很多其他動畫補間效果:
jazzviewpager簡介:
該項目是基于viewpager的一個重寫,讓我們看一下自帶的demo項目結構:
這裡我們可以看到,viewpager的動畫效果由nineoldandroids這個開源項目實作:
github位址:
<a target="_blank" href="https://github.com/jakewharton/nineoldandroids"> https://github.com/jakewharton/nineoldandroids</a>
該動畫庫将android3.0以上版本api實作的動畫做了重寫,可以相容到3.0以下的版本
jazzyviewpager的內建:
接下來我們看一下如何将該開源庫內建到自己的項目中:
1.布局檔案中遵照自定義控件的寫法即可:
<com.jfeinstein.jazzyviewpager.jazzyviewpager
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/jazzy_pager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
2.設定viewpager的動畫效果:
這裡首先介紹一下目前已經封裝好的效果:
jazzyviewpager中的的枚舉類:
public enum transitioneffect {
standard,
tablet,
cubein,
cubeout,
flipvertical,
fliphorizontal,
stack,
zoomin,
zoomout,
rotateup,
rotatedown,
accordion
}
怎麼設定呢?非常簡單:
private jazzyviewpager mjazzy;
/* ... */
mjazzy.settransitioneffect(transitioneffect.*);
在京東商城使用的效果即為transitioneffect.cubeout
這裡我們還可以看一下其他的效果
transitioneffect.tablet
transitioneffect.stack
其他效果大家可以自己嘗試下.
3.內建該開源庫需要注意一些事項<code>:</code>
當viewpager中的子view超過三個的時候,我們需要對<code>pageradapter修改,重寫instantiateitem()方法,,會導緻補間動畫不能正常顯示.</code>
<code>ex:</code>
<code></code>
@override
public object instantiateitem(viewgroup container, final int position) {
object obj = super.instantiateitem(container, position);
mjazzy.setobjectforposition(obj, position);
return obj;
}
jazzyviewpager的修改:
如果大家還是嫌目前已經封裝的效果還是不滿意怎麼辦?項目有其他動畫實作的需求怎麼辦?這裡順便講下如何擴充該開源庫:(紅色部分為需要添加修改的代碼)
1.在枚舉類中添加所需的動畫效果,這裡以test代替.
accordion,
<span style="color:#ff0000;">test</span>
}
2.增加動畫效果的具體實作:
protected void animatetest(view left, view right, float positionoffset) {
if (mstate != state.idle) {
if (left != null) {
//此處增加具體動畫
if (right != null) {
//此處增加具體動畫實作
3.在onpagescrolled的方法中,增加對應效果的處理:
public void onpagescrolled(int position, float positionoffset, int positionoffsetpixels) {
if (mstate == state.idle && positionoffset > 0) {
oldpage = getcurrentitem();
mstate = position == oldpage ? state.going_right : state.going_left;
boolean goingright = position == oldpage;
if (mstate == state.going_right && !goingright)
mstate = state.going_left;
else if (mstate == state.going_left && goingright)
mstate = state.going_right;
float effectoffset = issmall(positionoffset) ? 0 : positionoffset;
// mleft = getchildat(position);
// mright = getchildat(position+1);
mleft = findviewfromobject(position);
mright = findviewfromobject(position+1);
if (mfadeenabled)
animatefade(mleft, mright, effectoffset);
if (moutlineenabled)
animateoutline(mleft, mright);
switch (meffect) {
case standard:
break;
case tablet:
animatetablet(mleft, mright, effectoffset);
case cubein:
animatecube(mleft, mright, effectoffset, true);
case cubeout:
animatecube(mleft, mright, effectoffset, false);
case flipvertical:
animateflipvertical(mleft, mright, positionoffset, positionoffsetpixels);
case fliphorizontal:
animatefliphorizontal(mleft, mright, effectoffset, positionoffsetpixels);
case stack:
animatestack(mleft, mright, effectoffset, positionoffsetpixels);
case zoomin:
animatezoom(mleft, mright, effectoffset, true);
case zoomout:
animatezoom(mleft, mright, effectoffset, false);
case rotateup:
animaterotate(mleft, mright, effectoffset, true);
case rotatedown:
animaterotate(mleft, mright, effectoffset, false);
case accordion:
animateaccordion(mleft, mright, effectoffset);
<span style="color:#ff0000;">case</span> <span style="color:#ff0000;">test: </span><span class="nf">
<span style="color:#ff0000;"> animatetest</span></span><span style="color:#ff0000;"><span class="o"></span>(mleft, mright, effectoffset);
</span> }
super.onpagescrolled(position, positionoffset, positionoffsetpixels);
if (effectoffset == 0) {
disablehardwarelayer();
mstate = state.idle;
經過這三步,我們就可以添加具有新的補間動畫的viewpager. 這裡大家可以盡情發揮自己的創意,不斷地擴充該開源庫,實作自己想要的效果.