Android自定義引導玩轉ViewPager的方法詳解
ViewPager簡介:
ViewPager(android.support.v4.view.ViewPager)是android擴展包v4包中的類,這個類可以讓用戶左右切換當前的view,實現(xiàn)滑動切換的效果。
注意:
ViewPager類直接繼承了ViewGroup類,也就是說它和我們經常打交道的LinearLayout一樣,都是一個容器,需要在里面添加我們想要顯示的內容。
ViewPager類需要一個PagerAdapter適配器類給它提供數(shù)據(jù),這個和ListView類似。
ViewPager基礎使用
具體步驟:
1.在布局文件里加入
<android.support.v4.view.ViewPager android:id="@+id/in_viewpager" android:layout_width="match_parent" android:layout_height="match_parent"> </android.support.v4.view.ViewPager>
2.在Activity中加載要顯示的Views,通過動態(tài)加載布局得到一個個View
mViewList = new ArrayList<View>(); LayoutInflater lf = getLayoutInflater().from(MainActivity.this); View view1 = lf.inflate(R.layout.we_indicator1, null); View view2 = lf.inflate(R.layout.we_indicator2, null); View view3 = lf.inflate(R.layout.we_indicator3, null); mViewList.add(view1); mViewList.add(view2); mViewList.add(view3);
3.自定義PagerAdapter,以便將步驟2中的Views數(shù)據(jù)加載到ViewPager容器中
public class ViewPagerAdatper extends PagerAdapter { private List<View> mViewList ; public ViewPagerAdatper(List<View> mViewList ) { this.mViewList = mViewList; } @Override public int getCount() { return mViewList.size(); } @Override public boolean isViewFromObject(View view, Object object) { return view==object; } @Override public Object instantiateItem(ViewGroup container, int position) { container.addView(mViewList.get(position)); return mViewList.get(position); } @Override public void destroyItem(ViewGroup container, int position, Object object) { container.removeView(mViewList.get(position)); } }
4.將ViewPager和自定義的PagerAdapter關聯(lián)起來
mIn_vp.setAdapter(new ViewPagerAdatper(mViewList));
通過簡單使用ViewPager,得到的展示效果,僅僅支持左右滑動,效果比較單一。
ViewPager進階使用——實現(xiàn)跟隨式小圓點效果
步驟:
1.添加小圓點
在布局中的設置如下:
<RelativeLayout android:id="@+id/rl_dots" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_centerHorizontal="true" android:layout_marginBottom="60dp"> <LinearLayout android:id="@+id/in_ll" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal"> </LinearLayout> <ImageView android:id="@+id/iv_light_dots" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/light_dot"/> </RelativeLayout>
隨后在LinearLayout中動態(tài)添加3個小黑點,小白點默認覆蓋在第一個小黑點的上面。
在Activity中的添加小黑點,代碼如下:
private void addDots() { mOne_dot = new ImageView(this); mOne_dot.setImageResource(R.drawable.gray_dot); LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); layoutParams.setMargins(0, 0, 40, 0); mIn_ll.addView(mOne_dot, layoutParams); mTwo_dot = new ImageView(this); mTwo_dot.setImageResource(R.drawable.gray_dot); mIn_ll.addView(mTwo_dot, layoutParams); mThree_dot = new ImageView(this); mThree_dot.setImageResource(R.drawable.gray_dot); mIn_ll.addView(mThree_dot, layoutParams); setClickListener(); }
2.獲得兩個點之間的距離
實現(xiàn)小白點動態(tài)跟隨的思路是:根據(jù)頁面的移動情況,通過設置小白點的 leftMargin 實現(xiàn)小紅點的動態(tài)跟隨。因此首要的是獲得兩個點之間的距離,根據(jù)頁面移動到的位置,進行相應的運算。
需要注意的是:在onCreate()中直接獲得小白點的左邊距 getLeft()結果為0,這是因為View組件布局要在onResume回調后完成。
因此使用另一種方法:
mLight_dots.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { //獲得兩個圓點之間的距離 mDistance = mIn_ll.getChildAt(1).getLeft() - mIn_ll.getChildAt(0).getLeft(); mLight_dots.getViewTreeObserver() .removeGlobalOnLayoutListener(this); } });
在布局發(fā)生改變或者某個視圖的可視狀態(tài)發(fā)生改變時調用該事件。但此方法會被多次調用,因此需要在獲取到視圖的寬度和高度后執(zhí)行 remove 方法移除該監(jiān)聽事件。
3.監(jiān)聽頁面的移動情況
mIn_vp.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { //頁面滾動時小白點移動的距離,并通過setLayoutParams(params)不斷更新其位置 float leftMargin = mDistance * (position + positionOffset); RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) mLight_dots.getLayoutParams(); params.leftMargin = (int) leftMargin; mLight_dots.setLayoutParams(params); } @Override public void onPageSelected(int position) { //頁面跳轉時,設置小圓點的margin float leftMargin = mDistance * position; RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) mLight_dots.getLayoutParams(); params.leftMargin = (int) leftMargin; mLight_dots.setLayoutParams(params); } @Override public void onPageScrollStateChanged(int state) { } }); }
在頁面移動過程中,根據(jù)mDistance * (position + positionOffset) 可以實時更新小白點的位置
這部分內容加入了一個新的功能 點擊小黑點 可以直接跳轉到對應的引導頁面,具體邏輯就是在小黑點的點擊事件中加入如下代碼:
mIn_vp.setCurrentItem(1);
在頁面選擇過程中,根據(jù)mDistance * position可以實時小紅點的位置
4.跳轉按鈕的實現(xiàn)
具體邏輯:到引導頁到達最后一頁時,跳轉到主頁的按鈕出現(xiàn)。其他情況為隱藏狀態(tài)
因此可以在onPageScrolled(int position, float positionOffset, int positionOffsetPixels)和onPageSelected(int position)方法中加入如下代碼:
if(position==2){ mBtn_next.setVisibility(View.VISIBLE); }
當按照從第一頁到最后一頁,然后點擊按鈕跳轉到首頁,則以上邏輯足夠。
但當用戶瀏覽到最后一頁后再回轉到前面感興趣的頁面,則會出現(xiàn)按鈕依舊出現(xiàn)的情況,不符合要求。因此要完善邏輯,加入新的判斷,邏輯如下:
if(position!=2&&mBtn_next.getVisibility()==View.VISIBLE){ mBtn_next.setVisibility(View.GONE); }
以上邏輯保證了按鈕的正常顯示,剩下的就可以具體操作,實現(xiàn)跳轉到首頁的邏輯。
ViewPager進階使用——自定義炫酷動畫
ViewPager自帶了一個setPageTransformer用于設置切換動畫~
setPageTransformer (boolean reverseDrawingOrder, PageTransformer transformer)需要傳入兩個參數(shù)
第一個參數(shù):如果為true,則表明自定義的pageTransformer需要 page view從后到前的順序繪制,反之則為false。
第二個參數(shù):傳入一個自定義的pageTransformer對象
因此實現(xiàn)炫酷動畫的關鍵點就在于:自定義pageTransformer
Google官方給我們展示了兩個動畫例子:DepthPageTransformer和ZoomOutPageTransformer,比較炫。我們就以Google官方的例子來學習自定義pageTransformer,以此為基礎,我們可以自定義各種各樣的動畫實現(xiàn)效果。
1.PageTransformer中position解析
自定義PageTransformer只需要實現(xiàn)一個方法,transformPage(View page, float position),而這個方法實現(xiàn)的關鍵就是對position的理解。
源碼中的注釋解釋如下:
Apply the transformation to this page
position - Position of page relative to the current front-and-center position of the pager. 0 is front and center. 1 is one full page position to the right, and -1 is one page position to the left.
我們可以理解為:
- 0表示當前頁面,是當前頁面
- -1表示左側的頁面,是左側頁面
- 1表示右側的頁面,是右側頁面
在用戶滑動界面的時候,position是動態(tài)變化的,下面以左滑為例:
- 選中頁面 position:0->-1
- 前一個item position:-1 -> -2
- 后一個item position:1 -> 0
但是當ViewPager設置pageMargin,設置兩個頁面之間的距離(通過調用viewPager.setPageMargin()方法設置)后,情況則不同。
如果你設置了pageMargin,前后頁面的position需要分別加上(或減去,前減后加)一個偏移量(偏移量的計算方式為pageMargin / pageWidth)。
同樣以左滑為例:
- 選中頁面position:0->-1 - pageMargin / pageWidth
- 前一個item position:-1 - pageMargin / pageWidth -> -2 - pageMargin / pageWidth
- 后一個item position:1 + pageMargin / pageWidth -> 0
因此我們可以將position的值應用于setAlpha(), setTranslationX(), 或者 setScaleY()等等方法,從而實現(xiàn)自定義的動畫效果。
2.實現(xiàn)transformPage(View page, float position)方法
public class DepthPageTransformer implements ViewPager.PageTransformer { private static final float MIN_SCALE = 0.75f; @Override public void transformPage(View page, float position) { int pageWidth = page.getWidth(); if (position < -1) { // [-Infinity,-1) // 頁面遠離左側頁面 page.setAlpha(0); } else if (position <= 0) { // [-1,0] // 頁面在由中間頁滑動到左側頁面 或者 由左側頁面滑動到中間頁 page.setAlpha(1); page.setTranslationX(0); page.setScaleX(1); page.setScaleY(1); } else if (position <= 1) { // (0,1] //頁面在由中間頁滑動到右側頁面 或者 由右側頁面滑動到中間頁 // 淡入淡出效果 page.setAlpha(1 - position); // 反方向移動 page.setTranslationX(pageWidth * -position); // 0.75-1比例之間縮放 float scaleFactor = MIN_SCALE + (1 - MIN_SCALE) * (1 - Math.abs(position)); page.setScaleX(scaleFactor); page.setScaleY(scaleFactor); } else { // (1,+Infinity] // 頁面遠離右側頁面 page.setAlpha(0); } } }
以上是一些ViewPager做引導頁做用的到一些知識點,希望和大家分享共同學習。由于水平有限,有什么不對的地方歡迎指正。
總結
以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,謝謝大家對腳本之家的支持。
- Android使用ViewPager實現(xiàn)啟動引導頁
- Android開發(fā)實戰(zhàn)之漂亮的ViewPager引導頁
- Android開發(fā)實現(xiàn)的ViewPager引導頁功能(動態(tài)加載指示器)詳解
- ViewPager實現(xiàn)漂亮的引導頁
- Android控件ViewPager實現(xiàn)帶有動畫的引導頁
- ViewPager實現(xiàn)帶引導小圓點與自動跳轉的引導界面
- Android利用ViewPager實現(xiàn)用戶引導界面效果的方法
- ViewPager打造輪播圖Banner/引導頁Guide
- Android使用ViewPager完成app引導頁
- ViewPager實現(xiàn)輪播圖引導頁
相關文章
實例講解Android中ViewPager組件的一些進階使用技巧
這篇文章主要介紹了Android中ViewPager組件的一些進階使用技巧,包括添加標題與onPagerChangeListener監(jiān)聽使用等,需要的朋友可以參考下2016-03-03Android開發(fā)之BroadcastReceiver用法實例分析
這篇文章主要介紹了Android開發(fā)之BroadcastReceiver用法,實例分析了Android中廣播的相關使用技巧,需要的朋友可以參考下2015-05-05Android實現(xiàn)放大鏡效果的方法實例(附源碼)
這篇文章主要給大家介紹了利用Android實現(xiàn)放大鏡效果的方法實例,文中給出了詳細的介紹和示例代碼,文章的結尾更是給出了源碼供大家下載學習,有需要的朋友們下面來一起看看吧。2017-01-01Android studio實現(xiàn)PopupWindow彈出框效果
這篇文章主要為大家詳細介紹了Android studio實現(xiàn)PopupWindow彈出框效果,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-10-10