您的位置:首页 > 移动开发 > 微信开发

android高仿微信底部导航栏

2017-05-08 19:29 477 查看

这几天在公司没什么工作,闲来没事写了一下关于微信底部渐变的导航,textview 是利用 ArgbEvaluator 实现颜色渐变的效果,图片渐变是自定义imageview 来设置透明度进行渐变的

本代码与其他实现的优越性:

代码简单

容易看懂,对新手来说不是问题

直接可以copy到自己的项目中使用

首先看一下效果图



先了解一下ArgbEvaluator的使用,ArgbEvaluator俗称颜色计算器,举个栗子

float percentage = (float)i/100; //这个就是根据百分比来计算出颜色
ArgbEvaluator argb = new ArgbEvaluator();
int  color = (int)argb.evaluate(percentage, Color.parseColor("#ffffff"),Color.parseColor("#000000"));
findViewById(R.id.tv_simple).setBackgroundColor(color);


此栗子:当percentage为0的时候:color为纯白色,当percentage为1的时候:color为纯黑色, 当percentage从0-1变化的时候,颜色会从白色到黑色逐渐的变化

先看一自定义控件自定义imageView 不用再xml中设置src或者backgroud

在setImages的时候 就会传入两张图片, 一个是正常的,一个是选中状态下的图片. 实际上就是在此imageview上面画图片

在 transformPage的时候,就会根据offset(偏移量)的大小来设置透明度,从而效果为渐变.

public class MyImageView extends ImageView {

private Paint mPaint;
private Bitmap mSelectedIcon;
private Bitmap mNormalIcon;
private Rect mSelectedRect;
private Rect mNormalRect;
private int mSelectedAlpha = 0;

public MyImageView(Context context) {
super(context);
}

public MyImageView(Context context, AttributeSet attrs) {
super(context, attrs);
}

public MyImageView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}

public final void setImages(int normal, int selected) {
this.mNormalIcon = createBitmap(normal);                            // 拿到原图
this.mSelectedIcon = createBitmap(selected);
int width = (int)getResources().getDimension(R.dimen.tab_image_weith);
int heigh = (int)getResources().getDimension(R.dimen.tab_image_heigh);
this.mNormalRect = new Rect(0, 0, width, heigh);                   //拿到画板的大小 也就是此控件的大小
this.mSelectedRect = new Rect(0, 0, width, heigh);
this.mPaint = new Paint();                                         // 拿到画笔
}

private Bitmap createBitmap(int resId) {
return BitmapFactory.decodeResource(getResources(), resId);
}

@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (this.mPaint == null) {
return;
}
this.mPaint.setAlpha(255 - this.mSelectedAlpha);
canvas.drawBitmap(this.mNormalIcon, null, this.mNormalRect, this.mPaint); //开始在画板上画原图
// 也就是在这个控件上画bitmap
this.mPaint.setAlpha(this.mSelectedAlpha);
canvas.drawBitmap(this.mSelectedIcon, null, this.mSelectedRect, this.mPaint);
}

public final void changeSelectedAlpha(int alpha) {

}

/**
* 当viewpager滑动的时候,也就是onPageScrolled调用的时候,再来调用此方法
* @param offset  偏移量
*/
public final void transformPage(float offset) {
this.mSelectedAlpha = (int) (255 * (1 - offset));
invalidate();  // 此方法调用就会从新走 onDraw方法
}
}


之后我们看一下xml中,其实xml布局挺简单的,一看就懂,没错,就是上面一个ViewPgaer 下面一个LinearLayout 里面包裹着

<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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="kitrobot.com.wechat_bottom_navigation.MainActivity"
android:orientation="vertical">

<android.support.v4.view.ViewPager
android:layout_weight="1"
android:id="@+id/vp"
android:layout_width="match_parent"
android:layout_height="0dp"></android.support.v4.view.ViewPager>
<LinearLayout
android:paddingTop="10dp"
android:background="#ffffff"
android:orientation="horizontal"
android:id="@+id/rg"
android:layout_width="match_parent"
android:layout_height="60dp">
<LinearLayout
android:id="@+id/ll_home"
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="match_parent"
android:orientation="vertical">
<kitrobot.com.wechat_bottom_navigation.view.MyImageView
android:layout_gravity="center"
android:id="@+id/iv1"
android:layout_width="30dp"
android:layout_height="30dp"/>
<TextView
android:gravity="center"
android:text="微信"
android:button="@null"
android:id="@+id/rb1"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>

<LinearLayout
android:id="@+id/ll_categroy"
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="match_parent"
android:orientation="vertical">
<kitrobot.com.wechat_bottom_navigation.view.MyImageView
android:layout_gravity="center"
android:id="@+id/iv2"
android:layout_width="30dp"
android:layout_height="30dp"/>
<TextView
android:gravity="center"
android:text="通信录"
android:button="@null"
android:id="@+id/rb2"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
<LinearLayout
android:id="@+id/ll_find"
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="match_parent"
android:orientation="vertical">
<kitrobot.com.wechat_bottom_navigation.view.MyImageView
android:layout_gravity="center"
android:id="@+id/iv3"
android:layout_width="30dp"
android:layout_height="30dp"/>
<TextView
androi
4000
d:gravity="center"
android:text="发现"
android:button="@null"
android:id="@+id/rb3"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
<LinearLayout
android:id="@+id/ll_mine"
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="match_parent"
android:orientation="vertical">
<kitrobot.com.wechat_bottom_navigation.view.MyImageView
android:layout_gravity="center"
android:id="@+id/iv4"
android:layout_width="@dimen/tab_image_weith"
android:layout_height="@dimen/tab_image_heigh"/>
<TextView
android:gravity="center"
android:text="我"
android:button="@null"
android:id="@+id/rb4"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
</LinearLayout>

</LinearLayout>


最后看一下代码的逻辑 你会发现so简单 注释什么的都很全自己看一下绝对ok

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

private ViewPager mViewPager;
private MyImageView mIvHome; // tab 消息的imageview
private TextView mTvHome;   // tab 消息的imageview

private MyImageView mIvCategory; // tab 通讯录的imageview
private TextView mTvCategory;

private MyImageView mIvFind;  // tab 发现的imageview
private TextView mTvFind;

private MyImageView mIvMine; // tab 我的imageview
private TextView mTvMine;

private ArrayList<Fragment> mFragments;
private ArgbEvaluator mColorEvaluator;

private int mTextNormalColor;// 未选中的字体颜色
private int mTextSelectedColor;// 选中的字体颜色
private LinearLayout mLinearLayoutHome;
private LinearLayout mLinearLayoutCategory;
private LinearLayout mLinearLayoutFind;
private LinearLayout mLinearLayoutMine;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initColor();//也就是选中未选中的textview的color
initView();// 初始化控件
initData(); // 初始化数据(也就是fragments)
initSelectImage();// 初始化渐变的图片
aboutViewpager(); // 关于viewpager
setListener(); // viewpager设置滑动监听
}

private void initSelectImage() {
mIvHome.setImages(R.drawable.home_normal, R.drawable.home_selected);
mIvCategory.setImages(R.drawable.category_normal, R.drawable.category_selected);
mIvFind.setImages(R.drawable.find_normal, R.drawable.find_selected);
mIvMine.setImages(R.drawable.mine_normal, R.drawable.mine_selected);
}

private void initColor() {
mTextNormalColor = getResources().getColor(R.color.main_bottom_tab_textcolor_normal);
mTextSelectedColor = getResources().getColor(R.color.main_bottom_tab_textcolor_selected);
}

private void setListener() {
//下面的tab设置点击监听
mLinearLayoutHome.setOnClickListener(this);
mLinearLayoutCategory.setOnClickListener(this);
mLinearLayoutFind.setOnClickListener(this);
mLinearLayoutMine.setOnClickListener(this);

mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPs) {
setTabTextColorAndImageView(position,positionOffset);// 更改text的颜色还有图片
}

@Override
public void onPageSelected(int position) {
}

@Override
public void onPageScrollStateChanged(int state) {

}
});
}

private void setTabTextColorAndImageView(int position, float positionOffset) {
mColorEvaluator = new ArgbEvaluator();  // 根据偏移量 来得到
int  evaluateCurrent =(int) mColorEvaluator.evaluate(positionOffset,mTextSelectedColor , mTextNormalColor);//当前tab的颜色值
int  evaluateThe =(int) mColorEvaluator.evaluate(positionOffset, mTextNormalColor, mTextSelectedColor);// 将要到tab的颜色值
switch (position) {
case 0:
mTvHome.setTextColor(evaluateCurrent);  //设置消息的字体颜色
mTvCategory.setTextColor(evaluateThe);  //设置通讯录的字体颜色

mIvHome.transformPage(positionOffset);  //设置消息的图片
mIvCategory.transformPage(1-positionOffset); //设置通讯录的图片
break;
case 1:
mTvCategory.setTextColor(evaluateCurrent);
mTvFind.setTextColor(evaluateThe);

mIvCategory.transformPage(positionOffset);
mIvFind.transformPage(1-positionOffset);
break;
case 2:
mTvFind.setTextColor(evaluateCurrent);
mTvMine.setTextColor(evaluateThe);

mIvFind.transformPage(positionOffset);
mIvMine.transformPage(1-positionOffset);
break;

}
}

private void initData() {
mFragments = new ArrayList<>();
mFragments.add(new HomeFragment());
mFragments.add(new CategoryFragment());
mFragments.add(new FindFragment());
mFragments.add(new MineFragment());
}

private void aboutViewpager() {
MyAdapter myAdapter = new MyAdapter(getSupportFragmentManager(), mFragments);// 初始化adapter
mViewPager.setAdapter(myAdapter); // 设置adapter
}

private void initView() {
mLinearLayoutHome = (LinearLayout) findViewById(R.id.ll_home);
mLinearLayoutCategory = (LinearLayout) findViewById(R.id.ll_categroy);
mLinearLayoutFind = (LinearLayout) findViewById(R.id.ll_find);
mLinearLayoutMine = (LinearLayout) findViewById(R.id.ll_mine);
mViewPager = (ViewPager) findViewById(R.id.vp);
mIvHome = (MyImageView) findViewById(R.id.iv1);  // tab 微信 imageview
mTvHome = (TextView) findViewById(R.id.rb1);  //  tab  微信 字

mIvCategory = (MyImageView) findViewById(R.id.iv2); // tab 通信录 imageview
mTvCategory = (TextView) findViewById(R.id.rb2);  // tab   通信录 字

mIvFind = (MyImageView) findViewById(R.id.iv3); // tab 发现 imageview
mTvFind = (TextView) findViewById(R.id.rb3);   //  tab  发现 字

mIvMine = (MyImageView) findViewById(R.id.iv4);   // tab 我 imageview
mTvMine = (TextView) findViewById(R.id.rb4);    // tab   我 字
}

@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.ll_home:
mViewPager.setCurrentItem(0);
break;
case R.id.ll_categroy:
mViewPager.setCurrentItem(1);
break;
case R.id.ll_find:
mViewPager.setCurrentItem(2);
break;
case R.id.ll_mine:
mViewPager.setCurrentItem(3);
break;
}
}

}


有的同学会问:为什么不用初始化tab字体的颜色和imageview的图片的,其实这个我也是最近才发现的,当界面完成的时候,viewpager会自动加载第一页而此时的ViewPager.OnPageChangeListener中的 onPageScrolled 会自动的执行一次,其他的方法不会去执行

最后献上源码位置

github:wechat-Bottom-navigation

欢迎star
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息