亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

巧用ViewPager 打造不一樣的廣告輪播切換效果

2019-11-09 14:03:12
字體:
來源:轉載
供稿:網友

一、概述

如果大家關注了我的微信公眾號的話,一定知道我在5月6號的時候推送了一篇文章,文章名為Android超高仿QQ附近的人搜索展示(一),通過該文可以利用ViewPager實現單頁顯示多個Item且能夠添加一些炫酷的動畫效果。我當時閱讀這篇文章的時候,簡單做了下記錄,然后想了想,可以按照該思路做一個比較特殊輪播效果,如圖:

其實看到這個大家肯定不陌生,對于ViewPager切換有個很出名的庫叫JazzViewPager,沒錯,我又跑了下JazzyViewPager的例子,看看有什么動畫效果可以借鑒的,ok,最終呢,產生以下幾個效果圖。

貼效果圖前,簡單說下我的公眾號,恩,我是在上周決定正式開始好好打理的,目前很多東西都在嘗試階段,當然支持大家的投稿,目前存在一些文章過長,或者代碼過長的排版問題,不過都在嘗試改善與解決,以及對推送文章的選材都在考慮,所以多謝大家的支持,也歡迎大家的關注(二維碼在側欄),相信我一定會做的更好。

此外,針對不好閱讀的問題,大家可以通過該倉庫,看到所有推送文章的一個列表,https://github.com/hongyangAndroid/hongyangWeixinArticles該倉庫會和公眾號推送的文章同步更新。

下面進入正題,本文主要是利用ViewPager做類似上圖風格的Banner,這種Banner在app上不是很常見,不過在web端還有tv的app上還是很常見的。

不過原理很簡單,說到核心,就兩個地方:

android:clipChildren="false"viewPager.setPageTransformer

很久之前也寫過類似的文章,可以參考

Android 自定義 ViewPager 打造千變萬化的圖片切換效果Android 實現個性的ViewPager切換動畫 實戰PageTransformer(兼容Android3.0以下)

二、效果圖

Rotate Down

Rotate Up

ScaleIn

貼三個意思下,恩,更多效果見https://github.com/hongyangAndroid/MagicViewPager.

三、ViewPager一屏顯示多個頁面

ok,首先說明下控件,上述效果采用的控件是ViewPager,大家都清楚哇,使用ViewPager一般我們都是一屏幕顯示一個頁面,那么如何做到一屏顯示多個頁面呢?

ViewPager如何做到一屏顯示多個頁面呢?

原理就一個屬性Android:clipChildren="false",該屬性的意思就是在子View進行繪制時不要去裁切它們的顯示范圍。ok,知道要使用這個屬性之后,剩下的事情就不麻煩了:

我們的布局文件這么寫:

<FrameLayout android:layout_width="match_parent" android:layout_height="160dp" android:clipChildren="false" android:layout_centerInParent="true" android:background="#aadc71ff" > <android.support.v4.view.ViewPager android:id="@+id/id_viewpager" android:layout_width="match_parent" android:layout_marginLeft="60dp" android:layout_marginRight="60dp" android:clipChildren="false" android:layout_height="120dp" android:layout_gravity="center" > </android.support.v4.view.ViewPager></FrameLayout>1234567891011121314151617181912345678910111213141516171819

我們設置了ViewPager外層控件以及ViewPager都設置了android:clipChildren="false"。

我們的ViewPager的寬度是match_parent,左后個設置了60dp的邊距,就是為了顯示出左右部分的Page.

接下來可以對ViewPager設置Adapter等相關屬性。

public class MainActivity extends AppCompatActivity{ PRivate ViewPager mViewPager; private PagerAdapter mAdapter; int[] imgRes = {R.drawable.a, R.drawable.b, R.drawable.c...}; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mViewPager = (ViewPager) findViewById(R.id.id_viewpager); //設置Page間間距 mViewPager.setPageMargin(20); //設置緩存的頁面數量 mViewPager.setOffscreenPageLimit(3); mViewPager.setAdapter(mAdapter = new PagerAdapter() { @Override public Object instantiateItem(ViewGroup container, int position) { ImageView view = new ImageView(MainActivity.this); view.setImageResource(imgRes[position]); container.addView(view); return view; } @Override public void destroyItem(ViewGroup container, int position, Object object) { container.removeView((View) object); } @Override public int getCount() { return imgRes.length; } @Override public boolean isViewFromObject(View view, Object o) { return view == o; } }); }12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849501234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950

ok,沒有任何復雜的地方,注意

//設置Page間間距mViewPager.setPageMargin(20);1212

以及

//設置緩存的頁面數量 mViewPager.setOffscreenPageLimit(3);1212

我們這里最多可見就是3頁。

此時運行:

可以看到,我們已經實現了單屏幕顯示出多個page,而且是ViewPager所以肯定可以左右滑動。

這么看,是不是非常簡單,接下來就是加特效了,大家都清楚對于ViewPager可以通過設置PageTransformer來利用屬性動畫來設置特效,注意目前該方法添加的動畫在3.0即以上的手機中有效,因為3.0以下并不存在屬性動畫,所以setPageTransformer內部加了個判斷,不過現在已經幾乎沒有3.0以下的手機了,但是如果你非要較真,參考文章開始時給出的兩篇文章,里面有解決方案。

四、給ViewPager加特效

這里我們簡單抽取兩個動畫效果來講,其實以前的文章里面也有詳細的描述,所以不準備花費太多的時間描述。

(1) AlphaPageTransformer

首先講個最簡單的動畫,叫AlphaPageTransformer,顧名思義就是一個漸變的變化,那么我們的步驟是這樣的:

實現AlphaPageTransformer implements ViewPager.PageTransformer調用viewPager.setPageTransformer(new AlphaPageTransformer())

對于ViewPager.PageTransformer就一個方法需要實現

#AlphaPageTransformerprivate static final float DEFAULT_MIN_ALPHA = 0.5f;private float mMinAlpha = DEFAULT_MIN_ALPHA;public void pageTransform(View view, float position){ if (position < -1) { view.setAlpha(mMinAlpha); } else if (position <= 1) { // [-1,1] if (position < 0) //[0,-1] { float factor = mMinAlpha + (1 - mMinAlpha) * (1 + position); view.setAlpha(factor); } else//[1,0] { float factor = mMinAlpha + (1 - mMinAlpha) * (1 - position); view.setAlpha(factor); } } else { // (1,+Infinity] view.setAlpha(mMinAlpha); }}1234567891011121314151617181920212223242526272812345678910111213141516171819202122232425262728

代碼非常簡短,簡單的介紹下,可以看到postion主要分為

[-Infinity,-1)(1,+Infinity][-1,1]

這三個區間,對于前兩個,拿我們的頁面上目前顯示的3個Page來說,前兩個分別對應左右兩個露出一點的Page,那么對于alpha值,只需要設置為最小值即可。

對于[-1,1],這個就需要詳細分析了,我們這里拿:第一頁->第二頁這個過程來說,主要看position的變化

第1頁->第2頁

頁1的postion變化為:從0到-1頁2的postion變化為:從1到0

第一頁到第二頁,實際上就是左滑,第一頁到左邊,第二頁成為currentItem到達中間,那么對應alpha的變化應該是:

頁1到左邊,對應alpha應該是:1到minAlpha頁2到中間,成為currentItem,對應alpha應該是:minAlpha到1

分析到這就是寫代碼了:

對于頁1

//注意該代碼判斷在(position <= 1)的條件內if (position < 0) //[0,-1]{ float factor = mMinAlpha + (1 - mMinAlpha) * (1 + position); view.setAlpha(factor);} 123456123456

position是0到-1的變化

那么1+position就是從1到0的變化

(1 - mMinAlpha) * (1 + position)就是1 - mMinAlpha到0的變化

再加上一個mMinAlpha,就變為1到mMinAlpha的變化。

其實繞來繞去就是為了實現factor是1到minAlpha的變化,具體這樣的算式,每個人的思路可能不同,但是達到相同的效果即可。

同理,頁2是minAlpha到1的變化。

對應算式(postion為1到0變化)

float factor = mMinAlpha + (1 - mMinAlpha) * (1 - position);11

這個留給大家自己算,或者自己去總結出一個相同結果的算式。

ok,當我們完成AlphaPageTransformer的編碼,然后ViewPager設置后,效果就是這樣的:

(2) RotateDownPageTransformer

再介紹個RotateDownPageTransformer,因為這個涉及到旋轉中心的變化,即:

view.setPivotX();view.setPivotY();1212

直接看代碼:

private static final float DEFAULT_MAX_ROTATE = 15.0f;private float mMaxRotate = DEFAULT_MAX_ROTATE;public void pageTransform(View view, float position){ if (position < -1) { // [-Infinity,-1) // This page is way off-screen to the left. view.setRotation(mMaxRotate * -1); view.setPivotX(view.getWidth()); view.setPivotY(view.getHeight()); } else if (position <= 1) { // [-1,1] if (position < 0)//[0,-1] { view.setPivotX(view.getWidth() * (0.5f + 0.5f * (-position))); view.setPivotY(view.getHeight()); view.setRotation(mMaxRotate * position); } else//[1,0] { view.setPivotX(view.getWidth() * 0.5f * (1 - position)); view.setPivotY(view.getHeight()); view.setRotation(mMaxRotate * position); } } else { // (1,+Infinity] // This page is way off-screen to the right. view.setRotation(mMaxRotate); view.setPivotX(view.getWidth() * 0); view.setPivotY(view.getHeight()); }}12345678910111213141516171819202122232425262728293031323334351234567891011121314151617181920212223242526272829303132333435

經過上面的分析,我們直接鎖定到第一頁到第二頁時,第一頁的相關變化的代碼:

if (position < 0)//[0,-1]{ float factor = view.getWidth() * (0.5f + 0.5f * (-position)); view.setPivotX(factor); view.setPivotY(view.getHeight()); view.setRotation(mMaxRotate * position);} 12345671234567

第一頁開始時滑動時,旋轉中心上圖原點,即(width/2 , height).

第一頁滑動結束時,旋轉中心在左邊頁面的右下角,即(width,height).

恩,這個旋轉中心的位置是我自己定義的,不一定是最好的效果,如果有必要大家可以自己選擇,保證良好的顯示效果。

可以看到旋轉中心的縱坐標沒有發生變化,主要看橫坐標

float factor = view.getWidth() * (0.5f + 0.5f * (-position));11

position為0到-1,乘以-0.5之后,變為0到0.5

在加上0.5,變為0.5到1的變化

再乘以width,即變為width/2到width的變化。

對應我們的旋轉中心x是需要從width/2到width,是不是剛好匹配。

旋轉中心的變化說明白了;再簡單說下,角度的變化,第一頁到達左邊頁面的狀態,角度是-15度,開始狀態是0度,那么變化就是0到-15度之間,因為position是0到-1之間變化,所以直接乘以15即可

float rotation = position * 15f 11

好了,經過上面的分析,本文就基本結束了,有興趣可以下載源碼多分析幾個,或者創造幾個動畫效果,千萬不要忘了告訴我,我可以加入到這個動畫庫中。

五、總結

本文的內容其實涉及到的API實際上比較多,再多的動畫其實質性的原理都是一樣的,關鍵在于找規律,所以帶大家梳理一下步驟:

確定View需要變化的屬性確定該屬性的初始值,終值確定該View對應的position變化的梯度根據position的變化梯度,計算出需要變化的屬性的變化梯度剩下的就是調用屬性動畫的API了

ok,相信通過該步驟大家一定能夠自己去定義出形態各異的動畫,此外,切記如果學習,一定要嘗試編寫,看一看就認為了解的,可能有些坑是發現不了的。

源碼地址:https://github.com/hongyangAndroid/MagicViewPager


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
亚洲国产成人精品电影| 日韩福利在线播放| 国产精品一区二区三区在线播放| 欧美野外猛男的大粗鳮| 亚洲国产成人精品电影| 欧美激情亚洲视频| 97高清免费视频| 国产精品美女久久久久久免费| 狠狠躁夜夜躁久久躁别揉| 亚洲欧美另类自拍| 欧美在线观看网站| 色偷偷偷亚洲综合网另类| 一区二区三区四区在线观看视频| 黑人巨大精品欧美一区二区免费| 国产精品福利无圣光在线一区| 97视频在线播放| 欧美极品美女电影一区| 国产精品丝袜视频| 国产精品视频一区二区高潮| yw.139尤物在线精品视频| 久久久久久久亚洲精品| 中日韩美女免费视频网址在线观看| 91久久精品久久国产性色也91| 国产精品成人免费电影| 伊人久久五月天| 国产精品日韩在线播放| 国产精品久久久久久av福利软件| 日韩在线视频网站| 日韩在线视频观看正片免费网站| 国产精品欧美激情在线播放| 国产精品国语对白| 欧美精品在线网站| 日韩电影中文字幕一区| 欧美老少做受xxxx高潮| 久久国产精品久久国产精品| 亚洲韩国欧洲国产日产av| 在线精品高清中文字幕| 国产在线日韩在线| 91国在线精品国内播放| 尤物精品国产第一福利三区| 欧美成人精品在线| zzjj国产精品一区二区| 欧美一级大片在线免费观看| 日本三级韩国三级久久| 国产主播精品在线| 欧美中文在线字幕| 亚洲偷欧美偷国内偷| 欧美中文字幕在线视频| 国产91精品久久久久久久| 久久久www成人免费精品张筱雨| 这里只有精品在线观看| 国产成人+综合亚洲+天堂| 日韩中文字幕精品| 午夜精品一区二区三区视频免费看| 亚洲综合中文字幕在线| 九九精品在线观看| 久久99久久99精品中文字幕| 精品呦交小u女在线| 亚洲免费伊人电影在线观看av| 亚洲激情在线观看视频免费| 亚洲一区二区在线| 国产精品久久久久91| 亚洲欧美综合另类中字| 亚洲最新av在线网站| 欧美日韩在线视频首页| 欧美日韩国产999| 久久99精品久久久久久青青91| 亚洲国产另类 国产精品国产免费| 国产欧美日韩视频| 中日韩美女免费视频网站在线观看| 中日韩午夜理伦电影免费| 日韩高清欧美高清| 欧美刺激性大交免费视频| 国产69精品99久久久久久宅男| 亚洲欧美另类在线观看| 91精品国产九九九久久久亚洲| 欧美精品久久久久久久免费观看| 91综合免费在线| 日韩精品在线视频| 成人黄色在线免费| www.欧美精品| www.亚洲免费视频| 亚洲另类激情图| 色狠狠av一区二区三区香蕉蜜桃| 91欧美精品成人综合在线观看| 国产精品精品久久久久久| 欧美做受高潮1| 性色av香蕉一区二区| 日韩精品小视频| 美女久久久久久久| 亚洲性视频网址| 亚洲人成电影网站色| 国内精品免费午夜毛片| 久久五月情影视| 亚洲理论片在线观看| 91免费视频网站| 中文字幕精品一区久久久久| 68精品久久久久久欧美| 2019中文字幕在线免费观看| 久久天天躁狠狠躁夜夜爽蜜月| 亚洲最大福利网| 欧美日韩国产成人高清视频| 欧美色道久久88综合亚洲精品| 人妖精品videosex性欧美| 97国产一区二区精品久久呦| 91av免费观看91av精品在线| 狠狠躁夜夜躁人人躁婷婷91| 成人久久一区二区| 日韩在线观看免费全| 色综合视频一区中文字幕| 日韩欧美aⅴ综合网站发布| 韩国美女主播一区| 国产精品一区二区三| 国产精品91免费在线| 久久这里只有精品视频首页| 日本精品免费观看| 日韩高清有码在线| 日韩精品中文字幕在线| 国产精品91在线| 亚洲精品久久久久中文字幕欢迎你| 在线观看日韩欧美| 成人做爽爽免费视频| 欧美午夜激情小视频| 国产精品久久久999| 亚洲社区在线观看| 国产精品青青在线观看爽香蕉| 中文字幕精品在线| 91色在线视频| 久久久亚洲国产天美传媒修理工| 国产亚洲欧洲黄色| 98午夜经典影视| 亚洲国产天堂网精品网站| 亚洲第一av网站| 中文字幕在线日韩| 91成品人片a无限观看| 欧美亚洲国产日本| 亚洲免费一级电影| 欧美福利视频在线| www.亚洲天堂| 精品国产91久久久| 国产精品∨欧美精品v日韩精品| 午夜精品一区二区三区视频免费看| 在线视频亚洲欧美| 最近中文字幕mv在线一区二区三区四区| 欧美性猛交xxx| 欧美另类极品videosbest最新版本| 色狠狠av一区二区三区香蕉蜜桃| 欧美激情视频网站| 亚洲精品永久免费精品| 秋霞午夜一区二区| 精品性高朝久久久久久久| 国产精品av在线| 国产欧美韩国高清| 日韩国产欧美精品一区二区三区| 91啪国产在线| 色偷偷综合社区| 91禁国产网站| 精品视频在线播放免| 日韩中文字幕欧美| 国产精品免费久久久久久| 亚洲性69xxxbbb| 国产自产女人91一区在线观看| 97在线视频免费| 国产精品88a∨|