[Android]使用ViewPager实现图片滑动展示
在淘寶等電商的APP首頁經常能看到大幅的廣告位,通常有多幅經常更新的圖片用于展示促銷信息,如下圖所示:
通常會自動滾動,也可以根據手勢滑動。我沒有研究過人家的APP是通過什么實現的,可能有第三方已經封裝好的控件可以直接使用,也可能通過webview來實現,畢竟在網頁上也有很多類似的內容。如果有高手經驗豐富不妨指點一二。不管別人怎樣,今天我準備自己動手做一個,其實也不是特別復雜的。
?
我主要使用的實現方法是Android自帶的ViewPager控件,這個控件主要用于實現屏幕水平切換,有自帶的動畫效果。Android官網上有使用教程:http://developer.android.com/training/animation/screen-slide.html,當然下文會有相一致的說明。
?
然后就開始動手實現這個圖片滑動效果吧。
1. 首先解釋一下ViewPager的使用過程,通常來說ViewPager可以和Fragment結合起來用,每次ViewPager滑動,也就是展示一個新的Fragment。Fragment里面就是我們需要展現的內容。而這滑動的動畫就交給ViewPager來實現。所以第一步我們需要設置好Fragment的內容,新建一個布局文件,這里只需要展示一張圖即可,當然可以根據自己的需要進行改變:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent" ><ImageViewandroid:id="@+id/iv_main_pic"android:layout_width="match_parent"android:layout_height="match_parent"android:contentDescription="@string/main_image"android:scaleType="fitXY" /></RelativeLayout>?
2. 然后建立Fragment類。
import android.support.v4.app.Fragment; ......public class PictureSlideFragment extends Fragment {@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {View v = inflater.inflate(R.layout.fragment_picture_slide, container, false);return v;}}3. 在Activity布局文件的合適位置加入ViewPager控件。
<android.support.v4.view.ViewPagerandroid:id="@+id/pager"android:layout_width="match_parent"android:layout_height="match_parent" />?
4. 在Activity中得到這個ViewPager并且為其設置Adapter:
private ViewPager mPager;@Override protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);mPager = (ViewPager) findViewById(R.id.pager);mPagerAdapter = new PictureSlidePagerAdapter(getSupportFragmentManager());mPager.setAdapter(mPagerAdapter); }
?
5. 這個Adapter繼承自FragmentStatePagerAdapter,其中getCount()返回的值是一共需要顯示的內容數,是個常數:
private class PictureSlidePagerAdapter extends FragmentStatePagerAdapter {public PictureSlidePagerAdapter(FragmentManager fm) {super(fm);// TODO Auto-generated constructor stub }@Overridepublic Fragment getItem(int arg0) {// TODO Auto-generated method stubreturn new PictureSlideFragment();}@Overridepublic int getCount() {// TODO Auto-generated method stubreturn NUM_PIC;}}?
6. 到目前為止所有的內容都和官方的教程一致。如果你在Fragment中的那個ImageView通過android:src屬性設置圖片,會實現數張靜態圖片滑動的效果。這離我們的目標還有一些區別:
(1)圖片需要能夠動態改變,而不是固定的內容;
(2)每張圖片需要有點擊的響應;
(3)一般情況下需要實現循環滾動,即滑到最后一張圖時繼續滑動會回到第一張圖;
(4)圖片要能夠自動滾動;
(5)圖片下方需要有顯示第幾張圖的指示(小圓點)。
?
7. 接下來我們朝著目標繼續努力。首先是圖片的變化。觀察上述Adapter的實現方法,可以發現getItem()方法每次返回的都是一個Fragment的實例,需要顯示多少個Fragment這個方法就會執行多少遍。但我們發現每次創建新的Fragment都沒有區別,直接new一個了事,因此我們需要改寫這個創建新Fragment實例的方法,以實現每次新建的Fragment實例都不一樣。在我們的Fragment類中補充如下內容:
private int mIndex;public static PictureSlideFragment newInstance(int index) {PictureSlideFragment f = new PictureSlideFragment();Bundle args = new Bundle();args.putInt("index", index);f.setArguments(args);return f;}@Overridepublic void onCreate(Bundle savedInstanceState) {// TODO Auto-generated method stubsuper.onCreate(savedInstanceState);mIndex = getArguments() != null ? getArguments().getInt("index") : 1;}這個叫做newInstance的方法主要功能也是創建一個Fragment實例,和直接new的區別是傳遞進來一個index參數,這個參數在onCreate()方法中被獲得。然后我們將Adapter的getItem()改寫為如下:
@Overridepublic Fragment getItem(int arg0) {// TODO Auto-generated method stubreturn PictureSlideFragment.newInstance(arg0);}每次getItem都將Item的序號傳遞到新建的Fragment,然后再Fragment中根據需要設定不同的內容。真正實現的時候,可以在Fragment中加入從網絡獲取圖片的操作。
?
8. 圖片的點擊響應。這個比較簡單,在Fragment中獲得ImageView控件,然后設置onClick監聽器即可。就不給出代碼了。
9. 圖片的循環滾動。一般的ViewPager不能實現內容的循環滾動,即第一張向左滑或者最后一張向右滑都會到頂,顯示到頂的效果。如果要從ViewPager自身入手加入這功能需要對這個控件進行改寫,比較麻煩,這里我從stackoverflow上找到了一種比較聰明的辦法。
要實現幾張圖的循環滾動,其實只需要滿足視覺效果就可以了。比如有三張圖A,B,C,要實現A->B->C->A->B......以及C->B->A->C->B...這樣的循環,實際上可以這樣實現:
提供5張圖,分別是C'? A? B? C? A',其中C'和C,A'和A完全相同,當滑到C'時,自動切換到C,當滑到A'時,自動切換到A,并且這個切換過程沒有動畫,于是,使用者體驗出來的感覺就是A B C三張圖在循環滾動了。
于是我們為ViewPager添加setOnPageChangeListener方法:
mPager.setOnPageChangeListener(new OnPageChangeListener() {@Overridepublic void onPageSelected(int arg0) {// TODO Auto-generated method stub }@Overridepublic void onPageScrolled(int arg0, float arg1, int arg2) {// TODO Auto-generated method stub }@Overridepublic void onPageScrollStateChanged(int state) {// 當到第一張時切換到倒數第二張,當到最后一張時切換到第二張if (state == ViewPager.SCROLL_STATE_IDLE) {int curr = mPager.getCurrentItem();int lastReal = mPager.getAdapter().getCount() - 2;if (curr == 0) {mPager.setCurrentItem(lastReal, false);} else if (curr > lastReal) {mPager.setCurrentItem(1, false);}}}});覆寫的onPageScrollStateChanged方法在滑動內容改變時調用,在其中實現C'和C,A'和A的切換。
?
10. 圖片的自動滾動,這里我使用了timer啟動線程來實現,定時器線程每隔5秒發送消息,UI線程捕獲消息并調用ViewPager.setCurrentItem(currentItem+1, true)方法,滾動到下一張圖片。代碼就不贅述了。這里有個體驗細節,就是當使用者用手指滑動時,定時器需要取消,防止自動滑動和手指滑動發生沖突。這個我在Fragment的ImageView的onTouchListener中實現:
mMainImage.setOnTouchListener(new OnTouchListener() {@Overridepublic boolean onTouch(View v, MotionEvent event) {if (event.getAction() == MotionEvent.ACTION_DOWN) {((MainActivity)getActivity()).getTimer().cancel();} else if (event.getAction() == MotionEvent.ACTION_CANCEL) {((MainActivity)getActivity()).startSwitchImage();}return false;}});?
?11. 圖片序號的指示,也就是圖片下方的幾個小圓點,這個實現比較簡單,首先在Activity的布局文件中添加幾個圖片,因為這幾個小圓點本身不能隨ViewPager移動,因此不能放在Fragment布局中。切換內容也就是切換顯示不同顏色小圓點的位置,這個方法同樣可以在onPageScrollStateChanged方法中調用。注意一些細節,因為之前為了實現循環滾動而多用了兩個Fragment,而顯示的小圓點數量不能增加,因此需要調整好對應的序號。代碼也不再贅述了。
?
最終的效果如下圖所示,美食有木有。總結一下,整個過程并不復雜,就是一些細節需要仔細推敲。雖然做法可能有非主流的地方,但實現的效果跟別人的幾乎完全一致,這樣就行啦~
另外,這樣的實現方法也不是完全沒有值得改進的地方,比如圖片自動滾動的延時還不能自定義。ViewPager沒有現成的方法用來自改變自動滾動延時,如果需要自定義,就要自己改寫這個控件啦,有興趣的可以研究一下~
?
轉載于:https://www.cnblogs.com/lcyty/p/3648679.html
總結
以上是生活随笔為你收集整理的[Android]使用ViewPager实现图片滑动展示的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 吾爱破解crackme 023 024
- 下一篇: android sina oauth2.