TabLayoutの高度な使い方(tabのカスタマイズとインジケータ幅の変更)
7950 ワード
TabLayoutは使いやすいですが、原生の属性は正式なニーズを満たすのが難しいので、自分のtabをカスタマイズしなければなりません(単純な文字や文図の混在形式が可能です)、原生の切り替えはアニメーション効果がなく、インタラクティブな効果が良いために私たちも相応のアニメーションを追加することができます.原生のtabIndicatorは高さと背景色を設定する方法しか提供していません.幅は均一で、少し醜いです.以上の要件を達成するには、ビジネスに基づいて拡張または変更できるツールクラスを用意しました.
/**
* @Desc: TabLayout
* @Author: JiangRongtao
* @Created by: 2018/12/21 0021 13:55
**/
public class TabLayoutAnimUtils {
private TabLayout mTabLayout;
private List mTitleList;
private Context mContext;
public TabLayoutAnimUtils(Context context, TabLayout tabLayout, List titleList) {
this.mContext = context;
this.mTabLayout = tabLayout;
this.mTitleList = titleList;
}
/**
* TabLayout View
* :TabLayout Viewpager mViewPager.setAdapter(), , addOnTabSelectedListener; adapter mCustomViewView ,
*/
public void setCustomViews() {
int mSelectedTabPosition = mTabLayout.getSelectedTabPosition();
for (int i = 0; i < this.mTitleList.size(); i++) {
TabLayout.Tab mTab = this.mTabLayout.getTabAt(i).setCustomView(getTabView(i, mSelectedTabPosition));
if (i == mSelectedTabPosition) {
changeTabSelect(mTab);
} else {
changeTabNormal(mTab);
}
}
}
/**
* TabLayout View
* index View
* : View
*/
private View getTabView(int index, int mSelectedTabPosition) {
// View
View view = LayoutInflater.from(mContext).inflate(R.layout.custom_tab_item_layout, null);
TextView title = (TextView) view.findViewById(R.id.title);
title.setText(mTitleList.get(index));
title.setSelected(index == mSelectedTabPosition ? true : false);
return view;
}
/**
* TabLayout View
* Tab View
*/
public void changeTabSelect(TabLayout.Tab tab) {
final View view = tab.getCustomView();
ObjectAnimator anim = ObjectAnimator
.ofFloat(view, "", 1.0F, 1.1F)
.setDuration(200);
anim.start();
anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
float cVal = (Float) animation.getAnimatedValue();
view.setAlpha(0.5f + (cVal - 1f) * (0.5f / 0.1f));
view.setScaleX(cVal);
view.setScaleY(cVal);
}
});
}
/**
* TabLayout View
*/
public void changeTabNormal(TabLayout.Tab tab) {
final View view = tab.getCustomView();
ObjectAnimator anim = ObjectAnimator
.ofFloat(view, "", 1.0F, 0.9F)
.setDuration(200);
anim.start();
anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
float cVal = (Float) animation.getAnimatedValue();
view.setAlpha(1f - (1f - cVal) * (0.5f / 0.1f));
view.setScaleX(cVal);
view.setScaleY(cVal);
}
});
}
/**
* tablayout
*
* @param tabLayout
* @param margin
*/
public void changeTabIndicatorWidth(final TabLayout tabLayout, final int margin) {
tabLayout.post(new Runnable() {
@Override
public void run() {
try {
Field mTabStripField = tabLayout.getClass().getDeclaredField("mTabStrip");
mTabStripField.setAccessible(true);
LinearLayout mTabStrip = (LinearLayout) mTabStripField.get(tabLayout);
int dp10 = margin == 0 ? 50 : margin;
for (int i = 0; i < mTabStrip.getChildCount(); i++) {
View tabView = mTabStrip.getChildAt(i);
Field mTextViewField = tabView.getClass().getDeclaredField("mTextView");
mTextViewField.setAccessible(true);
TextView mTextView = (TextView) mTextViewField.get(tabView);
tabView.setPadding(0, 0, 0, 0);
int width = 0;
width = mTextView.getWidth();
if (width == 0) {
mTextView.measure(0, 0);
width = mTextView.getMeasuredWidth();
}
LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) tabView.getLayoutParams();
params.width = width;
params.leftMargin = dp10;
params.rightMargin = dp10;
tabView.setLayoutParams(params);
tabView.invalidate();
}
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (Throwable e) {
e.printStackTrace();
}
}
});
}
public void changeTabIndicatorWidth(TabLayout tabLayout) {
changeTabIndicatorWidth(tabLayout, 0);
}
/**
* tablayout
*
* @param tabs
* @param leftDip
* @param rightDip
*/
public void setIndicatorWidth(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();
}
}
}
具体的な使い方の部分コードは以下の通りです. mViewPager.setAdapter(new TabPagerAdapter(getChildFragmentManager(), mFragmentList, mTitles));
mTabLayout.setupWithViewPager(mViewPager);
//
final TabLayoutAnimUtils mTabLayoutAnimUtils = new TabLayoutAnimUtils(mContext, mTabLayout, mTitles);
mTabLayoutAnimUtils.changeTabIndicatorWidth(mTabLayout);
mTabLayoutAnimUtils.setCustomViews();
mTabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
@Override
public void onTabSelected(TabLayout.Tab tab) {
mTabLayoutAnimUtils.changeTabSelect(tab);
}
@Override
public void onTabUnselected(TabLayout.Tab tab) {
mTabLayoutAnimUtils.changeTabNormal(tab);
}
@Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
注意:TabLayoutとViewpagerを併用する場合はmViewPager.setAdapter()は、メソッドを初期化し、addOnTabSelectedListener;adapterリフレッシュはmCustomViewを空にします.つまり、あなたが設定したmCustomViewは表示されません.