android 底部标签栏CommonTabLayout搭建项目底部菜单(带消息提醒)(2)

import android.animation.ValueAnimator;

import android.annotation.SuppressLint;

import android.content.Context;

import android.content.res.TypedArray;

import android.graphics.Canvas;

import android.graphics.Color;

import android.graphics.Paint;

import android.graphics.Path;

import android.graphics.Rect;

import android.graphics.drawable.GradientDrawable;

import android.os.Bundle;

import android.os.Parcelable;

import android.support.v4.app.Fragment;

import android.support.v4.app.FragmentActivity;

import android.util.AttributeSet;

import android.util.SparseArray;

import android.util.TypedValue;

import android.view.Gravity;

import android.view.View;

import android.view.ViewGroup;

import android.view.animation.OvershootInterpolator;

import android.widget.FrameLayout;

import android.widget.ImageView;

import android.widget.LinearLayout;

import android.widget.TextView;

import java.util.ArrayList;

/** 没有继承HorizontalScrollView不能滑动,对于ViewPager无依赖 */

@SuppressLint(“NewApi”)

public class CommonTabLayout extends FrameLayout implements ValueAnimator.AnimatorUpdateListener {

private Context mContext;

private ArrayList mTabEntitys = new ArrayList<>();

private LinearLayout mTabsContainer;

private int mCurrentTab;

private int mLastTab;

private int mTabCount;

/** 用于绘制显示器 */

private Rect mIndicatorRect = new Rect();

private GradientDrawable mIndicatorDrawable = new GradientDrawable();

private Paint mRectPaint = new Paint(Paint.ANTI_ALIAS_FLAG);

private Paint mDividerPaint = new Paint(Paint.ANTI_ALIAS_FLAG);

private Paint mTrianglePaint = new Paint(Paint.ANTI_ALIAS_FLAG);

private Path mTrianglePath = new Path();

private static final int STYLE_NORMAL = 0;

private static final int STYLE_TRIANGLE = 1;

private static final int STYLE_BLOCK = 2;

private int mIndicatorStyle = STYLE_NORMAL;

private float mTabPadding;

private boolean mTabSpaceEqual;

private float mTabWidth;

/** indicator */

private int mIndicatorColor;

private float mIndicatorHeight;

private float mIndicatorWidth;

private float mIndicatorCornerRadius;

private float mIndicatorMarginLeft;

private float mIndicatorMarginTop;

private float mIndicatorMarginRight;

private float mIndicatorMarginBottom;

private long mIndicatorAnimDuration;

private boolean mIndicatorAnimEnable;

private boolean mIndicatorBounceEnable;

private int mIndicatorGravity;

/** underline */

private int mUnderlineColor;

private float mUnderlineHeight;

private int mUnderlineGravity;

/** divider */

private int mDividerColor;

private float mDividerWidth;

private float mDividerPadding;

/** title */

private static final int TEXT_BOLD_NONE = 0;

private static final int TEXT_BOLD_WHEN_SELECT = 1;

private static final int TEXT_BOLD_BOTH = 2;

private float mTextsize;

private int mTextSelectColor;

private int mTextUnselectColor;

private int mTextBold;

private boolean mTextAllCaps;

/** icon */

private boolean mIconVisible;

private int mIconGravity;

private float mIconWidth;

private float mIconHeight;

private float mIconMargin;

private int mHeight;

/** anim */

private ValueAnimator mValueAnimator;

private OvershootInterpolator mInterpolator = new OvershootInterpolator(1.5f);

private FragmentChangeManager mFragmentChangeManager;

public CommonTabLayout(Context context) {

this(context, null, 0);

}

public CommonTabLayout(Context context, AttributeSet attrs) {

this(context, attrs, 0);

}

@SuppressLint(“NewApi”)

public CommonTabLayout(Context context, AttributeSet attrs, int defStyleAttr) {

super(context, attrs, defStyleAttr);

setWillNotDraw(false);//重写onDraw方法,需要调用这个方法来清除flag

setClipChildren(false);

setClipToPadding(false);

this.mContext = context;

mTabsContainer = new LinearLayout(context);

addView(mTabsContainer);

obtainAttributes(context, attrs);

//get layout_height

String height = attrs.getAttributeValue(“http://schemas.android.com/apk/res/android”, “layout_height”);

//create ViewPager

if (height.equals(ViewGroup.LayoutParams.MATCH_PARENT + “”)) {

} else if (height.equals(ViewGroup.LayoutParams.WRAP_CONTENT + “”)) {

} else {

int[] systemAttrs = {android.R.attr.layout_height};

TypedArray a = context.obtainStyledAttributes(attrs, systemAttrs);

mHeight = a.getDimensionPixelSize(0, ViewGroup.LayoutParams.WRAP_CONTENT);

a.recycle();

}

mValueAnimator = ValueAnimator.ofObject(new PointEvaluator(), mLastP, mCurrentP);

mValueAnimator.addUpdateListener(this);

}

private void obtainAttributes(Context context, AttributeSet attrs) {

TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.CommonTabLayout);

mIndicatorStyle = ta.getInt(R.styleable.CommonTabLayout_tl_indicator_style, 0);

mIndicatorColor = ta.getColor(R.styleable.CommonTabLayout_tl_indicator_color, Color.parseColor(mIndicatorStyle == STYLE_BLOCK ? “#4B6A87” : “#ffffff”));

mIndicatorHeight = ta.getDimension(R.styleable.CommonTabLayout_tl_indicator_height,

dp2px(mIndicatorStyle == STYLE_TRIANGLE ? 4 : (mIndicatorStyle == STYLE_BLOCK ? -1 : 2)));

mIndicatorWidth = ta.getDimension(R.styleable.CommonTabLayout_tl_indicator_width, dp2px(mIndicatorStyle == STYLE_TRIANGLE ? 10 : -1));

mIndicatorCornerRadius = ta.getDimension(R.styleable.CommonTabLayout_tl_indicator_corner_radius, dp2px(mIndicatorStyle == STYLE_BLOCK ? -1 : 0));

mIndicatorMarginLeft = ta.getDimension(R.styleable.CommonTabLayout_tl_indicator_margin_left, dp2px(0));

mIndicatorMarginTop = ta.getDimension(R.styleable.CommonTabLayout_tl_indicator_margin_top, dp2px(mIndicatorStyle == STYLE_BLOCK ? 7 : 0));

mIndicatorMarginRight = ta.getDimension(R.styleable.CommonTabLayout_tl_indicator_margin_right, dp2px(0));

mIndicatorMarginBottom = ta.getDimension(R.styleable.CommonTabLayout_tl_indicator_margin_bottom, dp2px(mIndicatorStyle == STYLE_BLOCK ? 7 : 0));

mIndicatorAnimEnable = ta.getBoolean(R.styleable.CommonTabLayout_tl_indicator_anim_enable, true);

mIndicatorBounceEnable = ta.getBoolean(R.styleable.CommonTabLayout_tl_indicator_bounce_enable, true);

mIndicatorAnimDuration = ta.getInt(R.styleable.CommonTabLayout_tl_indicator_anim_duration, -1);

mIndicatorGravity = ta.getInt(R.styleable.CommonTabLayout_tl_indicator_gravity, Gravity.BOTTOM);

mUnderlineColor = ta.getColor(R.styleable.CommonTabLayout_tl_underline_color, Color.parseColor(“#ffffff”));

mUnderlineHeight = ta.getDimension(R.styleable.CommonTabLayout_tl_underline_height, dp2px(0));

mUnderlineGravity = ta.getInt(R.styleable.CommonTabLayout_tl_underline_gravity, Gravity.BOTTOM);

mDividerColor = ta.getColor(R.styleable.CommonTabLayout_tl_divider_color, Color.parseColor(“#ffffff”));

mDividerWidth = ta.getDimension(R.styleable.CommonTabLayout_tl_divider_width, dp2px(0));

mDividerPadding = ta.getDimension(R.styleable.CommonTabLayout_tl_divider_padding, dp2px(12));

mTextsize = ta.getDimension(R.styleable.CommonTabLayout_tl_textsize, sp2px(13f));

mTextSelectColor = ta.getColor(R.styleable.CommonTabLayout_tl_textSelectColor, Color.parseColor(“#ffffff”));

mTextUnselectColor = ta.getColor(R.styleable.CommonTabLayout_tl_textUnselectColor, Color.parseColor(“#AAffffff”));

mTextBold = ta.getInt(R.styleable.CommonTabLayout_tl_textBold, TEXT_BOLD_NONE);

mTextAllCaps = ta.getBoolean(R.styleable.CommonTabLayout_tl_textAllCaps, false);

mIconVisible = ta.getBoolean(R.styleable.CommonTabLayout_tl_iconVisible, true);

mIconGravity = ta.getInt(R.styleable.CommonTabLayout_tl_iconGravity, Gravity.TOP);

mIconWidth = ta.getDimension(R.styleable.CommonTabLayout_tl_iconWidth, dp2px(0));

mIconHeight = ta.getDimension(R.styleable.CommonTabLayout_tl_iconHeight, dp2px(0));

mIconMargin = ta.getDimension(R.styleable.CommonTabLayout_tl_iconMargin, dp2px(2.5f));

mTabSpaceEqual = ta.getBoolean(R.styleable.CommonTabLayout_tl_tab_space_equal, true);

mTabWidth = ta.getDimension(R.styleable.CommonTabLayout_tl_tab_width, dp2px(-1));

mTabPadding = ta.getDimension(R.styleable.CommonTabLayout_tl_tab_padding, mTabSpaceEqual || mTabWidth > 0 ? dp2px(0) : dp2px(10));

ta.recycle();

}

public void setTabData(ArrayList tabEntitys) {

if (tabEntitys == null || tabEntitys.size() == 0) {

throw new IllegalStateException(“TabEntitys can not be NULL or EMPTY !”);

}

this.mTabEntitys.clear();

this.mTabEntitys.addAll(tabEntitys);

notifyDataSetChanged();

}

/** 关联数据支持同时切换fragments */

public void setTabData(ArrayList tabEntitys, FragmentActivity fa, int containerViewId, ArrayList fragments) {

mFragmentChangeManager = new FragmentChangeManager(fa.getSupportFragmentManager(), containerViewId, fragments);

setTabData(tabEntitys);

}

/** 更新数据 */

public void notifyDataSetChanged() {

mTabsContainer.removeAllViews();

this.mTabCount = mTabEntitys.size();

View tabView;

for (int i = 0; i < mTabCount; i++) {

if (mIconGravity == Gravity.LEFT) {

tabView = View.inflate(mContext, R.layout.layout_tab_left, null);

} else if (mIconGravity == Gravity.RIGHT) {

tabView = View.inflate(mContext, R.layout.layout_tab_right, null);

} else if (mIconGravity == Gravity.BOTTOM) {

tabView = View.inflate(mContext, R.layout.layout_tab_bottom, null);

} else {

tabView = View.inflate(mContext, R.layout.layout_tab_top, null);

}

tabView.setTag(i);

addTab(i, tabView);

}

updateTabStyles();

}

/** 创建并添加tab */

private void addTab(final int position, View tabView) {

TextView tv_tab_title = (TextView) tabView.findViewById(R.id.tv_tab_title);

tv_tab_title.setText(mTabEntitys.get(position).getTabTitle());

ImageView iv_tab_icon = (ImageView) tabView.findViewById(R.id.iv_tab_icon);

iv_tab_icon.setImageResource(mTabEntitys.get(position).getTabUnselectedIcon());

tabView.setOnClickListener(new OnClickListener() {

@Override

public void onClick(View v) {

int position = (Integer) v.getTag();

if (mCurrentTab != position) {

setCurrentTab(position);

if (mListener != null) {

mListener.onTabSelect(position);

}

} else {

if (mListener != null) {

mListener.onTabReselect(position);

}

}

}

});

/** 每一个Tab的布局参数 */

LinearLayout.LayoutParams lp_tab = mTabSpaceEqual ?

new LinearLayout.LayoutParams(0, LayoutParams.MATCH_PARENT, 1.0f) :

new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);

if (mTabWidth > 0) {

lp_tab = new LinearLayout.LayoutParams((int) mTabWidth, LayoutParams.MATCH_PARENT);

}

mTabsContainer.addView(tabView, position, lp_tab);

}

private void updateTabStyles() {

for (int i = 0; i < mTabCount; i++) {

View tabView = mTabsContainer.getChildAt(i);

tabView.setPadding((int) mTabPadding, 0, (int) mTabPadding, 0);

TextView tv_tab_title = (TextView) tabView.findViewById(R.id.tv_tab_title);

tv_tab_title.setTextColor(i == mCurrentTab ? mTextSelectColor : mTextUnselectColor);

tv_tab_title.setTextSize(TypedValue.COMPLEX_UNIT_PX, mTextsize);

// tv_tab_title.setPadding((int) mTabPadding, 0, (int) mTabPadding, 0);

if (mTextAllCaps) {

tv_tab_title.setText(tv_tab_title.getText().toString().toUpperCase());

}

if (mTextBold == TEXT_BOLD_BOTH) {

tv_tab_title.getPaint().setFakeBoldText(true);

} else if (mTextBold == TEXT_BOLD_NONE) {

tv_tab_title.getPaint().setFakeBoldText(false);

}

ImageView iv_tab_icon = (ImageView) tabView.findViewById(R.id.iv_tab_icon);

if (mIconVisible) {

iv_tab_icon.setVisibility(View.VISIBLE);

CustomTabEntity tabEntity = mTabEntitys.get(i);

iv_tab_icon.setImageResource(i == mCurrentTab ? tabEntity.getTabSelectedIcon() : tabEntity.getTabUnselectedIcon());

LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(

mIconWidth <= 0 ? LinearLayout.LayoutParams.WRAP_CONTENT : (int) mIconWidth,

mIconHeight <= 0 ? LinearLayout.LayoutParams.WRAP_CONTENT : (int) mIconHeight);

if (mIconGravity == Gravity.LEFT) {

lp.rightMargin = (int) mIconMargin;

} else if (mIconGravity == Gravity.RIGHT) {

lp.leftMargin = (int) mIconMargin;

} else if (mIconGravity == Gravity.BOTTOM) {

lp.topMargin = (int) mIconMargin;

} else {

lp.bottomMargin = (int) mIconMargin;

}

iv_tab_icon.setLayoutParams(lp);

} else {

iv_tab_icon.setVisibility(View.GONE);

}

}

}

private void updateTabSelection(int position) {

for (int i = 0; i < mTabCount; ++i) {

View tabView = mTabsContainer.getChildAt(i);

final boolean isSelect = i == position;

TextView tab_title = (TextView) tabView.findViewById(R.id.tv_tab_title);

tab_title.setTextColor(isSelect ? mTextSelectColor : mTextUnselectColor);

ImageView iv_tab_icon = (ImageView) tabView.findViewById(R.id.iv_tab_icon);

CustomTabEntity tabEntity = mTabEntitys.get(i);

iv_tab_icon.setImageResource(isSelect ? tabEntity.getTabSelectedIcon() : tabEntity.getTabUnselectedIcon());

if (mTextBold == TEXT_BOLD_WHEN_SELECT) {

tab_title.getPaint().setFakeBoldText(isSelect);

}

}

}

private void calcOffset() {

final View currentTabView = mTabsContainer.getChildAt(this.mCurrentTab);

mCurrentP.left = currentTabView.getLeft();

mCurrentP.right = currentTabView.getRight();

final View lastTabView = mTabsContainer.getChildAt(this.mLastTab);

mLastP.left = lastTabView.getLeft();

mLastP.right = lastTabView.getRight();

// Log.d(“AAA”, “mLastP—>” + mLastP.left + “&” + mLastP.right);

// Log.d(“AAA”, “mCurrentP—>” + mCurrentP.left + “&” + mCurrentP.right);

if (mLastP.left == mCurrentP.left && mLastP.right == mCurrentP.right) {

invalidate();

} else {

mValueAnimator.setObjectValues(mLastP, mCurrentP);

if (mIndicatorBounceEnable) {

mValueAnimator.setInterpolator(mInterpolator);

}

if (mIndicatorAnimDuration < 0) {

mIndicatorAnimDuration = mIndicatorBounceEnable ? 500 : 250;

}

mValueAnimator.setDuration(mIndicatorAnimDuration);

mValueAnimator.start();

}

}

private void calcIndicatorRect() {

View currentTabView = mTabsContainer.getChildAt(this.mCurrentTab);

float left = currentTabView.getLeft();

float right = currentTabView.getRight();

mIndicatorRect.left = (int) left;

mIndicatorRect.right = (int) right;

if (mIndicatorWidth < 0) { //indicatorWidth小于0时,原jpardogo’s PagerSlidingTabStrip

} else {//indicatorWidth大于0时,圆角矩形以及三角形

float indicatorLeft = currentTabView.getLeft() + (currentTabView.getWidth() - mIndicatorWidth) / 2;

mIndicatorRect.left = (int) indicatorLeft;

mIndicatorRect.right = (int) (mIndicatorRect.left + mIndicatorWidth);

}

}

@Override

public void onAnimationUpdate(ValueAnimator animation) {

View currentTabView = mTabsContainer.getChildAt(this.mCurrentTab);

IndicatorPoint p = (IndicatorPoint) animation.getAnimatedValue();

mIndicatorRect.left = (int) p.left;

mIndicatorRect.right = (int) p.right;

if (mIndicatorWidth < 0) { //indicatorWidth小于0时,原jpardogo’s PagerSlidingTabStrip

} else {//indicatorWidth大于0时,圆角矩形以及三角形

float indicatorLeft = p.left + (currentTabView.getWidth() - mIndicatorWidth) / 2;

mIndicatorRect.left = (int) indicatorLeft;

mIndicatorRect.right = (int) (mIndicatorRect.left + mIndicatorWidth);

}

invalidate();

}

private boolean mIsFirstDraw = true;

@Override

protected void onDraw(Canvas canvas) {

super.onDraw(canvas);

if (isInEditMode() || mTabCount <= 0) {

return;

}

int height = getHeight();

int paddingLeft = getPaddingLeft();

// draw divider

if (mDividerWidth > 0) {

mDividerPaint.setStrokeWidth(mDividerWidth);

mDividerPaint.setColor(mDividerColor);

for (int i = 0; i < mTabCount - 1; i++) {

View tab = mTabsContainer.getChildAt(i);

canvas.drawLine(paddingLeft + tab.getRight(), mDividerPadding, paddingLeft + tab.getRight(), height - mDividerPadding, mDividerPaint);

}

}

// draw underline

if (mUnderlineHeight > 0) {

mRectPaint.setColor(mUnderlineColor);

if (mUnderlineGravity == Gravity.BOTTOM) {

canvas.drawRect(paddingLeft, height - mUnderlineHeight, mTabsContainer.getWidth() + paddingLeft, height, mRectPaint);

} else {

canvas.drawRect(paddingLeft, 0, mTabsContainer.getWidth() + paddingLeft, mUnderlineHeight, mRectPaint);

}

}

//draw indicator line

if (mIndicatorAnimEnable) {

if (mIsFirstDraw) {

mIsFirstDraw = false;

calcIndicatorRect();

}

} else {

calcIndicatorRect();

}

if (mIndicatorStyle == STYLE_TRIANGLE) {

if (mIndicatorHeight > 0) {

mTrianglePaint.setColor(mIndicatorColor);

mTrianglePath.reset();

mTrianglePath.moveTo(paddingLeft + mIndicatorRect.left, height);

mTrianglePath.lineTo(paddingLeft + mIndicatorRect.left / 2 + mIndicatorRect.right / 2, height - mIndicatorHeight);

mTrianglePath.lineTo(paddingLeft + mIndicatorRect.right, height);

mTrianglePath.close();

canvas.drawPath(mTrianglePath, mTrianglePaint);

}

} else if (mIndicatorStyle == STYLE_BLOCK) {

if (mIndicatorHeight < 0) {

mIndicatorHeight = height - mIndicatorMarginTop - mIndicatorMarginBottom;

} else {

}

if (mIndicatorHeight > 0) {

if (mIndicatorCornerRadius < 0 || mIndicatorCornerRadius > mIndicatorHeight / 2) {

mIndicatorCornerRadius = mIndicatorHeight / 2;

}

mIndicatorDrawable.setColor(mIndicatorColor);

mIndicatorDrawable.setBounds(paddingLeft + (int) mIndicatorMarginLeft + mIndicatorRect.left,

(int) mIndicatorMarginTop, (int) (paddingLeft + mIndicatorRect.right - mIndicatorMarginRight),

(int) (mIndicatorMarginTop + mIndicatorHeight));

mIndicatorDrawable.setCornerRadius(mIndicatorCornerRadius);

mIndicatorDrawable.draw(canvas);

}

} else {

/* mRectPaint.setColor(mIndicatorColor);

calcIndicatorRect();

canvas.drawRect(getPaddingLeft() + mIndicatorRect.left, getHeight() - mIndicatorHeight,

mIndicatorRect.right + getPaddingLeft(), getHeight(), mRectPaint);*/

if (mIndicatorHeight > 0) {

mIndicatorDrawable.setColor(mIndicatorColor);

if (mIndicatorGravity == Gravity.BOTTOM) {

mIndicatorDrawable.setBounds(paddingLeft + (int) mIndicatorMarginLeft + mIndicatorRect.left,

height - (int) mIndicatorHeight - (int) mIndicatorMarginBottom,

paddingLeft + mIndicatorRect.right - (int) mIndicatorMarginRight,

height - (int) mIndicatorMarginBottom);

} else {

mIndicatorDrawable.setBounds(paddingLeft + (int) mIndicatorMarginLeft + mIndicatorRect.left,

(int) mIndicatorMarginTop,

paddingLeft + mIndicatorRect.right - (int) mIndicatorMarginRight,

(int) mIndicatorHeight + (int) mIndicatorMarginTop);

}

mIndicatorDrawable.setCornerRadius(mIndicatorCornerRadius);

mIndicatorDrawable.draw(canvas);

}

}

}

//setter and getter

public void setCurrentTab(int currentTab) {

mLastTab = this.mCurrentTab;

this.mCurrentTab = currentTab;

updateTabSelection(currentTab);

if (mFragmentChangeManager != null) {

mFragmentChangeManager.setFragments(currentTab);

}

if (mIndicatorAnimEnable) {

calcOffset();

} else {

invalidate();

}

}

public void setIndicatorStyle(int indicatorStyle) {

this.mIndicatorStyle = indicatorStyle;

invalidate();

}

public void setTabPadding(float tabPadding) {

this.mTabPadding = dp2px(tabPadding);

updateTabStyles();

}

public void setTabSpaceEqual(boolean tabSpaceEqual) {

this.mTabSpaceEqual = tabSpaceEqual;

updateTabStyles();

}

public void setTabWidth(float tabWidth) {

this.mTabWidth = dp2px(tabWidth);

updateTabStyles();

}

public void setIndicatorColor(int indicatorColor) {

this.mIndicatorColor = indicatorColor;

invalidate();

}

public void setIndicatorHeight(float indicatorHeight) {

this.mIndicatorHeight = dp2px(indicatorHeight);

invalidate();

}

public void setIndicatorWidth(float indicatorWidth) {

this.mIndicatorWidth = dp2px(indicatorWidth);

invalidate();

}

public void setIndicatorCornerRadius(float indicatorCornerRadius) {

this.mIndicatorCornerRadius = dp2px(indicatorCornerRadius);

invalidate();

}

public void setIndicatorGravity(int indicatorGravity) {

this.mIndicatorGravity = indicatorGravity;

invalidate();

}

public void setIndicatorMargin(float indicatorMarginLeft, float indicatorMarginTop,

float indicatorMarginRight, float indicatorMarginBottom) {

this.mIndicatorMarginLeft = dp2px(indicatorMarginLeft);

this.mIndicatorMarginTop = dp2px(indicatorMarginTop);

this.mIndicatorMarginRight = dp2px(indicatorMarginRight);

this.mIndicatorMarginBottom = dp2px(indicatorMarginBottom);

invalidate();

}

public void setIndicatorAnimDuration(long indicatorAnimDuration) {

this.mIndicatorAnimDuration = indicatorAnimDuration;

}

public void setIndicatorAnimEnable(boolean indicatorAnimEnable) {

this.mIndicatorAnimEnable = indicatorAnimEnable;

}

public void setIndicatorBounceEnable(boolean indicatorBounceEnable) {

this.mIndicatorBounceEnable = indicatorBounceEnable;

}

public void setUnderlineColor(int underlineColor) {

this.mUnderlineColor = underlineColor;

invalidate();

}

public void setUnderlineHeight(float underlineHeight) {

this.mUnderlineHeight = dp2px(underlineHeight);

invalidate();

}

public void setUnderlineGravity(int underlineGravity) {

this.mUnderlineGravity = underlineGravity;

invalidate();

}

public void setDividerColor(int dividerColor) {

this.mDividerColor = dividerColor;

invalidate();

}

public void setDividerWidth(float dividerWidth) {

this.mDividerWidth = dp2px(dividerWidth);

最后

我一直以来都有整理练习大厂面试题的习惯,有随时跳出舒服圈的准备,也许求职者已经很满意现在的工作,薪酬,觉得习惯而且安逸。

不过如果公司突然倒闭,或者部门被裁减,还能找到这样或者更好的工作吗?

我建议各位,多刷刷面试题,知道最新的技术,每三个月可以去面试一两家公司,因为你已经有不错的工作了,所以可以带着轻松的心态去面试,同时也可以增加面试的经验。

我可以将最近整理的一线互联网公司面试真题+解析分享给大家,大概花了三个月的时间整理2246页,帮助大家学习进步。

由于篇幅限制,文档的详解资料太全面,细节内容太多,所以只把部分知识点截图出来粗略的介绍,每个小节点里面都有更细化的内容!以下是部分内容截图:

部分目录截图

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

nderlineColor;

invalidate();

}

public void setUnderlineHeight(float underlineHeight) {

this.mUnderlineHeight = dp2px(underlineHeight);

invalidate();

}

public void setUnderlineGravity(int underlineGravity) {

this.mUnderlineGravity = underlineGravity;

invalidate();

}

public void setDividerColor(int dividerColor) {

this.mDividerColor = dividerColor;

invalidate();

}

public void setDividerWidth(float dividerWidth) {

this.mDividerWidth = dp2px(dividerWidth);

最后

我一直以来都有整理练习大厂面试题的习惯,有随时跳出舒服圈的准备,也许求职者已经很满意现在的工作,薪酬,觉得习惯而且安逸。

不过如果公司突然倒闭,或者部门被裁减,还能找到这样或者更好的工作吗?

我建议各位,多刷刷面试题,知道最新的技术,每三个月可以去面试一两家公司,因为你已经有不错的工作了,所以可以带着轻松的心态去面试,同时也可以增加面试的经验。

我可以将最近整理的一线互联网公司面试真题+解析分享给大家,大概花了三个月的时间整理2246页,帮助大家学习进步。

由于篇幅限制,文档的详解资料太全面,细节内容太多,所以只把部分知识点截图出来粗略的介绍,每个小节点里面都有更细化的内容!以下是部分内容截图:

[外链图片转存中…(img-h2IAPUKd-1714316372666)]

[外链图片转存中…(img-wwXIyLOh-1714316372667)]

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 25
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值