點擊不同 Tab 時,底部紅色條平滑滑動到對應位置,寬度佔單個 Tab 1/4。
// mTabSelector 為底部指示器 ImageView,寬度 = 螢幕寬 / Tab數量
RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) mTabSelector.getLayoutParams();
params.leftMargin = (currentIndex - 1) * params.width; // 0-based index
mTabSelector.setLayoutParams(params);
ObjectAnimator animator = ObjectAnimator.ofInt(mTabSelector, "leftMargin",
mTabSelector.getLeft(), targetLeft);
animator.setDuration(300);
animator.addUpdateListener(animation -> {
RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) mTabSelector.getLayoutParams();
lp.leftMargin = (int) animation.getAnimatedValue();
mTabSelector.setLayoutParams(lp);
});
animator.start();
HorizontalScrollView 或 LinearLayout,內部包含 Tab 按鈕與指示器。onSizeChanged 計算:width = getMeasuredWidth() / tabCount。OnClickListener 切換 Tab 並啟動指示器動畫。ViewPager,在 OnPageChangeListener.onPageScrolled 即時更新 leftMargin = positionOffset * indicatorWidth + position * indicatorWidth。TabLayout(app:tabIndicator、tabGravity、tabMode)核心只需一行:根據索引計算 leftMargin 並套用 LayoutParams,再包裝動畫即得絲滑體驗。