不说废话了,直接上代码:
自定义View
/**
*
* author : Harvey
* time : 2018/06/14
* desc :navigation icon自定义view,可以通过设置透明度实现类似微信效果
*
*/
public class NavigationIconView extends View {
private Paint mPaint;
private Paint textPaint;
private Bitmap selectedBitmap;
private Bitmap unselectedBitmap;
private Rect textRect;
private int unSelectColor;
private int selectColor;
private String tabText;
private int alphaValue = 0;
private boolean selected;
private int mWidth;
private int textWidth;
private float iconPadding;//默认icon和文字间距10
private ArgbEvaluator mColorEvaluator;
private int textColor;
public NavigationIconView(Context context) {
super(context);
}
public NavigationIconView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs);
}
public NavigationIconView(Context context, AttributeSet attrs, int defStyleAttr, Paint mPaint) {
super(context, attrs, defStyleAttr);
init(context, attrs);
}
public final void init(Context context, AttributeSet attrs) {
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.NavigationIconView);
int selectImg = typedArray.getResourceId(R.styleable.NavigationIconView_tab_select_img, android.R.drawable.ic_menu_add);
int unSelectImg = typedArray.getResourceId(R.styleable.NavigationIconView_tab_unSelect_img, android.R.drawable.ic_menu_add);
selectColor = typedArray.getColor(R.styleable.NavigationIconView_tab_select_text_color, Color.BLACK);
unSelectColor = typedArray.getColor(R.styleable.NavigationIconView_tab_unSelect_text_color, Color.BLACK);
tabText = typedArray.getString(R.styleable.NavigationIconView_tab_text);
float tabTextSize = typedArray.getDimension(R.styleable.NavigationIconView_tab_textSize, 14f);
iconPadding = typedArray.getDimension(R.styleable.NavigationIconView_img_padding, 18f);
selected = typedArray.getBoolean(R.styleable.NavigationIconView_selected, false);
typedArray.recycle();
unselectedBitmap = createBitmap(unSelectImg);
selectedBitmap = createBitmap(selectImg);
mPaint = new Paint();
mPaint.setAntiAlias(true);
textPaint = new Paint();
textPaint.setTextSize(tabTextSize);
textPaint.setAntiAlias(true);
//获得绘制文本的宽和高
textRect = new Rect();
mPaint.getTextBounds(tabText, 0, tabText.length(), textRect);
mColorEvaluator = new ArgbEvaluator();
if (selected) {
textColor = selectColor;
alphaValue = 255;
} else {
textColor = unSelectColor;
alphaValue = 0;
}
textWidth = getTextWidth(textPaint,tabText);
}
private Bitmap createBitmap(int resId) {
return decodeResource(getResources(), resId);
}
private Bitmap decodeResource(Resources resources, int id) {
BitmapFactory.Options options = new BitmapFactory.Options();
TypedValue value = new TypedValue();
getResources().openRawResource(id, value);
options.inTargetDensity = value.density;//float scale = targetDensity / (float)density;//缩放比例
return BitmapFactory.decodeResource(resources, id, options);
}
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
mWidth = Math.max(unselectedBitmap.getWidth(), textWidth);
int mHeight = unselectedBitmap.getHeight() + textRect.height() + (int) iconPadding;
if (getLayoutParams().width == ViewGroup.LayoutParams.WRAP_CONTENT
&& getLayoutParams().height == ViewGroup.LayoutParams.WRAP_CONTENT) {
setMeasuredDimension(mWidth, mHeight);
} else if (getLayoutParams().width == ViewGroup.LayoutParams.WRAP_CONTENT) {
setMeasuredDimension(mWidth, heightSize);
} else if (getLayoutParams().height == ViewGroup.LayoutParams.WRAP_CONTENT) {
setMeasuredDimension(widthSize, mHeight);
}
}
@Override
protected void onDraw(Canvas canvas) {
mPaint.setAlpha(255 - alphaValue);
canvas.drawBitmap(unselectedBitmap, getWidth() / 2 - unselectedBitmap.getWidth() / 2, 0, mPaint); //开始在画板上画原图
mPaint.setAlpha(alphaValue);
canvas.drawBitmap(selectedBitmap, getWidth() / 2 - unselectedBitmap.getWidth() / 2, 0, mPaint);
//绘制文字
textPaint.setColor(textColor);
canvas.drawText(tabText, getWidth() / 2 - textWidth / 2, unselectedBitmap.getHeight() + textRect.height() / 2 + (int) iconPadding, textPaint);
}
/**
* 当滑动的时候来调用此方法渐变
*
* @param percent =1选中 =0不选中
*/
public final void changePage(float percent, boolean isNext) {
if (isNext) {
textColor = (int) mColorEvaluator.evaluate(percent, unSelectColor, selectColor);//下一tab的颜色值
alphaValue = (int) (255 * percent);
} else {
textColor = (int) mColorEvaluator.evaluate(percent, selectColor, unSelectColor);//当前tab的颜色值
alphaValue = (int) (255 * (1 - percent));
}
invalidate();
}
private int getTextWidth(Paint paint, String str) {
int iRet = 0;
if (str != null && str.length() > 0) {
int len = str.length();
float[] widths = new float[len];
paint.getTextWidths(str, widths);
for (int j = 0; j < len; j++) {
iRet += (int) Math.ceil(widths[j]);
}
}
return iRet;
}
}
此处要说明一下,不知为何
textRect = new Rect();
mPaint.getTextBounds(tabText, 0, tabText.length(), textRect);
这种方式得到的文字宽度不对。。。只好换了方法。请路过的大神指导一下~
attr文件定义
布局文件
Activity部分代码:
public void initView() {
mFragments.add(requirementFragment);
mFragments.add(equipmentStateFragment);
mFragments.add(equipmentManageFragment);
FragmentAdapter adapter = new FragmentAdapter(getSupportFragmentManager(), mFragments);// 初始化adapter
viewPager.setAdapter(adapter); // 设置adapter
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
// 当前总的偏移量
float currentPositionOffsetSum = position + positionOffset;
// 上次滑动的总偏移量大于此次滑动的总偏移量,页面从右向左进入(手指从右向左滑动)
boolean rightToLeft = mLastPositionOffsetSum <= currentPositionOffsetSum;
if (currentPositionOffsetSum == mLastPositionOffsetSum) return;
int enterPosition;
int leavePosition;
float percent;
if (rightToLeft) { // 从右向左滑
enterPosition = (positionOffset == 0.0f) ? position : position + 1;
leavePosition = enterPosition - 1;
percent = (positionOffset == 0.0f) ? 1.0f : positionOffset;
} else { // 从左向右滑
enterPosition = position;
leavePosition = position + 1;
percent = 1 - positionOffset;
}
switchTab(enterPosition, leavePosition, percent);
mLastPositionOffsetSum = currentPositionOffsetSum;
}
@Override
public void onPageSelected(int position) {
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
}
private void switchTab(int enterPosition, int leavePosition, float percent) {
switch (leavePosition) {
case 0:
requirementIv.changePage(percent, false);
equipStateIv.changePage(percent, true);
equipManageIv.changePage(1, false);
break;
case 1:
switch (enterPosition) {
case 0:
equipStateIv.changePage(percent,false);
requirementIv.changePage(percent,true);
equipManageIv.changePage(1,false);
break;
case 2:
equipStateIv.changePage(percent,false);
equipManageIv.changePage(percent,true);
requirementIv.changePage(1,false);
break;
}
break;
case 2:
equipManageIv.changePage(percent,false);
equipStateIv.changePage(percent,true);
requirementIv.changePage(1,false);
break;
}
}
Acitivty中判断viewpager滑动与上一篇文章用到同样的方法。https://www.jianshu.com/p/354c3a89eccc
完。