天天看点

Viewpager切换的淡入淡出切换(页面不移动)

本文转载自:http://blog.csdn.net/qq_22770457/article/details/52133288

纯手工自制的Android引导页,实现了Viewpager切换的淡入淡出(页面不移动!)切换以及文字动画。

下面是效果演示:

Viewpager切换的淡入淡出切换(页面不移动)

实现思路+心路历程...:

其实别的都还蛮简单的,就是这个ViewPager的淡入淡出切换动画比较棘手,以前都没有做过,然后去网上找了好久好久。

其中碰到各种坑无数,大概90%的人是引的 JazzyViewPager的包然后就balabala说自己实现了种种功能,真是醉了....

结论是国内根本找不到这个效果的实现嘛....

然后 在Github下了JazzyViewPager的包里也并没有看到我需要实现的效果:淡入淡出并且页面不滑动!不滑动!不动!

不过最后终于摸索出了方法...

对没错就是PageTransformer,在其中通过控制左右视图View的位置移动使得向右滑动时右视图不移动过来。(在下面会详细解释)。

代码实现:

GuideActivity.java

[java]  view plain  copy  

Viewpager切换的淡入淡出切换(页面不移动)
Viewpager切换的淡入淡出切换(页面不移动)
  1. package com.whale.nangua.toquan;  
  2. import android.os.Bundle;  
  3. import android.support.v4.app.Fragment;  
  4. import android.support.v4.app.FragmentActivity;  
  5. import android.support.v4.app.FragmentPagerAdapter;  
  6. import android.support.v4.view.ViewPager;  
  7. import android.view.LayoutInflater;  
  8. import android.view.View;  
  9. import android.view.WindowManager;  
  10. import android.widget.ImageButton;  
  11. import android.widget.TextView;  
  12. import com.whale.nangua.toquan.frag.Guide1Fragment;  
  13. import com.whale.nangua.toquan.frag.Guide2Fragment;  
  14. import com.whale.nangua.toquan.frag.Guide3Fragment;  
  15. import com.whale.nangua.toquan.frag.Guide4Fragment;  
  16. import com.whale.nangua.toquan.view.NGGuidePageTransformer;  
  17. import java.util.ArrayList;  
  18. import java.util.List;  
  19. public class GuideActivity extends FragmentActivity implements ViewPager.OnPageChangeListener,View.OnClickListener {  
  20.     // 主界面适配器  
  21.     private FragmentPagerAdapter guidePagerAdapter;  
  22.     // 所有的Tab  
  23.     private List<View> views;  
  24.     // 碎片每个碎片为一个布局  
  25.     private ArrayList<Fragment> fragments;  
  26.     // 导航式Tab  
  27.     private ViewPager vp;  
  28.     //四个Choice按钮id  
  29.      private int[] choicebtnids = {R.id.imgbtn_guide_choice1, R.id.imgbtn_guide_choice2,  
  30.             R.id.imgbtn_guide_choice3, R.id.imgbtn_guide_choice4};  
  31.     //四个Choice按钮  
  32.     private ImageButton[] choicebtns;  
  33.     //右移按钮  
  34.     private ImageButton btn_guide_next;  
  35.     //跳过按钮  
  36.     private TextView btn_guide_skip;  
  37.     @Override  
  38.     protected void onCreate(Bundle savedInstanceState) {  
  39.         super.onCreate(savedInstanceState);  
  40.         setContentView(R.layout.activity_guide);  
  41.         // 创建碎片集合  
  42.         fragments = new ArrayList<Fragment>();  
  43.         initView();  
  44.     }  
  45.     private void initView() {  
  46.         WindowManager wm = this.getWindowManager();  
  47.         screenWith = wm.getDefaultDisplay().getWidth();    //屏幕宽度  
  48.         //右移按钮  
  49.         btn_guide_next = (ImageButton) findViewById(R.id.btn_guide_next);  
  50.         btn_guide_next.setOnClickListener(this);  
  51.         //跳过  
  52.         btn_guide_skip = (TextView) findViewById(R.id.btn_guide_skip);  
  53.         btn_guide_skip.setOnClickListener(this);  
  54.         //绑定按钮组件  
  55.         choicebtns = new ImageButton[4];  
  56.         for (int i = 0; i < 4; i++) {  
  57.             final int j = i;  
  58.             choicebtns[i] = (ImageButton) findViewById(choicebtnids[i]);  
  59.             choicebtns[i].setOnClickListener(new View.OnClickListener() {  
  60.                 @Override  
  61.                 public void onClick(View v) {  
  62.                     changeTagView(j);  
  63.                 }  
  64.             });  
  65.         }  
  66.         LayoutInflater inflater = LayoutInflater.from(this);  
  67.         // 添加滑动  
  68.         views = new ArrayList<>();  
  69.         views.add(inflater.inflate(R.layout.fragment_guide1, null));  
  70.         views.add(inflater.inflate(R.layout.fragment_guide2, null));  
  71.         views.add(inflater.inflate(R.layout.fragment_guide3, null));  
  72.         views.add(inflater.inflate(R.layout.fragment_guide4, null));  
  73.         vp = (ViewPager) findViewById(R.id.vp_guide);  
  74.         guidePagerAdapter = new FragmentPagerAdapter(getSupportFragmentManager()) {  
  75.             @Override  
  76.             public int getCount() {  
  77.                 return fragments.size();  
  78.             }  
  79.             @Override  
  80.             public Fragment getItem(int arg0) {  
  81.                 return fragments.get(arg0);  
  82.             }  
  83.         };  
  84.         // 声明各个Tab的实例  
  85.         Guide1Fragment guide1Fragment = new Guide1Fragment();  
  86.         Guide2Fragment guide2Fragment = new Guide2Fragment();  
  87.         Guide3Fragment guide3Fragment = new Guide3Fragment();  
  88.         Guide4Fragment guide4Fragment = new Guide4Fragment();  
  89.         fragments.add(guide1Fragment);  
  90.         fragments.add(guide2Fragment);  
  91.         fragments.add(guide3Fragment);  
  92.         fragments.add(guide4Fragment);  
  93.         ngGuidePageTransformer = new NGGuidePageTransformer();  
  94.         ngGuidePageTransformer.setCurrentItem(this, 0, fragments);  
  95.         vp.setPageTransformer(true, ngGuidePageTransformer);  
  96.         vp.setAdapter(guidePagerAdapter);  
  97.         vp.setOnPageChangeListener(this);  
  98.         //注意,设置Page 即缓存页面的个数,数过小时会出现fragment重复加载的问题  
  99.         vp.setOffscreenPageLimit(4);  
  100.     }  
  101.     NGGuidePageTransformer ngGuidePageTransformer;  
  102.     TranslationInterface tempfrag;  
  103.     @Override  
  104.     public void onClick(View v) {  
  105.         switch (v.getId()) {  
  106.             //下一个  
  107.             case R.id.btn_guide_next:  
  108.                 int nextPage;  
  109.                 if (nowPage == 3) {  
  110.                     nextPage = 0;  
  111.                 }else {  
  112.                     nextPage = nowPage+1;  
  113.                 }  
  114.                 onPageSelected(nextPage);  
  115.                 changeTagView(nextPage);  
  116.                 break;  
  117.             //跳过  
  118.             case R.id.btn_guide_skip:  
  119.                 //TODO 跳过操作  
  120.                 break;  
  121.         }  
  122.     }  
  123.     public interface TranslationInterface {  
  124.         void translation(float x);  
  125.     }  
  126.     int screenWith ;//屏幕宽度  
  127.     @Override  
  128.     public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {  
  129.         //如果向右  
  130.             switch (position) {  
  131.                 case 0:  
  132.                     tempfrag = (Guide1Fragment) fragments.get(0);  
  133.                     tempfrag.translation(positionOffsetPixels);  
  134.                     break;  
  135.                 case 1:  
  136.                     tempfrag = (Guide2Fragment) fragments.get(1);  
  137.                     tempfrag.translation(positionOffsetPixels);  
  138.                     break;  
  139.                 case 2:  
  140.                     tempfrag = (Guide3Fragment) fragments.get(2);  
  141.                     tempfrag.translation(positionOffsetPixels);  
  142.                     break;  
  143.                 case 3:  
  144.                     tempfrag = (Guide4Fragment) fragments.get(3);  
  145.                     tempfrag.translation(positionOffsetPixels);  
  146.                     break;  
  147.             }  
  148.     }  
  149.     private int nowPage = 0;  
  150.     private void pageCheck(int position) {  
  151.         choicebtns[position].setBackgroundResource(R.drawable.shape_guide_choice);  
  152.         for (int i = 0;i<4;i++) {  
  153.             if (i!= position) {  
  154.                 choicebtns[i].setBackgroundResource(R.drawable.shape_guide_unchoice);  
  155.             }  
  156.         }  
  157.     }  
  158.     @Override  
  159.     public void onPageSelected(int position) {  
  160.         nowPage = position;  
  161.         ngGuidePageTransformer.setCurrentItem(position);  
  162.         pageCheck(position);  
  163.     }  
  164.     @Override  
  165.     public void onPageScrollStateChanged(int state) {  
  166.     }  
  167.     // 更换标签  
  168.     private void changeTagView(int change) {  
  169.         vp.setCurrentItem(change, false);  
  170.     }  
  171. }  

整体页面的布局,其中比较重要的点时设置Viewpager的PageTransformer,以及设置文字动画的效果。

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

[java]  view plain  copy  

Viewpager切换的淡入淡出切换(页面不移动)
Viewpager切换的淡入淡出切换(页面不移动)
  1. package com.whale.nangua.toquan.view;  
  2. import android.content.Context;  
  3. import android.support.v4.app.Fragment;  
  4. import android.support.v4.view.ViewPager;  
  5. import android.view.View;  
  6. import java.util.ArrayList;  
  7. public class NGGuidePageTransformer implements ViewPager.PageTransformer {  
  8.     private static final float MIN_ALPHA = 0.0f;    //最小透明度  
  9.     public void transformPage(View view, float position) {  
  10.         int pageWidth = view.getWidth();    //得到view宽  
  11.         if (position < -1) { // [-Infinity,-1)  
  12.             // This page is way off-screen to the left. 出了左边屏幕  
  13.             view.setAlpha(0);  
  14.         } else if (position <= 1) { // [-1,1]  
  15.             if (position < 0) {  
  16.                 //消失的页面  
  17.                 view.setTranslationX(-pageWidth * position);  //阻止消失页面的滑动  
  18.             } else {  
  19.                 //出现的页面  
  20.                 view.setTranslationX(pageWidth);        //直接设置出现的页面到底  
  21.                 view.setTranslationX(-pageWidth * position);  //阻止出现页面的滑动  
  22.             }  
  23.             // Fade the page relative to its size.  
  24.             float alphaFactor = Math.max(MIN_ALPHA, 1 - Math.abs(position));  
  25.             //透明度改变Log  
  26.             view.setAlpha(alphaFactor);  
  27.         } else { // (1,+Infinity]  
  28.             // This page is way off-screen to the right.    出了右边屏幕  
  29.             view.setAlpha(0);  
  30.         }  
  31.     }  
  32.     int nowPostion = 0; //当前页面  
  33.     Context context;  
  34.     ArrayList<Fragment> fragments;  
  35.     public void setCurrentItem(Context context, int nowPostion, ArrayList<Fragment> fragments) {  
  36.         this.nowPostion = nowPostion;  
  37.         this.context = context;  
  38.         this.fragments = fragments;  
  39.     }  
  40.     public void setCurrentItem(int nowPostion) {  
  41.         this.nowPostion = nowPostion;  
  42.     }  
  43. }  

实现的思路注释也比较详细,但是我还是说明一下:

就是先判断滑动的位置,如果是向右滑动,则首先要阻止当前页面(消失ing的页面)随着Viewpager的特性向左边滑动,以及右边要出现的界面向左滑动(在此之前先直接设置右边的界面到屏幕最左边)。要注意的是这里区分位置以及区分左右边是根据position来判断的

继续阅读