android 开发 TabLayout+ViewPager 点击+滑动效果

TabLayout是android design包内的控件; 
一般情况下,它总是喜欢和ViewPager成对出现;

实现效果图:




具体代码实现如下:


Xml代码   收藏代码
  1. <!-- 如果你屏幕上显示只有少数 tab 的时候,可以设置tabMode="fixed",若很多需要拖动,则设置tabMode="scroll" -->  
  2.         <!-- 如果 tabMode 设置成 scrollable 的,则tabGravity属性将会被忽略 -->  
  3.         <!-- 其他可设置属性  
  4.             app:tabIndicatorColor="#FF00FF00"  
  5.             app:tabSelectedTextColor="#FF00FF00"  
  6.             app:tabTextColor="#FF000000"  
  7.          -->  
  8.         <android.support.design.widget.TabLayout  
  9.             android:id="@+id/tabLayout"  
  10.             android:layout_width="match_parent"  
  11.             android:layout_height="wrap_content"  
  12.             app:tabGravity="fill"  
  13.             app:tabMode="fixed"  
  14.             app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" />  
  15. <android.support.v4.view.ViewPager  
  16.             android:id="@+id/viewPager"  
  17.             android:layout_width="match_parent"  
  18.             android:layout_height="match_parent"  
  19.             />  


然后就是结合了,由于我们通常在ViewPager中放置的是若干个Fragment,所以还得先实现几个Fragment,典型的像下面这个: 
Java代码   收藏代码
  1. public class MoveFragment extends Fragment implements OnClickListener {  
  2.   
  3.     private String curFlag;  
  4.     public static MoveFragment newInstance(String flag){  
  5.         MoveFragment fragment = new MoveFragment();    
  6.         Bundle bundle = new Bundle();    
  7.         bundle.putString("Flag", flag);  
  8.         fragment.setArguments(bundle);    
  9.         return fragment;  
  10.     }  
  11.   
  12.     public void onCreate(Bundle savedInstanceState) {    
  13.         super.onCreate(savedInstanceState);    
  14.         Bundle args = getArguments();  
  15.         if (args != null) {    
  16.              curFlag = args.getString("Flag");  
  17.         }  
  18.     }   
  19.   
  20.     @Override  
  21.     public View onCreateView(LayoutInflater inflater, ViewGroup container,  
  22.             Bundle savedInstanceState) {  
  23.         super.onCreateView(inflater, container, savedInstanceState);  
  24.         View view = inflater.inflate(R.layout.fragment_move, container,false);  
  25.         initViews(view);  
  26.         return view;  
  27.     }  
  28.   
  29.     public void initViews(View view){  
  30.         TextView tv=(TextView)view.findViewById(R.id.tv);  
  31.         tv.setText(curFlag);  
  32.     }  
  33.     @Override  
  34.     public void onClick(View v) {  
  35.   
  36.     }  
  37.   
  38. }  


接下去就可以使用了: 
首先new 几个Fragment出来: 
private static final String[] titles = new String[]{"Tab 1", "Tab 2","Tab 3", "Tab 4"}; 
..... 
Fragment[] fragments = new Fragment[titles.length]; 
fragments[0]=MoveFragment.newInstance(titles[0]); 
fragments[1]=XFragment.newInstance(titles[1]); 
fragments[2]=YFragment.newInstance(titles[2]); 
fragments[3]=ZFragment.newInstance(titles[3]); 

然后实现一个FragmentPagerAdapter,注意,一定要重写getPageTitle方法,这样TabLayout就可以从中取到要显示的标题了: 
Java代码   收藏代码
  1. FragmentPagerAdapter pagerAdapter = new FragmentPagerAdapter(getSupportFragmentManager()) {  
  2.             @Override  
  3.             public int getCount() {  
  4.                 return fragments.length;  
  5.             }  
  6.   
  7.             @Override  
  8.             public Fragment getItem(int position) {  
  9.                 return fragments[position];  
  10.             }  
  11.   
  12.             @Override  
  13.             public CharSequence getPageTitle(int position) {  
  14.                 return titles[position];  
  15.             }  
  16.         };  


剩下就是绑定了: 
Java代码   收藏代码
  1. tabLayout = (TabLayout) findViewById(R.id.tabLayout);  
  2. tabLayout.setupWithViewPager(viewPager);  


然而偶尔也会没有ViewPager,TabLayout也会单独使用 
那么这个时候需要使用addTab方法为TabLayout添加title了: 
Java代码   收藏代码
  1. tabLayout = (TabLayout) findViewById(R.id.tabLayout);  
  2. tabLayout.addTab(tabLayout.newTab().setText("Tab 1"));  
  3. tabLayout.addTab(tabLayout.newTab().setText("Tab 2"));  
  4. tabLayout.addTab(tabLayout.newTab().setText("Tab 3"));  
  5. tabLayout.addTab(tabLayout.newTab().setText("Tab 4"));  


 
//下面的内容与Tablayout无关,可以无视 
/// 
接下去要实现一个ViewPager滑动的时候背景颜色过渡变化的效果 
在网上找到一个背景颜色可以过渡变化的View,和ViewPager结合使用: 
Java代码   收藏代码
  1. ViewPager viewPager = (ViewPager) findViewById(R.id.viewPager);  
  2.         viewPager.setAdapter(pagerAdapter);  
  3.           
  4.         ColorAnimationView colorAnimationView = (ColorAnimationView) findViewById(R.id.colorAnimationView);  
  5.          colorAnimationView.setViewPager(viewPager,titles.length,0xffFF8080,0xff8080FF,0xffffffff,0xff80ff80);  
  6.          //you can call this method like this:  
  7. //      colorAnimationView.setViewPager(viewPager, titles.length);//use default color  
  8.         colorAnimationView.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {  
  9.             @Override  
  10.             public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {  
  11.             }  
  12.   
  13.             @Override  
  14.             public void onPageSelected(int position) {  
  15.             }  
  16.   
  17.             @Override  
  18.             public void onPageScrollStateChanged(int state) {  
  19.             }  
  20.         });  

布局的时候需要把这个View和ViewPager重叠(FrameLayout)在一起使用,这样就能看出效果了: 
Java代码   收藏代码
  1. <FrameLayout  
  2.         android:layout_width="match_parent"  
  3.         android:layout_height="match_parent"   
  4.         app:layout_behavior="@string/appbar_scrolling_view_behavior"  
  5.         >  
  6.   
  7.         <com.widget.view.ColorAnimationView  
  8.             android:id="@+id/colorAnimationView"  
  9.             android:layout_width="match_parent"  
  10.             android:layout_height="match_parent" />  
  11.   
  12.         <android.support.v4.view.ViewPager  
  13.             android:id="@+id/viewPager"  
  14.             android:layout_width="match_parent"  
  15.             android:layout_height="match_parent"  
  16.             />  
  17.     </FrameLayout>  

注意ViewPager中的Fragment不要设置backgroundColor(用屁股想想也知道为什么!) 

该类的源码如下: 
Java代码   收藏代码
  1. package com.widget.view;  
  2.   
  3. import android.animation.Animator;  
  4. import android.animation.ArgbEvaluator;  
  5. import android.animation.ObjectAnimator;  
  6. import android.animation.ValueAnimator;  
  7. import android.content.Context;  
  8. import android.support.v4.view.ViewPager;  
  9. import android.util.AttributeSet;  
  10. import android.view.View;  
  11. /** 
  12.  *  
  13.  * @author Administrator 
  14.  * @see https://github.com/TaurusXi/GuideBackgroundColorAnimation 
  15.  */  
  16. public class ColorAnimationView extends View implements ValueAnimator.AnimatorUpdateListener, Animator.AnimatorListener {  
  17.     private static final int WHITE = 0xFFFFFFFF;  
  18.     private static final int RED = 0xffFF8080;  
  19.     private static final int BLUE = 0xff8080FF;  
  20.     private static final int GREEN = 0xff80ff80;  
  21.     private static final int DURATION = 3000;  
  22.     ValueAnimator colorAnim = null;  
  23.   
  24.     private PageChangeListener mPageChangeListener;  
  25.   
  26.     ViewPager.OnPageChangeListener onPageChangeListener;  
  27.   
  28.     public void setOnPageChangeListener(ViewPager.OnPageChangeListener onPageChangeListener) {  
  29.         this.onPageChangeListener = onPageChangeListener;  
  30.     }  
  31.   
  32.   
  33.   
  34.     /** 
  35.      * 这是你唯一需要关心的方法 
  36.      * @param mViewPager  你必须在设置 Viewpager 的 Adapter 这后,才能调用这个方法。 
  37.      * @param obj ,这个obj实现了 ColorAnimationView.OnPageChangeListener ,实现回调 
  38.      * @param count   ,viewpager孩子的数量 
  39.      * @param colors int... colors ,你需要设置的颜色变化值~~ 如何你传人 空,那么触发默认设置的颜色动画 
  40.      * */  
  41.     /** 
  42.      * This is the only method you need care about. 
  43.      * @param mViewPager  ,you need set the adpater before you call this. 
  44.      * @param count   ,this param set the count of the viewpaper's child 
  45.      * @param colors ,this param set the change color use (int... colors), 
  46.      *               so,you could set any length if you want.And by default. 
  47.      *               if you set nothing , don't worry i have already creat 
  48.      *               a default good change color! 
  49.      * */  
  50.     public void setViewPager(ViewPager mViewPager, int count, int... colors) {  
  51. //      this.mViewPager = mViewPager;  
  52.         if (mViewPager.getAdapter() == null) {  
  53.             throw new IllegalStateException("ViewPager does not have adapter instance.");  
  54.         }  
  55.         mPageChangeListener.setViewPagerChildCount(count);  
  56.   
  57.         mViewPager.setOnPageChangeListener(mPageChangeListener);  
  58.         if (colors.length == 0) {  
  59.             createDefaultAnimation();  
  60.         } else {  
  61.             createAnimation(colors);  
  62.         }  
  63.   
  64.     }  
  65.   
  66.     public ColorAnimationView(Context context) {  
  67.         this(context, null0);  
  68.   
  69.     }  
  70.   
  71.     public ColorAnimationView(Context context, AttributeSet attrs) {  
  72.         this(context, attrs, 0);  
  73.     }  
  74.   
  75.     public ColorAnimationView(Context context, AttributeSet attrs, int defStyleAttr) {  
  76.         super(context, attrs, defStyleAttr);  
  77.         mPageChangeListener = new PageChangeListener();  
  78.     }  
  79.   
  80.     private void seek(long seekTime) {  
  81.         if (colorAnim == null) {  
  82.             createDefaultAnimation();  
  83.         }  
  84.         colorAnim.setCurrentPlayTime(seekTime);  
  85.     }  
  86.   
  87.     private void createAnimation(int... colors) {  
  88.         if (colorAnim == null) {  
  89.             colorAnim = ObjectAnimator.ofInt(this,"backgroundColor", colors);  
  90.             colorAnim.setEvaluator(new ArgbEvaluator());  
  91.             colorAnim.setDuration(DURATION);  
  92.             colorAnim.addUpdateListener(this);  
  93.         }  
  94.     }  
  95.   
  96.     private void createDefaultAnimation() {  
  97.         colorAnim = ObjectAnimator.ofInt(this,"backgroundColor", WHITE, RED, BLUE, GREEN);  
  98.         colorAnim.setEvaluator(new ArgbEvaluator());  
  99.         colorAnim.setDuration(DURATION);  
  100.         colorAnim.addUpdateListener(this);  
  101.     }  
  102.   
  103.     @Override public void onAnimationStart(Animator animation) {  
  104.   
  105.     }  
  106.   
  107.     @Override public void onAnimationEnd(Animator animation) {  
  108.     }  
  109.   
  110.     @Override public void onAnimationCancel(Animator animation) {  
  111.   
  112.     }  
  113.   
  114.     @Override public void onAnimationRepeat(Animator animation) {  
  115.   
  116.     }  
  117.   
  118.     @Override public void onAnimationUpdate(ValueAnimator animation) {  
  119.         invalidate();  
  120. //      long playtime = colorAnim.getCurrentPlayTime();  
  121.     }  
  122.   
  123.     private class PageChangeListener implements ViewPager.OnPageChangeListener {  
  124.   
  125.         private int viewPagerChildCount;  
  126.   
  127.         public void setViewPagerChildCount(int viewPagerChildCount) {  
  128.             this.viewPagerChildCount = viewPagerChildCount;  
  129.         }  
  130.   
  131.         public int getViewPagerChildCount() {  
  132.             return viewPagerChildCount;  
  133.         }  
  134.   
  135.         @Override   
  136.         public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {  
  137.   
  138.             int count = getViewPagerChildCount() - 1;  
  139.             if (count != 0) {  
  140.                 float length = (position + positionOffset) / count;  
  141.                 int progress = (int) (length * DURATION);  
  142.                 ColorAnimationView.this.seek(progress);  
  143.             }  
  144.             // call the method by default  
  145.             if (onPageChangeListener!=null){  
  146.                 onPageChangeListener.onPageScrolled(position,positionOffset,positionOffsetPixels);  
  147.             }  
  148.   
  149.         }  
  150.   
  151.         @Override   
  152.         public void onPageSelected(int position) {  
  153.             if (onPageChangeListener!=null) {  
  154.                 onPageChangeListener.onPageSelected(position);  
  155.             }  
  156.         }  
  157.   
  158.         @Override   
  159.         public void onPageScrollStateChanged(int state) {  
  160.             if (onPageChangeListener!=null) {  
  161.                 onPageChangeListener.onPageScrollStateChanged(state);  
  162.             }  
  163.         }  
  164.     }  
  165. }  


Android TabLayout 库:FlycoTabLayout 
http://www.open-open.com/lib/view/open1447294190257.html  


https://github.com/hugeterry/CoordinatorTabLayout



有些时候或许有需求,要求TabLayout或者ViewPager在某些情况下不能滑动,这个时候就需要我们能主动控制TabLayout和ViewPager什么可以滑动,什么时候不可以滑动。

1、先要自定义一个可以自由控制viewpager是否能滑动的viewpager:

package com.example.yk.tabviewpagertest;

import android.content.Context;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.view.MotionEvent;

/**
 * Created by yk on 2016/12/7.
 */

public class NoScrollViewPager extends ViewPager{

    public void setNeedScroll(boolean needScroll) {
        isNeedScroll = needScroll;
    }

    private boolean isNeedScroll=true;

    public NoScrollViewPager(Context context) {
        super(context);
    }

    public NoScrollViewPager(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        if(isNeedScroll){
            return super.onTouchEvent(ev);
        }else {
            return false;
        }
    }

//    @Override
//    public boolean onInterceptTouchEvent(MotionEvent ev) {
//        return super.onInterceptTouchEvent(ev);
//        return false;
//    }
}

2、自由控制TabLayout是否可以点击:

public void setTabLayoutCanClick(boolean canClick){
        LinearLayout tabStrip= (LinearLayout) tabLayout.getChildAt(0);
        for (int i = 0; i < tabStrip.getChildCount(); i++) {
            View tabView = tabStrip.getChildAt(i);
            if(tabView !=null){
                tabView.setClickable(canClick);
            }
        }
    }

整体代码:

MainActivity中代码:

package com.example.yk.tabviewpagertest;

import android.support.design.widget.TabLayout;
import android.support.v4.app.Fragment;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;

import java.util.ArrayList;


public class MainActivity extends AppCompatActivity {
    private TabLayout tabLayout;
    private NoScrollViewPager viewPager;
    private String[] mTabTexts;
    private ArrayList<Fragment> mFragmentsList;
    private PurFragmentPageAdapter pageAdapter;
    private Button btnCan,btnCanNot;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        tabLayout = (TabLayout) findViewById(R.id.tablayout);
        viewPager = (NoScrollViewPager) findViewById(R.id.viewpager);
        btnCan = (Button) findViewById(R.id.btn_can);
        btnCanNot= (Button) findViewById(R.id.btn_can_not);

        mTabTexts = new String[]{"定量", "计件", "散斤"};
        mFragmentsList = new ArrayList<>();
        mFragmentsList.add(new FirstFragment());
        mFragmentsList.add(new SecondFragment());
        mFragmentsList.add(new ThirdFragment());
        for (int i = 0; i < mTabTexts.length; i++) {
            tabLayout.addTab(tabLayout.newTab().setText(mTabTexts[i]));
        }


        tabLayout.setTabMode(TabLayout.MODE_FIXED);
        pageAdapter = new PurFragmentPageAdapter(getSupportFragmentManager(), mFragmentsList, mTabTexts);
        viewPager.setAdapter(pageAdapter);
        tabLayout.setupWithViewPager(viewPager);

        viewPager.setCurrentItem(1);//设置默认选中某个tab

        btnCanNot.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                viewPager.setNeedScroll(false);
                setTabLayoutCanClick(false);
            }
        });

        btnCan.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                viewPager.setNeedScroll(true);
                setTabLayoutCanClick(true);
            }
        });
    }

    public void setTabLayoutCanClick(boolean canClick){
        LinearLayout tabStrip= (LinearLayout) tabLayout.getChildAt(0);
        for (int i = 0; i < tabStrip.getChildCount(); i++) {
            View tabView = tabStrip.getChildAt(i);
            if(tabView !=null){
                tabView.setClickable(canClick);
            }
        }
    }
}

自定义viewPager中的代码和上面的一样,就不赘述了。


TabLayout禁止选择 

项目中有个页面上面是TabLayout下面是Listview,选择TabLayout的选项卡更新下面Listview里面的数据,在请求的时候想禁用TabLayout选项卡来避免用户频繁点击选项卡造成Listview的数据错误。
       如果只是调用TabLayout的setClickable方法是不起作用的,需要获取到每个选项卡的tabView然后再分别设置。


	LinearLayout tabStrip = (LinearLayout) tabLayout.getChildAt(0);
	for (int i = 0; i < tabStrip.getChildCount(); i++) {
   		 View tabView = tabStrip.getChildAt(i);
    		if (tabView != null) {
        		tabView.setClickable(false);
   	 }




  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值