美文网首页自定义Android知识Android开发
Android自定义底部菜单栏控件

Android自定义底部菜单栏控件

作者: yancy2430 | 来源:发表于2017-03-07 21:44 被阅读316次

    在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'

    相关文章

      网友评论

      • SmartSean:我想问下,如果项目中需要在tab栏加上一个角标,这个可以实现吗?
        yancy2430:@Coding_css 恩 直接引用不能 你可以照着上面的代码进行修改一下
        SmartSean:@yancy2430 你这个是不是就不能用了?
        yancy2430:需要自定义带角标的Button

      本文标题:Android自定义底部菜单栏控件

      本文链接:https://www.haomeiwen.com/subject/zclvgttx.html