TabLayout是android design包内的控件;
一般情况下,它总是喜欢和ViewPager成对出现;
实现效果图:
具体代码实现如下:
- <!-- 如果你屏幕上显示只有少数 tab 的时候,可以设置tabMode="fixed",若很多需要拖动,则设置tabMode="scroll" -->
- <!-- 如果 tabMode 设置成 scrollable 的,则tabGravity属性将会被忽略 -->
- <!-- 其他可设置属性
- app:tabIndicatorColor="#FF00FF00"
- app:tabSelectedTextColor="#FF00FF00"
- app:tabTextColor="#FF000000"
- -->
- <android.support.design.widget.TabLayout
- android:id="@+id/tabLayout"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- app:tabGravity="fill"
- app:tabMode="fixed"
- app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" />
- <android.support.v4.view.ViewPager
- android:id="@+id/viewPager"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- />
然后就是结合了,由于我们通常在ViewPager中放置的是若干个Fragment,所以还得先实现几个Fragment,典型的像下面这个:
- public class MoveFragment extends Fragment implements OnClickListener {
- private String curFlag;
- public static MoveFragment newInstance(String flag){
- MoveFragment fragment = new MoveFragment();
- Bundle bundle = new Bundle();
- bundle.putString("Flag", flag);
- fragment.setArguments(bundle);
- return fragment;
- }
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- Bundle args = getArguments();
- if (args != null) {
- curFlag = args.getString("Flag");
- }
- }
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container,
- Bundle savedInstanceState) {
- super.onCreateView(inflater, container, savedInstanceState);
- View view = inflater.inflate(R.layout.fragment_move, container,false);
- initViews(view);
- return view;
- }
- public void initViews(View view){
- TextView tv=(TextView)view.findViewById(R.id.tv);
- tv.setText(curFlag);
- }
- @Override
- public void onClick(View v) {
- }
- }
接下去就可以使用了:
首先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就可以从中取到要显示的标题了:
- FragmentPagerAdapter pagerAdapter = new FragmentPagerAdapter(getSupportFragmentManager()) {
- @Override
- public int getCount() {
- return fragments.length;
- }
- @Override
- public Fragment getItem(int position) {
- return fragments[position];
- }
- @Override
- public CharSequence getPageTitle(int position) {
- return titles[position];
- }
- };
剩下就是绑定了:
- tabLayout = (TabLayout) findViewById(R.id.tabLayout);
- tabLayout.setupWithViewPager(viewPager);
然而偶尔也会没有ViewPager,TabLayout也会单独使用
那么这个时候需要使用addTab方法为TabLayout添加title了:
- tabLayout = (TabLayout) findViewById(R.id.tabLayout);
- tabLayout.addTab(tabLayout.newTab().setText("Tab 1"));
- tabLayout.addTab(tabLayout.newTab().setText("Tab 2"));
- tabLayout.addTab(tabLayout.newTab().setText("Tab 3"));
- tabLayout.addTab(tabLayout.newTab().setText("Tab 4"));
//下面的内容与Tablayout无关,可以无视
///
接下去要实现一个ViewPager滑动的时候背景颜色过渡变化的效果
在网上找到一个背景颜色可以过渡变化的View,和ViewPager结合使用:
- ViewPager viewPager = (ViewPager) findViewById(R.id.viewPager);
- viewPager.setAdapter(pagerAdapter);
- ColorAnimationView colorAnimationView = (ColorAnimationView) findViewById(R.id.colorAnimationView);
- colorAnimationView.setViewPager(viewPager,titles.length,0xffFF8080,0xff8080FF,0xffffffff,0xff80ff80);
- //you can call this method like this:
- // colorAnimationView.setViewPager(viewPager, titles.length);//use default color
- colorAnimationView.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
- @Override
- public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
- }
- @Override
- public void onPageSelected(int position) {
- }
- @Override
- public void onPageScrollStateChanged(int state) {
- }
- });
布局的时候需要把这个View和ViewPager重叠(FrameLayout)在一起使用,这样就能看出效果了:
- <FrameLayout
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- app:layout_behavior="@string/appbar_scrolling_view_behavior"
- >
- <com.widget.view.ColorAnimationView
- android:id="@+id/colorAnimationView"
- android:layout_width="match_parent"
- android:layout_height="match_parent" />
- <android.support.v4.view.ViewPager
- android:id="@+id/viewPager"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- />
- </FrameLayout>
注意ViewPager中的Fragment不要设置backgroundColor(用屁股想想也知道为什么!)
该类的源码如下:
- package com.widget.view;
- import android.animation.Animator;
- import android.animation.ArgbEvaluator;
- import android.animation.ObjectAnimator;
- import android.animation.ValueAnimator;
- import android.content.Context;
- import android.support.v4.view.ViewPager;
- import android.util.AttributeSet;
- import android.view.View;
- /**
- *
- * @author Administrator
- * @see https://github.com/TaurusXi/GuideBackgroundColorAnimation
- */
- public class ColorAnimationView extends View implements ValueAnimator.AnimatorUpdateListener, Animator.AnimatorListener {
- private static final int WHITE = 0xFFFFFFFF;
- private static final int RED = 0xffFF8080;
- private static final int BLUE = 0xff8080FF;
- private static final int GREEN = 0xff80ff80;
- private static final int DURATION = 3000;
- ValueAnimator colorAnim = null;
- private PageChangeListener mPageChangeListener;
- ViewPager.OnPageChangeListener onPageChangeListener;
- public void setOnPageChangeListener(ViewPager.OnPageChangeListener onPageChangeListener) {
- this.onPageChangeListener = onPageChangeListener;
- }
- /**
- * 这是你唯一需要关心的方法
- * @param mViewPager 你必须在设置 Viewpager 的 Adapter 这后,才能调用这个方法。
- * @param obj ,这个obj实现了 ColorAnimationView.OnPageChangeListener ,实现回调
- * @param count ,viewpager孩子的数量
- * @param colors int... colors ,你需要设置的颜色变化值~~ 如何你传人 空,那么触发默认设置的颜色动画
- * */
- /**
- * This is the only method you need care about.
- * @param mViewPager ,you need set the adpater before you call this.
- * @param count ,this param set the count of the viewpaper's child
- * @param colors ,this param set the change color use (int... colors),
- * so,you could set any length if you want.And by default.
- * if you set nothing , don't worry i have already creat
- * a default good change color!
- * */
- public void setViewPager(ViewPager mViewPager, int count, int... colors) {
- // this.mViewPager = mViewPager;
- if (mViewPager.getAdapter() == null) {
- throw new IllegalStateException("ViewPager does not have adapter instance.");
- }
- mPageChangeListener.setViewPagerChildCount(count);
- mViewPager.setOnPageChangeListener(mPageChangeListener);
- if (colors.length == 0) {
- createDefaultAnimation();
- } else {
- createAnimation(colors);
- }
- }
- public ColorAnimationView(Context context) {
- this(context, null, 0);
- }
- public ColorAnimationView(Context context, AttributeSet attrs) {
- this(context, attrs, 0);
- }
- public ColorAnimationView(Context context, AttributeSet attrs, int defStyleAttr) {
- super(context, attrs, defStyleAttr);
- mPageChangeListener = new PageChangeListener();
- }
- private void seek(long seekTime) {
- if (colorAnim == null) {
- createDefaultAnimation();
- }
- colorAnim.setCurrentPlayTime(seekTime);
- }
- private void createAnimation(int... colors) {
- if (colorAnim == null) {
- colorAnim = ObjectAnimator.ofInt(this,"backgroundColor", colors);
- colorAnim.setEvaluator(new ArgbEvaluator());
- colorAnim.setDuration(DURATION);
- colorAnim.addUpdateListener(this);
- }
- }
- private void createDefaultAnimation() {
- colorAnim = ObjectAnimator.ofInt(this,"backgroundColor", WHITE, RED, BLUE, GREEN);
- colorAnim.setEvaluator(new ArgbEvaluator());
- colorAnim.setDuration(DURATION);
- colorAnim.addUpdateListener(this);
- }
- @Override public void onAnimationStart(Animator animation) {
- }
- @Override public void onAnimationEnd(Animator animation) {
- }
- @Override public void onAnimationCancel(Animator animation) {
- }
- @Override public void onAnimationRepeat(Animator animation) {
- }
- @Override public void onAnimationUpdate(ValueAnimator animation) {
- invalidate();
- // long playtime = colorAnim.getCurrentPlayTime();
- }
- private class PageChangeListener implements ViewPager.OnPageChangeListener {
- private int viewPagerChildCount;
- public void setViewPagerChildCount(int viewPagerChildCount) {
- this.viewPagerChildCount = viewPagerChildCount;
- }
- public int getViewPagerChildCount() {
- return viewPagerChildCount;
- }
- @Override
- public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
- int count = getViewPagerChildCount() - 1;
- if (count != 0) {
- float length = (position + positionOffset) / count;
- int progress = (int) (length * DURATION);
- ColorAnimationView.this.seek(progress);
- }
- // call the method by default
- if (onPageChangeListener!=null){
- onPageChangeListener.onPageScrolled(position,positionOffset,positionOffsetPixels);
- }
- }
- @Override
- public void onPageSelected(int position) {
- if (onPageChangeListener!=null) {
- onPageChangeListener.onPageSelected(position);
- }
- }
- @Override
- public void onPageScrollStateChanged(int state) {
- if (onPageChangeListener!=null) {
- onPageChangeListener.onPageScrollStateChanged(state);
- }
- }
- }
- }
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);
}