在App開發時經常會遇到需要做類似微信底部切換按鈕那樣的菜單欄,所以封裝了一個底部菜單控件,方便日后使用。
先看一下demo效果
先看如何進行使用,在看如何實現。
1、在activity_main.xml布局里引用控件
2、在activity進行設置數據
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
BottomMenuView bmv_list = (BottomMenuView) findViewById(R.id.bmv_list);
//設置bottom數據
bmv_list.setBottomItem(getData());
//監聽點擊事件
bmv_list.setBottomItemOnClickListener(new BottomMenuView.BottomItemOnClickListener() {
@Override
public void bottomItemOnClick(View view, int i, BottomItem item) {
Toast.makeText(getApplicationContext(),"點擊了第"+i+"個",Toast.LENGTH_SHORT).show();
}
});
//默認選擇第幾個
bmv_list.setShowIndex(0);
}
/**
* 創建bottom數據
* @return
*/
public List<BottomItem> getData(){
List<BottomItem> items = new ArrayList<>();
items.add(new BottomItem("首頁",R.mipmap.icon_function_tab));
items.add(new BottomItem("信息",R.mipmap.icon_home_tab));
items.add(new BottomItem("應用",R.mipmap.icon_my_tab));
items.add(new BottomItem("我的",R.mipmap.icon_home_tab));
return items;
}
}
Bottomitem的代碼
public class BottomItem {
private String name;
private int icon;
public BottomItem(String name, int icon) {
this.name = name;
this.icon = icon;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getIcon() {
return icon;
}
public void setIcon(int icon) {
this.icon = icon;
}
}
是不是很方便呢!
現在來BottomMenuView看看是怎么實現的
public class BottomMenuView extends LinearLayout implements View.OnClickListener{
private static final String TAG = "BottomMenuView";
private Context mContext;
private int imgColor = 0xff009AFF;//點擊改變圖片顏色
private int imgDefaultColor = 0xff565656;//默認圖片顏色
private float textSize = 12; //字體大小
private int imgPadding = 12; //內邊距
private List<BottomItem> bottomItems;//Item列表
private List<Button> buttons;//buttom列表
private int width;
private int hight;
//回調接口
private BottomItemOnClickListener bottomItemOnClickListener;
public BottomMenuView(Context context) {
super(context);
initView(context);
}
public BottomMenuView(Context context, AttributeSet attrs) {
super(context, attrs);
initView(context);
}
public BottomMenuView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initView(context);
}
public void initView(Context context){
mContext =context;
buttons = new ArrayList<>();//實例化按鈕列表
}
/**
* 傳入item列表
* @param bottomItems
*/
public void setBottomItem(List<BottomItem> bottomItems){
this.bottomItems = bottomItems;
//循環button按鈕
for (int i = 0; i < bottomItems.size(); i++) {
//創建button
Button buttom = new Button(mContext);
//設置寬和高為MATCH_PARENT
LayoutParams layoutParams = new LayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
buttom.setLayoutParams(layoutParams);
//字體居中
buttom.setGravity(Gravity.CENTER);
//設置文字
buttom.setText(bottomItems.get(i).getName());
//設置文字大小
buttom.setTextSize(textSize);
//設置內邊距
buttom.setPadding(imgPadding,imgPadding,imgPadding,imgPadding);
//去掉button背景
buttom.setBackground(null);
//獲取圖標資源
Bitmap bitmap = BitmapFactory.decodeResource(mContext.getResources(),bottomItems.get(i).getIcon());
//設置圖標默認顏色
Drawable drawable = new BitmapDrawable(getResources(),tintBitmap(bitmap,imgDefaultColor));
//設置圖標
buttom.setCompoundDrawablesWithIntrinsicBounds(null,drawable,null,null);
//將item設置到tag中下一步需要用到
buttom.setTag(bottomItems.get(i));
//設置監聽
buttom.setOnClickListener(this);
//添加到當前布局
addView(buttom);
//添加到按鈕組里
buttons.add(buttom);
}
}
private boolean isShow = false;
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
//計算每一個子button的寬度 并且判斷只計算一次
if (!isShow){
for (int i = 0; i < getChildCount(); i++) {
LinearLayout.LayoutParams ll = (LayoutParams) getChildAt(i).getLayoutParams();
ll.width=width/bottomItems.size();
getChildAt(i).setLayoutParams(ll);
}
isShow=true;
}
}
/**
* 手動設置選中的button
**/
public void setShowIndex(int index){
if (buttons.size()!=0){
BottomItem bottomItem = (BottomItem) buttons.get(index).getTag();
getBitmap(buttons.get(index),bottomItem.getIcon(),imgColor);
bottomItemOnClickListener.bottomItemOnClick(buttons.get(index),index,bottomItem);
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
width = MeasureSpec.getSize(widthMeasureSpec);
hight = MeasureSpec.getSize(heightMeasureSpec);
}
/**
* 改變選中顏色
* @param btn
* @param img
* @param color
*/
public void getBitmap(Button btn, int img, int color){
btn.setTextColor(color);
Bitmap bitmap = BitmapFactory.decodeResource(mContext.getResources(),img);
Drawable drawable = new BitmapDrawable(mContext.getResources(), tintBitmap(bitmap,color));
btn.setCompoundDrawablesWithIntrinsicBounds(null,drawable,null,null);
}
/**
* 對每一個BUTTON進行監聽
* @param view
*/
@Override
public void onClick(View view) {
for (int i = 0; i < buttons.size(); i++) {
BottomItem bottomItem = (BottomItem) buttons.get(i).getTag();//從tag中獲取BottomItem
getBitmap(buttons.get(i),bottomItem.getIcon(),imgDefaultColor);//重置按鈕顏色
if (buttons.get(i).getTag()==view.getTag()){//判斷點擊的是哪個按鈕
getBitmap(buttons.get(i),bottomItem.getIcon(),imgColor);//更改被點擊的按鈕牙
if (bottomItemOnClickListener != null) {
//通知回調
bottomItemOnClickListener.bottomItemOnClick(view,i,bottomItem);
}
}
}
}
public BottomItemOnClickListener getBottomItemOnClickListener() {
return bottomItemOnClickListener;
}
public void setBottomItemOnClickListener(BottomItemOnClickListener bottomItemOnClickListener) {
this.bottomItemOnClickListener = bottomItemOnClickListener;
}
/**
* 點擊監聽回調接口
*/
public interface BottomItemOnClickListener{
void bottomItemOnClick(View view, int i,BottomItem item);
}
/**
* 改變顏色
* @param inBitmap
* @param tintColor
* @return
*/
public static Bitmap tintBitmap(Bitmap inBitmap , int tintColor) {
if (inBitmap == null) {
return null;
}
Bitmap outBitmap = Bitmap.createBitmap (inBitmap.getWidth(), inBitmap.getHeight() , inBitmap.getConfig());
Canvas canvas = new Canvas(outBitmap);
Paint paint = new Paint();
paint.setColorFilter( new PorterDuffColorFilter(tintColor, PorterDuff.Mode.SRC_IN)) ;
canvas.drawBitmap(inBitmap , 0, 0, paint) ;
return outBitmap ;
}
/** get / set **/
public int getImgDefaultColor() {
return imgDefaultColor;
}
public void setImgDefaultColor(int imgDefaultColor) {
this.imgDefaultColor = imgDefaultColor;
}
public int getImgColor() {
return imgColor;
}
public void setImgColor(int imgColor) {
this.imgColor = imgColor;
}
public float getTextSize() {
return textSize;
}
public void setTextSize(float textSize) {
this.textSize = textSize;
}
public int getImgPadding() {
return imgPadding;
}
public void setImgPadding(int imgPadding) {
this.imgPadding = imgPadding;
}
}
代碼比較簡單,相信大家看一遍都可以理解。
全部代碼已托管到開源中國的碼云和GitHub上,歡迎下載。
地址:
https://github.com/yancy2430/BottomNavView
https://git.oschina.net/zhe2430/BottomNavView
也可以直接Gradle引用
compile 'com.tdeado:bottomnav:1.0.0'