Android 项目常用滑动页卡模式ViewPager+MagicIndicator(三)
TabLayout设置切换水平布局展示Tabs,大家也许会想到各种第三方的,如:XTabLayout,还可以直接使用Button等控件来实现效果,那这里就简单的介绍并总结一下TabLayout的一些用法:
1.先看看布局代码:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/main_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:orientation="vertical"
tools:context=".view.largeamount.view.ApplyHistoryActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/colorWhite"
android:orientation="horizontal">
<TextView
android:id="@+id/backButton"
android:layout_width="50dp"
android:layout_height="match_parent"
android:drawableStart="@mipmap/common_nav_icon_back"
android:paddingStart="15dp"/>
<android.support.design.widget.TabLayout
android:id="@+id/tabLayout"
app:tabIndicatorColor="@color/blue_one"
android:layout_width="match_parent"
app:tabIndicatorHeight="3dp"
android:layout_height="wrap_content">
<android.support.design.widget.TabItem
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/text_coin_subtitle"/>
<android.support.design.widget.TabItem
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/menu_borrowing_money"/>
</android.support.design.widget.TabLayout>
</LinearLayout>
<android.support.v4.view.ViewPager
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
</LinearLayout>
使用TabLayout,要让Activity继承自AppCompatActivity,但有时候你项目里的BaseActivity却是继承自FragmentActivity的,AppCompatActivity 也是extends FragmentActivity的。可以把BaseActivity extends AppCompatActivity。如果不想这么做也可以,可以指定当前Activity的theme为:
android:theme="@style/Theme.AppCompat"
然后build.gradle文件在dependencies里加上
compile 'com.android.support:design:25.0.0'
TabLayout的一些基本属性:
app:tabIndicatorColor :指示条的颜色
app:tabIndicatorHeight :指示条的高度
app:tabSelectedTextColor : tab被选中时的字体颜色
app:tabTextColor : tab未被选中时的字体颜色
app:tabMode="scrollable" : 默认是fixed:固定的,标签很多时候会被挤压,不能滑动。
若是不需要指示器显示的话可以加上下面的代码:
高度设置为0:
app:tabIndicatorHeight="0dp"
还可以设置成透明色:
app:tabIndicatorColor="@color/transparent"
2.TabItem的一些常识:
设置其字体的大小:
app:tabTextAppearance="@android:style/TextAppearance.Holo.Large"
<style name="TextAppearance.Holo.Large" parent="TextAppearance.Large" />
<style name="TextAppearance.Holo.Medium"parent="TextAppearance.Medium"/>
<style name="TextAppearance.Holo.Small" parent="TextAppearance.Small" />
3.添加图标:
Tab是使用adapter中的getPageTitle()方法做其显示的内容,这个方法返回类型为CharSequence。于是,我们可以在PagerAdapter中重写getPageTitle()方法,创建一个SpannableString,而将图标放置在ImageSpan中,设置在SpannableString中:
public class ImageTabActivity extends AppCompatActivity {
ViewPager mViewPager;
ListFragment mFragment1;
ListFragment mFragment2;
ListFragment mFragment3;
PagerAdapter mPagerAdapter;
private TabLayout mTabLayout;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.image_tab_layout);
initView(savedInstanceState);
}
private void initView(Bundle savedInstanceState) {
mViewPager = (ViewPager) findViewById(R.id.view_pager);
mViewPager.setOffscreenPageLimit(2);
mTabLayout = (TabLayout) findViewById(R.id.toolbar_tab);
if (savedInstanceState == null) {
mFragment1 = new ListFragment();
mFragment1.initData('a', 'z');
mFragment2 = new ListFragment();
mFragment2.initData('A', 'Z');
mFragment3 = new ListFragment();
mFragment3.initData('c', 'x');
}
mPagerAdapter = new PagerAdapter(getSupportFragmentManager());
mViewPager.setAdapter(mPagerAdapter);
mViewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(mTabLayout));
mTabLayout.setupWithViewPager(mViewPager);
mTabLayout.addOnTabSelectedListener(new TabLayout.ViewPagerOnTabSelectedListener(mViewPager));
}
private int[] imageResId = {
R.mipmap.login_qq,
R.mipmap.login_sina,
R.mipmap.login_wechat
};
public class PagerAdapter extends FragmentPagerAdapter {
public PagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public CharSequence getPageTitle(int position){
Drawable image = ContextCompat.getDrawable(ImageTabActivity.this, imageResId[position]);
image.setBounds(0, 0, image.getIntrinsicWidth(), image.getIntrinsicHeight());
SpannableString sb = new SpannableString(" ");
ImageSpan imageSpan = new ImageSpan(image, ImageSpan.ALIGN_BOTTOM);
sb.setSpan(imageSpan, 0, 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
return sb;
}
@Override
public Fragment getItem(int position) {
if (position == 0) {
return mFragment1;
} else if (position == 1) {
return mFragment2;
}else if (position == 2) {
return mFragment3;
}
return null;
}
@Override
public int getCount() {
return 3;
}
}
}
public class CustomTabItemActivity extends AppCompatActivity {
ViewPager mViewPager;
ListFragment mFragment1;
ListFragment mFragment2;
PagerAdapter mPagerAdapter;
private TabLayout mTabLayout;
private ArrayList<String> titles = new ArrayList<>();
private boolean isSelected = false;
private int[] tabIcons = {
R.mipmap.icon_down,
R.mipmap.icon_down,
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.custom_tabitem_layout);
initView(savedInstanceState);
}
private void initView(Bundle savedInstanceState) {
mViewPager = (ViewPager) findViewById(R.id.view_pager);
mViewPager.setOffscreenPageLimit(2);
mTabLayout = (TabLayout) findViewById(R.id.toolbar_tab);
if (savedInstanceState == null) {
mFragment1 = new ListFragment();
mFragment1.initData('a', 'z');
mFragment2 = new ListFragment();
mFragment2.initData('A', 'Z');
}
titles.add("最新");
titles.add("最热");
mPagerAdapter = new PagerAdapter(getSupportFragmentManager());
mViewPager.setAdapter(mPagerAdapter);
mViewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(mTabLayout));
mTabLayout.setupWithViewPager(mViewPager);
mTabLayout.getTabAt(0).setCustomView(getTabView(0));
mTabLayout.getTabAt(1).setCustomView(getTabView(1));
mTabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
@Override
public void onTabSelected(TabLayout.Tab tab) {
changeTabStatus(tab, true);
}
@Override
public void onTabUnselected(TabLayout.Tab tab) {
changeTabStatus(tab, false);
}
@Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
}
private void changeTabStatus(TabLayout.Tab tab, boolean selected) {
View view = tab.getCustomView();
final ImageView imgTitle = (ImageView) view.findViewById(R.id.img_title);
TextView txtTitle = (TextView) view.findViewById(R.id.txt_title);
imgTitle.setVisibility(View.VISIBLE);
if (selected) {
txtTitle.setTextColor(Color.parseColor("#0EA73C"));
startPropertyAnim(imgTitle);
} else {
txtTitle.setTextColor(Color.parseColor("#7f7f7f"));
imgTitle.setVisibility(View.INVISIBLE);
}
}
public View getTabView(final int position) {
final View view = LayoutInflater.from(this).inflate(R.layout.item_tab, null);
TextView txtTitle = (TextView) view.findViewById(R.id.txt_title);
final ImageView imgTitle = (ImageView) view.findViewById(R.id.img_title);
imgTitle.setImageResource(tabIcons[position]);
txtTitle.setText(titles.get(position));
if (position == 0) {
txtTitle.setTextColor(Color.parseColor("#057523"));
} else {
imgTitle.setVisibility(View.INVISIBLE);
txtTitle.setTextColor(Color.parseColor("#ced0d3"));
}
view.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
startPropertyAnim(imgTitle);
mViewPager.setCurrentItem(position);
}
});
return view;
}
private void startPropertyAnim(ImageView v) {
ObjectAnimator anim = ObjectAnimator.ofFloat(v, "rotation", 180f, 360f);
anim.setDuration(500);
anim.start();
}
public class PagerAdapter extends FragmentPagerAdapter {
public PagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int position) {
if (position == 0) {
return mFragment1;
} else if (position == 1) {
return mFragment2;
}
return null;
}
@Override
public int getCount() {
return 2;
}
}
}
4.TabLayout的指示器的高度、颜色都可以设置,下面来设置一下宽度:
/**
* @desc: 设置tablayout的指示器的宽度
*/
private void initView() {
mTabLayout.post(new Runnable() {
@Override
public void run() {
setIndicator(mTabLayout, 40, 40);
}
});
}
/**
* @desc: 设置tab指示器的宽度
*/
public void setIndicator(TabLayout tabs, int leftDip, int rightDip) {
Class<?> tabLayout = tabs.getClass();
Field tabStrip = null;
try {
tabStrip = tabLayout.getDeclaredField("mTabStrip");
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
tabStrip.setAccessible(true);
LinearLayout llTab = null;
try {
llTab = (LinearLayout) tabStrip.get(tabs);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
int left = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, leftDip, Resources.getSystem().getDisplayMetrics());
int right = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, rightDip, Resources.getSystem().getDisplayMetrics());
for (int i = 0; i < llTab.getChildCount(); i++) {
View child = llTab.getChildAt(i);
child.setPadding(0, 0, 0, 0);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.MATCH_PARENT, 1);
params.leftMargin = left;
params.rightMargin = right;
child.setLayoutParams(params);
child.invalidate();
}
}