Viewpager切換的淡入淡出切換(頁面不移動)

本文轉載自:http://blog.csdn.net/qq_22770457/article/details/52133288


純手工自制的Android引導頁,實現了Viewpager切換的淡入淡出(頁面不移動!)切換以及文字動畫。

下面是效果演示:


實現思路+心路歷程...:

其實別的都還蠻簡單的,就是這個ViewPager的淡入淡出切換動畫比較棘手,以前都沒有做過,然後去網上找了好久好久。

其中碰到各種坑無數,大概90%的人是引的 JazzyViewPager的包然後就balabala說自己實現了種種功能,真是醉了....

結論是國內根本找不到這個效果的實現嘛....

然後 在Github下了JazzyViewPager的包裏也並沒有看到我需要實現的效果:淡入淡出並且頁面不滑動!不滑動!不動!

不過最後終於摸索出了方法...

對沒錯就是PageTransformer,在其中通過控制左右視圖View的位置移動使得向右滑動時右視圖不移動過來。(在下面會詳細解釋)。

代碼實現:

GuideActivity.java

[java] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. package com.whale.nangua.toquan;  
  2.   
  3. import android.os.Bundle;  
  4. import android.support.v4.app.Fragment;  
  5. import android.support.v4.app.FragmentActivity;  
  6. import android.support.v4.app.FragmentPagerAdapter;  
  7. import android.support.v4.view.ViewPager;  
  8. import android.view.LayoutInflater;  
  9. import android.view.View;  
  10. import android.view.WindowManager;  
  11. import android.widget.ImageButton;  
  12. import android.widget.TextView;  
  13. import com.whale.nangua.toquan.frag.Guide1Fragment;  
  14. import com.whale.nangua.toquan.frag.Guide2Fragment;  
  15. import com.whale.nangua.toquan.frag.Guide3Fragment;  
  16. import com.whale.nangua.toquan.frag.Guide4Fragment;  
  17. import com.whale.nangua.toquan.view.NGGuidePageTransformer;  
  18. import java.util.ArrayList;  
  19. import java.util.List;  
  20.   
  21. /** 
  22.  * Created by nangua on 2016/8/1. 
  23.  */  
  24. public class GuideActivity extends FragmentActivity implements ViewPager.OnPageChangeListener,View.OnClickListener {  
  25.     // 主界面適配器  
  26.     private FragmentPagerAdapter guidePagerAdapter;  
  27.     // 所有的Tab  
  28.     private List<View> views;  
  29.     // 碎片每個碎片爲一個佈局  
  30.     private ArrayList<Fragment> fragments;  
  31.     // 導航式Tab  
  32.     private ViewPager vp;  
  33.     //四個Choice按鈕id  
  34.      private int[] choicebtnids = {R.id.imgbtn_guide_choice1, R.id.imgbtn_guide_choice2,  
  35.             R.id.imgbtn_guide_choice3, R.id.imgbtn_guide_choice4};  
  36.     //四個Choice按鈕  
  37.     private ImageButton[] choicebtns;  
  38.     //右移按鈕  
  39.     private ImageButton btn_guide_next;  
  40.     //跳過按鈕  
  41.     private TextView btn_guide_skip;  
  42.   
  43.     @Override  
  44.     protected void onCreate(Bundle savedInstanceState) {  
  45.         super.onCreate(savedInstanceState);  
  46.         setContentView(R.layout.activity_guide);  
  47.         // 創建碎片集合  
  48.         fragments = new ArrayList<Fragment>();  
  49.         initView();  
  50.     }  
  51.   
  52.     private void initView() {  
  53.         WindowManager wm = this.getWindowManager();  
  54.         screenWith = wm.getDefaultDisplay().getWidth();    //屏幕寬度  
  55.         //右移按鈕  
  56.         btn_guide_next = (ImageButton) findViewById(R.id.btn_guide_next);  
  57.         btn_guide_next.setOnClickListener(this);  
  58.         //跳過  
  59.         btn_guide_skip = (TextView) findViewById(R.id.btn_guide_skip);  
  60.         btn_guide_skip.setOnClickListener(this);  
  61.         //綁定按鈕組件  
  62.         choicebtns = new ImageButton[4];  
  63.         for (int i = 0; i < 4; i++) {  
  64.             final int j = i;  
  65.             choicebtns[i] = (ImageButton) findViewById(choicebtnids[i]);  
  66.             choicebtns[i].setOnClickListener(new View.OnClickListener() {  
  67.                 @Override  
  68.                 public void onClick(View v) {  
  69.                     changeTagView(j);  
  70.                 }  
  71.             });  
  72.         }  
  73.         LayoutInflater inflater = LayoutInflater.from(this);  
  74.         // 添加滑動  
  75.         views = new ArrayList<>();  
  76.         views.add(inflater.inflate(R.layout.fragment_guide1, null));  
  77.         views.add(inflater.inflate(R.layout.fragment_guide2, null));  
  78.         views.add(inflater.inflate(R.layout.fragment_guide3, null));  
  79.         views.add(inflater.inflate(R.layout.fragment_guide4, null));  
  80.         vp = (ViewPager) findViewById(R.id.vp_guide);  
  81.         guidePagerAdapter = new FragmentPagerAdapter(getSupportFragmentManager()) {  
  82.             @Override  
  83.             public int getCount() {  
  84.                 return fragments.size();  
  85.             }  
  86.   
  87.             @Override  
  88.             public Fragment getItem(int arg0) {  
  89.                 return fragments.get(arg0);  
  90.             }  
  91.         };  
  92.         // 聲明各個Tab的實例  
  93.         Guide1Fragment guide1Fragment = new Guide1Fragment();  
  94.         Guide2Fragment guide2Fragment = new Guide2Fragment();  
  95.         Guide3Fragment guide3Fragment = new Guide3Fragment();  
  96.         Guide4Fragment guide4Fragment = new Guide4Fragment();  
  97.         fragments.add(guide1Fragment);  
  98.         fragments.add(guide2Fragment);  
  99.         fragments.add(guide3Fragment);  
  100.         fragments.add(guide4Fragment);  
  101.         ngGuidePageTransformer = new NGGuidePageTransformer();  
  102.         ngGuidePageTransformer.setCurrentItem(this0, fragments);  
  103.         vp.setPageTransformer(true, ngGuidePageTransformer);  
  104.         vp.setAdapter(guidePagerAdapter);  
  105.         vp.setOnPageChangeListener(this);  
  106.         //注意,設置Page 即緩存頁面的個數,數過小時會出現fragment重複加載的問題  
  107.         vp.setOffscreenPageLimit(4);  
  108.     }  
  109.   
  110.     NGGuidePageTransformer ngGuidePageTransformer;  
  111.     TranslationInterface tempfrag;  
  112.   
  113.     @Override  
  114.     public void onClick(View v) {  
  115.         switch (v.getId()) {  
  116.             //下一個  
  117.             case R.id.btn_guide_next:  
  118.                 int nextPage;  
  119.                 if (nowPage == 3) {  
  120.                     nextPage = 0;  
  121.                 }else {  
  122.                     nextPage = nowPage+1;  
  123.                 }  
  124.                 onPageSelected(nextPage);  
  125.                 changeTagView(nextPage);  
  126.                 break;  
  127.             //跳過  
  128.             case R.id.btn_guide_skip:  
  129.                 //TODO 跳過操作  
  130.   
  131.                 break;  
  132.         }  
  133.     }  
  134.   
  135.     public interface TranslationInterface {  
  136.         void translation(float x);  
  137.     }  
  138.   
  139.     int screenWith ;//屏幕寬度  
  140.   
  141.     /** 
  142.      * TODO 動畫修改 
  143.      * @param position 
  144.      * @param positionOffset 
  145.      * @param positionOffsetPixels 
  146.      */  
  147.     @Override  
  148.     public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {  
  149.         //如果向右  
  150.             switch (position) {  
  151.                 case 0:  
  152.                     tempfrag = (Guide1Fragment) fragments.get(0);  
  153.                     tempfrag.translation(positionOffsetPixels);  
  154.                     break;  
  155.                 case 1:  
  156.                     tempfrag = (Guide2Fragment) fragments.get(1);  
  157.                     tempfrag.translation(positionOffsetPixels);  
  158.                     break;  
  159.                 case 2:  
  160.                     tempfrag = (Guide3Fragment) fragments.get(2);  
  161.                     tempfrag.translation(positionOffsetPixels);  
  162.                     break;  
  163.                 case 3:  
  164.                     tempfrag = (Guide4Fragment) fragments.get(3);  
  165.                     tempfrag.translation(positionOffsetPixels);  
  166.                     break;  
  167.             }  
  168.     }  
  169.   
  170.     private int nowPage = 0;  
  171.     /** 
  172.      * 自定義按鈕選擇的方法 
  173.      * @param position 
  174.      */  
  175.     private void pageCheck(int position) {  
  176.         choicebtns[position].setBackgroundResource(R.drawable.shape_guide_choice);  
  177.         for (int i = 0;i<4;i++) {  
  178.             if (i!= position) {  
  179.                 choicebtns[i].setBackgroundResource(R.drawable.shape_guide_unchoice);  
  180.             }  
  181.         }  
  182.     }  
  183.   
  184.     @Override  
  185.     public void onPageSelected(int position) {  
  186.         nowPage = position;  
  187.         ngGuidePageTransformer.setCurrentItem(position);  
  188.         pageCheck(position);  
  189.     }  
  190.   
  191.     @Override  
  192.     public void onPageScrollStateChanged(int state) {  
  193.     }  
  194.   
  195.     // 更換標籤  
  196.     private void changeTagView(int change) {  
  197.         vp.setCurrentItem(change, false);  
  198.     }  
  199. }  

整體頁面的佈局,其中比較重要的點時設置Viewpager的PageTransformer,以及設置文字動畫的效果。

下面是最重要的類:PageTransformer.java

[java] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. package com.whale.nangua.toquan.view;  
  2.   
  3. import android.content.Context;  
  4. import android.support.v4.app.Fragment;  
  5. import android.support.v4.view.ViewPager;  
  6. import android.view.View;  
  7. import java.util.ArrayList;  
  8.   
  9. public class NGGuidePageTransformer implements ViewPager.PageTransformer {  
  10.     private static final float MIN_ALPHA = 0.0f;    //最小透明度  
  11.   
  12.     public void transformPage(View view, float position) {  
  13.         int pageWidth = view.getWidth();    //得到view寬  
  14.   
  15.         if (position < -1) { // [-Infinity,-1)  
  16.             // This page is way off-screen to the left. 出了左邊屏幕  
  17.             view.setAlpha(0);  
  18.   
  19.         } else if (position <= 1) { // [-1,1]  
  20.             if (position < 0) {  
  21.                 //消失的頁面  
  22.                 view.setTranslationX(-pageWidth * position);  //阻止消失頁面的滑動  
  23.             } else {  
  24.                 //出現的頁面  
  25.                 view.setTranslationX(pageWidth);        //直接設置出現的頁面到底  
  26.                 view.setTranslationX(-pageWidth * position);  //阻止出現頁面的滑動  
  27.             }  
  28.             // Fade the page relative to its size.  
  29.             float alphaFactor = Math.max(MIN_ALPHA, 1 - Math.abs(position));  
  30.             //透明度改變Log  
  31.             view.setAlpha(alphaFactor);  
  32.         } else { // (1,+Infinity]  
  33.             // This page is way off-screen to the right.    出了右邊屏幕  
  34.             view.setAlpha(0);  
  35.         }  
  36.     }  
  37.   
  38.     int nowPostion = 0//當前頁面  
  39.     Context context;  
  40.     ArrayList<Fragment> fragments;  
  41.   
  42.     public void setCurrentItem(Context context, int nowPostion, ArrayList<Fragment> fragments) {  
  43.         this.nowPostion = nowPostion;  
  44.         this.context = context;  
  45.         this.fragments = fragments;  
  46.     }  
  47.   
  48.     public void setCurrentItem(int nowPostion) {  
  49.         this.nowPostion = nowPostion;  
  50.     }  
  51.   
  52. }  

實現的思路註釋也比較詳細,但是我還是說明一下:

就是先判斷滑動的位置,如果是向右滑動,則首先要阻止當前頁面(消失ing的頁面)隨着Viewpager的特性向左邊滑動,以及右邊要出現的界面向左滑動(在此之前先直接設置右邊的界面到屏幕最左邊)。要注意的是這裏區分位置以及區分左右邊是根據position來判斷的

發佈了73 篇原創文章 · 獲贊 75 · 訪問量 15萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章