美文网首页安卓
通用的底部导航栏

通用的底部导航栏

作者: it奔跑在路上 | 来源:发表于2018-10-31 14:59 被阅读52次

    通用的底部导航栏

    可自主设置底部导航栏的消息数及提醒

    用CV大法即可

    都说“所有贴代码不贴效果图的都是耍流氓”,效果图献上


    效果图.jpg
    public class MainActivity extends AppCompatActivity {
    
        private ViewPager mVpContent;
        private BottomBarLayout mBottomBarLayout;
    
        private List<TabFragment> mFragmentList = new ArrayList<>();
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            initView();
            initData();
            initListener();
        }
        private void initView() {
            mVpContent = (ViewPager) findViewById(R.id.vp_content);
            mBottomBarLayout = (BottomBarLayout) findViewById(R.id.bbl);
        }
    
        private void initData() {
    
            TabFragment homeFragment = new TabFragment();
            Bundle bundle1 = new Bundle();
            bundle1.putString(TabFragment.CONTENT,"第一个页面");
            homeFragment.setArguments(bundle1);
            mFragmentList.add(homeFragment);
    
            TabFragment videoFragment = new TabFragment();
            Bundle bundle2 = new Bundle();
            bundle2.putString(TabFragment.CONTENT,"第二个页面");
            videoFragment.setArguments(bundle2);
            mFragmentList.add(videoFragment);
    
            TabFragment microFragment = new TabFragment();
            Bundle bundle3 = new Bundle();
            bundle3.putString(TabFragment.CONTENT,"第三个页面");
            microFragment.setArguments(bundle3);
            mFragmentList.add(microFragment);
    
            TabFragment meFragment = new TabFragment();
            Bundle bundle4 = new Bundle();
            bundle4.putString(TabFragment.CONTENT,"第四个页面");
            meFragment.setArguments(bundle4);
            mFragmentList.add(meFragment);
        }
    
        private void initListener() {
            mVpContent.setAdapter(new MyAdapter(getSupportFragmentManager(),mFragmentList));
            mBottomBarLayout.setViewPager(mVpContent);
    
            mBottomBarLayout.setUnread(0,20);//设置第一个页签的未读数为20
            mBottomBarLayout.setUnread(1,101);//设置第二个页签的未读数
            mBottomBarLayout.showNotify(2);//设置第三个页签显示提示的小红点
            mBottomBarLayout.setMsg(3,"NEW");//设置第四个页签显示NEW提示文字
        }
    }
    
    class MyAdapter extends FragmentStatePagerAdapter {
    
        private List<TabFragment> mFragmentList;
    
        public MyAdapter(FragmentManager fm, List<TabFragment> fragmentList) {
            super(fm);
            this.mFragmentList = fragmentList;
        }
    
        @Override
        public Fragment getItem(int position) {
            return mFragmentList.get(position);
        }
    
        @Override
        public int getCount() {
            return mFragmentList.size();
        }
    }
    
    public class TabFragment extends Fragment {
    
        public static final String CONTENT = "content";
        private TextView mTextView;
    
    
        @Nullable
        @Override
        public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle bundle) {
            mTextView = new TextView(getActivity());
            mTextView.setGravity(Gravity.CENTER);
            String content = getArguments().getString(CONTENT);
            mTextView.setText(content);
            return mTextView;
        }
    }
    
    public class BottomBarItem extends LinearLayout {
    
        private Context mContext;
        private int     mIconNormalResourceId;//普通状态图标的资源id
        private int     mIconSelectedResourceId;//选中状态图标的资源id
        private String  mText;//文本
        private int mTextSize = 12;//文字大小 默认为12sp
        private int mTextColorNormal = 0xFF999999;    //描述文本的默认显示颜色
        private int mTextColorSelected = 0xFF46C01B;  //述文本的默认选中显示颜色
        private int mWhiteColor = 0xFFFFFFFF;  //白色
        private int mMarginTop = 0;//文字和图标的距离,默认0dp
        private boolean mOpenTouchBg = false;// 是否开启触摸背景,默认关闭
        private Drawable mTouchDrawable;//触摸时的背景
        private int      mIconWidth;//图标的宽度
        private int      mIconHeight;//图标的高度
        private int      mItemPadding;//BottomBarItem的padding
    
    
        private ImageView mImageView;
        private TextView  mTvUnread;
        private TextView  mTvNotify;
        private TextView  mTvMsg;
        private TextView  mTextView;
    
        private int mUnreadTextSize = 10; //未读数默认字体大小10sp
        private int mMsgTextSize = 6; //消息默认字体大小6sp
        private int unreadNumThreshold = 99;//未读数阈值
        private int      mUnreadTextColor;//未读数字体颜色
        private Drawable mUnreadTextBg;
        private int      mMsgTextColor;
        private Drawable mMsgTextBg;
        private Drawable mNotifyPointBg;
    
        public BottomBarItem(Context context) {
            this(context, null);
        }
    
        public BottomBarItem(Context context, @Nullable AttributeSet attrs) {
            this(context, attrs, 0);
        }
    
        public BottomBarItem(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
    
            mContext = context;
    
            TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.BottomBarItem);
    
            initAttrs(ta); //初始化属性
    
            ta.recycle();
    
            checkValues();//检查值是否合法
    
            init();//初始化相关操作
        }
    
        private void initAttrs(TypedArray ta) {
            mIconNormalResourceId = ta.getResourceId(R.styleable.BottomBarItem_iconNormal, -1);
            mIconSelectedResourceId = ta.getResourceId(R.styleable.BottomBarItem_iconSelected, -1);
    
            mText = ta.getString(R.styleable.BottomBarItem_itemText);
            mTextSize = ta.getDimensionPixelSize(R.styleable.BottomBarItem_itemTextSize, UIUtils.sp2px(mContext, mTextSize));
    
            mTextColorNormal = ta.getColor(R.styleable.BottomBarItem_textColorNormal, mTextColorNormal);
            mTextColorSelected = ta.getColor(R.styleable.BottomBarItem_textColorSelected, mTextColorSelected);
    
            mMarginTop = ta.getDimensionPixelSize(R.styleable.BottomBarItem_itemMarginTop, UIUtils.dip2Px(mContext, mMarginTop));
    
            mOpenTouchBg = ta.getBoolean(R.styleable.BottomBarItem_openTouchBg, mOpenTouchBg);
            mTouchDrawable = ta.getDrawable(R.styleable.BottomBarItem_touchDrawable);
    
            mIconWidth = ta.getDimensionPixelSize(R.styleable.BottomBarItem_iconWidth, 0);
            mIconHeight = ta.getDimensionPixelSize(R.styleable.BottomBarItem_iconHeight, 0);
            mItemPadding = ta.getDimensionPixelSize(R.styleable.BottomBarItem_itemPadding, 0);
    
            mUnreadTextSize = ta.getDimensionPixelSize(R.styleable.BottomBarItem_unreadTextSize, UIUtils.sp2px(mContext, mUnreadTextSize));
            mUnreadTextColor = ta.getColor(R.styleable.BottomBarItem_unreadTextColor, 0xFFFFFFFF);
            mUnreadTextBg = ta.getDrawable(R.styleable.BottomBarItem_unreadTextBg);
    
            mMsgTextSize = ta.getDimensionPixelSize(R.styleable.BottomBarItem_msgTextSize, UIUtils.sp2px(mContext, mMsgTextSize));
            mMsgTextColor = ta.getColor(R.styleable.BottomBarItem_msgTextColor, 0xFFFFFFFF);
            mMsgTextBg = ta.getDrawable(R.styleable.BottomBarItem_msgTextBg);
    
            mNotifyPointBg = ta.getDrawable(R.styleable.BottomBarItem_notifyPointBg);
    
            unreadNumThreshold = ta.getInteger(R.styleable.BottomBarItem_unreadThreshold,99);
        }
    
        /**
         * 检查传入的值是否完善
         */
        private void checkValues() {
            if (mIconNormalResourceId == -1) {
                throw new IllegalStateException("您还没有设置默认状态下的图标,请指定iconNormal的图标");
            }
    
            if (mIconSelectedResourceId == -1) {
                throw new IllegalStateException("您还没有设置选中状态下的图标,请指定iconSelected的图标");
            }
    
            if (mOpenTouchBg && mTouchDrawable == null) {
                //如果有开启触摸背景效果但是没有传对应的drawable
                throw new IllegalStateException("开启了触摸效果,但是没有指定touchDrawable");
            }
    
            if (mUnreadTextBg == null){
                mUnreadTextBg = getResources().getDrawable(R.drawable.shape_unread);
            }
    
            if (mMsgTextBg == null){
                mMsgTextBg = getResources().getDrawable(R.drawable.shape_msg);
            }
    
            if (mNotifyPointBg == null){
                mNotifyPointBg = getResources().getDrawable(R.drawable.shape_notify_point);
            }
        }
    
        private void init() {
            setOrientation(VERTICAL);
            setGravity(Gravity.CENTER);
    
            View view = initView();
    
            mImageView.setImageResource(mIconNormalResourceId);
    
            if (mIconWidth != 0 && mIconHeight != 0) {
                //如果有设置图标的宽度和高度,则设置ImageView的宽高
                FrameLayout.LayoutParams imageLayoutParams = (FrameLayout.LayoutParams) mImageView.getLayoutParams();
                imageLayoutParams.width = mIconWidth;
                imageLayoutParams.height = mIconHeight;
                mImageView.setLayoutParams(imageLayoutParams);
            }
    
            mTextView.setTextSize(TypedValue.COMPLEX_UNIT_PX, mTextSize);//设置底部文字字体大小
    
            mTvUnread.setTextSize(TypedValue.COMPLEX_UNIT_PX, mUnreadTextSize);//设置未读数的字体大小
            mTvUnread.setTextColor(mUnreadTextColor);//设置未读数字体颜色
            mTvUnread.setBackground(mUnreadTextBg);//设置未读数背景
    
            mTvMsg.setTextSize(TypedValue.COMPLEX_UNIT_PX, mMsgTextSize);//设置提示文字的字体大小
            mTvMsg.setTextColor(mMsgTextColor);//设置提示文字的字体颜色
            mTvMsg.setBackground(mMsgTextBg);//设置提示文字的背景颜色
    
            mTvNotify.setBackground(mNotifyPointBg);//设置提示点的背景颜色
    
            mTextView.setTextColor(mTextColorNormal);//设置底部文字字体颜色
            mTextView.setText(mText);//设置标签文字
    
            LayoutParams textLayoutParams = (LayoutParams) mTextView.getLayoutParams();
            textLayoutParams.topMargin = mMarginTop;
            mTextView.setLayoutParams(textLayoutParams);
    
            if (mOpenTouchBg) {
                //如果有开启触摸背景
                setBackground(mTouchDrawable);
            }
    
            addView(view);
        }
    
        @NonNull
        private View initView() {
            View view = View.inflate(mContext, R.layout.item_bottom_bar, null);
            if (mItemPadding != 0) {
                //如果有设置item的padding
                view.setPadding(mItemPadding, mItemPadding, mItemPadding, mItemPadding);
            }
            mImageView = (ImageView) view.findViewById(R.id.iv_icon);
            mTvUnread = (TextView) view.findViewById(R.id.tv_unred_num);
            mTvMsg = (TextView) view.findViewById(R.id.tv_msg);
            mTvNotify = (TextView) view.findViewById(R.id.tv_point);
            mTextView = (TextView) view.findViewById(R.id.tv_text);
            return view;
        }
    
        public ImageView getImageView() {
            return mImageView;
        }
    
        public TextView getTextView() {
            return mTextView;
        }
    
        public void setIconNormalResourceId(int mIconNormalResourceId) {
            this.mIconNormalResourceId = mIconNormalResourceId;
        }
    
        public void setIconSelectedResourceId(int mIconSelectedResourceId) {
            this.mIconSelectedResourceId = mIconSelectedResourceId;
        }
    
        public void setStatus(boolean isSelected) {
            mImageView.setImageDrawable(getResources().getDrawable(isSelected ? mIconSelectedResourceId : mIconNormalResourceId));
            mTextView.setTextColor(isSelected ? mTextColorSelected : mTextColorNormal);
        }
    
        private void setTvVisiable(TextView tv) {
            //都设置为不可见
            mTvUnread.setVisibility(GONE);
            mTvMsg.setVisibility(GONE);
            mTvNotify.setVisibility(GONE);
    
            tv.setVisibility(VISIBLE);//设置为可见
        }
    
        public int getUnreadNumThreshold() {
            return unreadNumThreshold;
        }
    
        public void setUnreadNumThreshold(int unreadNumThreshold) {
            this.unreadNumThreshold = unreadNumThreshold;
        }
    
        /**
         * 设置未读数
         *
         * @param unreadNum 小于等于{@link #unreadNumThreshold}则隐藏,
         *                  大于0小于{@link #unreadNumThreshold}则显示对应数字,
         *                  超过{@link #unreadNumThreshold}
         *                  显示{@link #unreadNumThreshold}+
         */
        public void setUnreadNum(int unreadNum) {
            setTvVisiable(mTvUnread);
            if (unreadNum <= 0) {
                mTvUnread.setVisibility(GONE);
            } else if (unreadNum <= unreadNumThreshold) {
                mTvUnread.setText(String.valueOf(unreadNum));
            } else {
                mTvUnread.setText(String.format(Locale.CHINA, "%d+", unreadNumThreshold));
            }
        }
    
        public void setMsg(String msg) {
            setTvVisiable(mTvMsg);
            mTvMsg.setText(msg);
        }
    
        public void hideMsg() {
            mTvMsg.setVisibility(GONE);
        }
    
        public void showNotify() {
            setTvVisiable(mTvNotify);
        }
    
        public void hideNotify() {
            mTvNotify.setVisibility(GONE);
        }
    }
    
    public class BottomBarLayout extends LinearLayout implements ViewPager.OnPageChangeListener {
    
        private static final String STATE_INSTANCE = "instance_state";
        private static final String STATE_ITEM     = "state_item";
    
    
        private ViewPager mViewPager;
        private int       mChildCount;//子条目个数
        private List<BottomBarItem> mItemViews = new ArrayList<>();
        private int mCurrentItem;//当前条目的索引
        private boolean mSmoothScroll;
    
        public BottomBarLayout(Context context) {
            this(context, null);
        }
    
        public BottomBarLayout(Context context, AttributeSet attrs) {
            this(context, attrs, 0);
        }
    
        public BottomBarLayout(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.BottomBarLayout);
            mSmoothScroll = ta.getBoolean(R.styleable.BottomBarLayout_smoothScroll,false);
            ta.recycle();
        }
    
        @Override
        protected void onFinishInflate() {
            super.onFinishInflate();
            init();
        }
    
        @Override
        public void setOrientation(int orientation) {
            super.setOrientation(orientation);
        }
    
        public void setViewPager(ViewPager viewPager) {
            this.mViewPager = viewPager;
            init();
        }
    
        private void init() {
            mChildCount = getChildCount();
    
            if (mViewPager != null) {
                if (mViewPager.getAdapter().getCount() != mChildCount) {
                    throw new IllegalArgumentException("LinearLayout的子View数量必须和ViewPager条目数量一致");
                }
            }
    
            for (int i = 0; i < mChildCount; i++) {
                if (getChildAt(i) instanceof BottomBarItem) {
                    BottomBarItem bottomBarItem = (BottomBarItem) getChildAt(i);
                    mItemViews.add(bottomBarItem);
                    //设置点击监听
                    bottomBarItem.setOnClickListener(new MyOnClickListener(i));
                } else {
                    throw new IllegalArgumentException("BottomBarLayout的子View必须是BottomBarItem");
                }
            }
    
            mItemViews.get(mCurrentItem).setStatus(true);//设置选中项
    
            if (mViewPager != null){
                mViewPager.setOnPageChangeListener(this);
            }
        }
    
        @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
    
        }
    
        @Override
        public void onPageSelected(int position) {
            resetState();
            mItemViews.get(position).setStatus(true);
            if (onItemSelectedListener != null){
                onItemSelectedListener.onItemSelected(getBottomItem(position),mCurrentItem,position);
            }
            mCurrentItem = position;//记录当前位置
        }
    
        @Override
        public void onPageScrollStateChanged(int state) {
    
        }
    
        private class MyOnClickListener implements OnClickListener {
    
            private int currentIndex;
    
            public MyOnClickListener(int i) {
                this.currentIndex = i;
            }
    
            @Override
            public void onClick(View v) {
                //回调点击的位置
                if(mViewPager != null){
                    //有设置viewPager
                    if (currentIndex == mCurrentItem){
                        //如果还是同个页签,使用setCurrentItem不会回调OnPageSelecte(),所以在此处需要回调点击监听
                        if (onItemSelectedListener != null) {
                            onItemSelectedListener.onItemSelected(getBottomItem(currentIndex),mCurrentItem,currentIndex);
                        }
                    }else{
                        mViewPager.setCurrentItem(currentIndex, mSmoothScroll);
                    }
                }else{
                    //没有设置viewPager
                    if (onItemSelectedListener != null) {
                        onItemSelectedListener.onItemSelected(getBottomItem(currentIndex),mCurrentItem,currentIndex);
                    }
    
                    updateTabState(currentIndex);
                }
            }
        }
    
        private void updateTabState(int position){
            resetState();
            mCurrentItem = position;
            mItemViews.get(mCurrentItem).setStatus(true);
        }
    
        /**
         * 重置当前按钮的状态
         */
        private void resetState() {
            if (mCurrentItem < mItemViews.size()){
                mItemViews.get(mCurrentItem).setStatus(false);
            }
        }
    
        public void setCurrentItem(int currentItem) {
            if (mViewPager != null){
                mViewPager.setCurrentItem(currentItem,mSmoothScroll);
            }else{
                updateTabState(currentItem);
            }
        }
    
        /**
         * 设置未读数
         * @param position 底部标签的下标
         * @param unreadNum 未读数
         */
        public void setUnread(int position,int unreadNum){
            mItemViews.get(position).setUnreadNum(unreadNum);
        }
    
        /**
         * 设置提示消息
         * @param position 底部标签的下标
         * @param msg 未读数
         */
        public void setMsg(int position,String msg){
            mItemViews.get(position).setMsg(msg);
        }
    
        /**
         * 隐藏提示消息
         * @param position 底部标签的下标
         */
        public void hideMsg(int position){
            mItemViews.get(position).hideMsg();
        }
    
        /**
         * 显示提示的小红点
         * @param position 底部标签的下标
         */
        public void showNotify(int position){
            mItemViews.get(position).showNotify();
        }
    
        /**
         * 隐藏提示的小红点
         * @param position 底部标签的下标
         */
        public void hideNotify(int position){
            mItemViews.get(position).hideNotify();
        }
    
        public int getCurrentItem() {
            return mCurrentItem;
        }
    
        public void setSmoothScroll(boolean smoothScroll) {
            this.mSmoothScroll = smoothScroll;
        }
    
        public BottomBarItem getBottomItem(int position){
            return mItemViews.get(position);
        }
    
        /**
         * @return 当View被销毁的时候,保存数据
         */
        @Override
        protected Parcelable onSaveInstanceState() {
            Bundle bundle = new Bundle();
            bundle.putParcelable(STATE_INSTANCE, super.onSaveInstanceState());
            bundle.putInt(STATE_ITEM, mCurrentItem);
            return bundle;
        }
    
        /**
         * @param state 用于恢复数据使用
         */
        @Override
        protected void onRestoreInstanceState(Parcelable state) {
            if (state instanceof Bundle) {
                Bundle bundle = (Bundle) state;
                mCurrentItem = bundle.getInt(STATE_ITEM);
                //重置所有按钮状态
                resetState();
                //恢复点击的条目颜色
                mItemViews.get(mCurrentItem).setStatus(true);
                super.onRestoreInstanceState(bundle.getParcelable(STATE_INSTANCE));
            } else {
                super.onRestoreInstanceState(state);
            }
        }
    
        private OnItemSelectedListener onItemSelectedListener;
    
        public interface OnItemSelectedListener {
            void onItemSelected(BottomBarItem bottomBarItem, int previousPosition, int currentPosition);
        }
    
        public void setOnItemSelectedListener(OnItemSelectedListener onItemSelectedListener) {
            this.onItemSelectedListener = onItemSelectedListener;
        }
    }
    
    public class UIUtils {
        /**
         * dip-->px
         */
        public static int dip2Px(Context context, int dip) {
            // px/dip = density;
            // density = dpi/160
            // 320*480 density = 1 1px = 1dp
            // 1280*720 density = 2 2px = 1dp
    
            float density = context.getResources().getDisplayMetrics().density;
            int px = (int) (dip * density + 0.5f);
            return px;
        }
    
        /**
         * 将sp值转换为px值,保证文字大小不变
         *
         * @param spValue
         * @return
         */
        public static int sp2px(Context context, float spValue) {
            final float fontScale = context.getResources().getDisplayMetrics().scaledDensity;
            return (int) (spValue * fontScale + 0.5f);
        }
    }
    

    activity_main.xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        >
    
        <android.support.v4.view.ViewPager
            android:id="@+id/vp_content"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"
            ></android.support.v4.view.ViewPager>
    
        <com.clkj.bottombar.bottombar.BottomBarLayout
            android:id="@+id/bbl"
            android:layout_width="match_parent"
            android:layout_height="45dp"
            android:orientation="horizontal"
            android:gravity="center"
            android:layout_gravity="center"
            android:background="@color/tab_gb"
            >
    
            <com.clkj.bottombar.bottombar.BottomBarItem
                android:layout_width="0dp"
                android:layout_weight="1"
                android:layout_height="match_parent"
                app:iconNormal="@mipmap/tab_home_normal"
                app:iconSelected="@mipmap/tab_home_selected"
                app:itemText="首页"
                app:textColorNormal="@color/tab_normal_color"
                app:textColorSelected="@color/tab_selected_color"
                app:itemTextSize="8sp"
                app:itemMarginTop="-5dp"
                app:openTouchBg="true"
                app:touchDrawable="@drawable/selector_bg"
                />
    
            <com.clkj.bottombar.bottombar.BottomBarItem
                android:layout_width="0dp"
                android:layout_weight="1"
                android:layout_height="match_parent"
                app:iconNormal="@mipmap/tab_video_normal"
                app:iconSelected="@mipmap/tab_video_selected"
                app:itemText="视频"
                app:textColorNormal="@color/tab_normal_color"
                app:textColorSelected="@color/tab_selected_color"
                app:itemTextSize="8sp"
                app:itemMarginTop="-5dp"
                app:openTouchBg="true"
                app:unreadThreshold="99"
                app:touchDrawable="@drawable/selector_bg"
                />
    
    
            <com.clkj.bottombar.bottombar.BottomBarItem
                android:layout_width="0dp"
                android:layout_weight="1"
                android:layout_height="match_parent"
                app:iconNormal="@mipmap/tab_micro_normal"
                app:iconSelected="@mipmap/tab_micro_selected"
                app:itemText="微头条"
                app:textColorNormal="@color/tab_normal_color"
                app:textColorSelected="@color/tab_selected_color"
                app:itemTextSize="8sp"
                app:itemMarginTop="-5dp"
                app:openTouchBg="true"
                app:touchDrawable="@drawable/selector_bg"
                />
    
            <com.clkj.bottombar.bottombar.BottomBarItem
                android:layout_width="0dp"
                android:layout_weight="1"
                android:layout_height="match_parent"
                app:iconNormal="@mipmap/tab_me_normal"
                app:iconSelected="@mipmap/tab_me_selected"
                app:itemText="我的"
                app:textColorNormal="@color/tab_normal_color"
                app:textColorSelected="@color/tab_selected_color"
                app:itemTextSize="8sp"
                app:itemMarginTop="-5dp"
                app:openTouchBg="true"
                app:touchDrawable="@drawable/selector_bg"
                />
    
        </com.clkj.bottombar.bottombar.BottomBarLayout>
    </LinearLayout>
    

    item_bottom_bar.xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
                  android:layout_width="match_parent"
                  android:layout_height="wrap_content"
                  android:layout_gravity="center"
                  android:gravity="center"
                  android:orientation="vertical"
        >
    
    
        <FrameLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
    
            <ImageView
                android:id="@+id/iv_icon"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                />
    
            <TextView
                android:id="@+id/tv_unred_num"
                android:layout_width="wrap_content"
                android:minWidth="15dp"
                android:layout_height="wrap_content"
                android:layout_gravity="center_horizontal"
                android:layout_marginLeft="14dp"
                android:background="@drawable/shape_unread"
                android:gravity="center"
                android:text="99+"
                android:textColor="@color/white"
                android:textSize="10sp"
                android:visibility="gone" />
    
            <TextView
                android:id="@+id/tv_msg"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center_horizontal"
                android:layout_marginLeft="14dp"
                android:background="@drawable/shape_msg"
                android:gravity="center"
                android:text="NEW"
                android:textColor="@color/white"
                android:textSize="6sp"
                android:visibility="gone" />
    
            <TextView
                android:id="@+id/tv_point"
                android:layout_width="10dp"
                android:layout_height="10dp"
                android:layout_gravity="center_horizontal"
                android:layout_marginLeft="10dp"
                android:background="@drawable/shape_notify_point"
                android:gravity="center"
                android:textSize="6sp"
                android:visibility="gone" />
    
        </FrameLayout>
    
    
        <TextView
            android:id="@+id/tv_text"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            />
    
    </LinearLayout>
    

    attr.xml

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
        <declare-styleable name="BottomBarItem">
            <!--默认状态下的图标-->
            <attr name="iconNormal" format="reference"/>
            <!--选中状态下的图标-->
            <attr name="iconSelected" format="reference"/>
    
            <!--底部文字-->
            <attr name="itemText" format="string"/>
            <!--文字大小-->
            <attr name="itemTextSize" format="dimension"/>
            <!--默认状态下的文字颜色-->
            <attr name="textColorNormal" format="color"/>
            <!--选中状态下的文字颜色-->
            <attr name="textColorSelected" format="color"/>
    
            <!--文字和图标的顶部距离-->
            <attr name="itemMarginTop" format="dimension"/>
    
            <!--是否开启触摸背景效果-->
            <attr name="openTouchBg" format="boolean"/>
            <!--设置触摸背景-->
            <attr name="touchDrawable" format="reference"/>
    
            <!--设置图标的宽度-->
            <attr name="iconWidth" format="dimension"/>
            <!--设置图标的高度-->
            <attr name="iconHeight" format="dimension"/>
    
            <!--设置BottomBarItem的padding-->
            <attr name="itemPadding" format="dimension"/>
    
            <!--设置未读数字体大小-->
            <attr name="unreadTextSize" format="dimension"/>
            <!--设置未读数字体颜色-->
            <attr name="unreadTextColor" format="reference"/>
            <!--设置未读数背景色-->
            <attr name="unreadTextBg" format="reference"/>
    
            <!--设置提示消息字体大小-->
            <attr name="msgTextSize" format="dimension"/>
            <!--设置提示消息字体颜色-->
            <attr name="msgTextColor" format="reference"/>
            <!--设置提示消息背景-->
            <attr name="msgTextBg" format="reference"/>
    
            <!--设置提示点背景-->
            <attr name="notifyPointBg" format="reference"/>
    
            <!--设置未读数组阈值 大于阈值的数字将显示为 n+ n为设置的阈值-->
            <attr name="unreadThreshold" format="integer"/>
        </declare-styleable>
    
        <declare-styleable name="BottomBarLayout">
            <attr name="smoothScroll" format="boolean"/>
        </declare-styleable>
    </resources>
    

    colors.xml

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
        <color name="colorPrimary">#3F51B5</color>
        <color name="colorPrimaryDark">#303F9F</color>
        <color name="colorAccent">#FF4081</color>
    
    
    
        <color name="tab_gb">#F3F5F4</color>
        <color name="tab_normal_color">#515051</color>
        <color name="tab_selected_color">#D33D3C</color>
    
        <color name="unreadTextColor">#00ff00</color>
        <color name="msgTextColor">#00ff00</color>
    
        <color name="red">#ff0000</color>
        <color name="selector_grey">#DDDDDD</color>
        <color name="white">#FFFFFF</color>
    </resources>
    
    tab_home_normal.png tab_home_selected.png tab_me_normal.png tab_me_selected.png tab_micro_normal.png tab_micro_selected.png tab_video_normal.png tab_video_selected.png

    当需要禁止viewpager滑动时

    /**
     * 可以控制滑动的ViewPager
     */
    public class MyViewPager extends ViewPager {
        private boolean mIsCanScroll = false;
    
        public MyViewPager(Context context) {
            super(context);
        }
    
        public MyViewPager(Context context, AttributeSet attrs) {
            super(context, attrs);
        }
    
        public boolean onTouchEvent(MotionEvent event) {
            if (this.mIsCanScroll) {
                return super.onTouchEvent(event);
            }
    
            return false;
        }
    
        @Override
        public boolean onInterceptTouchEvent(MotionEvent event) {
            if (this.mIsCanScroll) {
                return super.onInterceptTouchEvent(event);
            }
    
            return false;
        }
    
        public void setCanScroll(boolean isCanScroll) {
            this.mIsCanScroll = isCanScroll;
        }
    
        @Override
        public void setCurrentItem(int item) {
            super.setCurrentItem(item, false);
        }
    }
    

    在MainActivity设置mVpContent.setCanScroll(false);即可
    别忘了ViewPager将强转成MyViewPager

    新增常用的方法:

    点击返回提示 “再按一次退出程序” ,2秒内在按一次,退出APP

    /**
     * 管理activity stack
     */
    public class AppManager {
    
        private static Stack<Activity> mActivityStack;
        //存放Class信息Map
        private static Map<String,Class<?>> mClassMap = new HashMap<>();
    
        public AppManager() {
        }
    
        /**
         * 单一实例
         */
        public static AppManager getInstance() {
            return SingleApp.INSTANCE;
        }
    
        public static class SingleApp {
            public static AppManager INSTANCE = new AppManager();
        }
    
        /**
         * 获取map中的Class
         * @param className
         * @return
         */
        public Class<?> getClassFromMap(String className){
            return mClassMap.get(className);
        }
    
        /**
         * 添加Activity到堆栈
         */
        public void addActivity(Activity activity) {
            if (mActivityStack == null) {
                mActivityStack = new Stack<Activity>();
            }
            mActivityStack.add(activity);
            //加入到map
            mClassMap.put(activity.getClass().getSimpleName(),activity.getClass());
        }
    
        /**
         * 移除Activity
         */
        public void removeActivity(Activity activity) {
            mActivityStack.remove(activity);
            //从map中移除
            mClassMap.remove(activity.getClass().getSimpleName());
        }
    
        /**
         * 获取指定的Activity
         */
        public Activity getActivity(Class<?> cls) {
            if (mActivityStack != null)
                for (Activity activity : mActivityStack) {
                    if (activity.getClass().equals(cls)) {
                        return activity;
                    }
                }
            return null;
        }
    
        /**
         * 获取当前显示Activity(堆栈中最后一个传入的activity)
         */
        public Activity getLastActivity() {
            Activity activity = mActivityStack.lastElement();
            return activity;
        }
    
        /**
         * 获取所有Activity
         */
        public Stack<Activity> getAllActivityStacks() {
            return mActivityStack;
        }
    
        /**
         * 结束指定的Activity
         */
        public void finishActivity(Activity activity) {
            if (activity != null) {
                if (!activity.isFinishing()) {
                    activity.finish();
                    mActivityStack.remove(activity);
                }
            }
        }
    
        /**
         * 结束指定类名的Activity
         */
        public void finishActivity(Class<?> cls) {
            for (Activity activity : mActivityStack) {
                if (activity.getClass().equals(cls)) {
                    finishActivity(activity);
                    break;
                }
            }
        }
    
        /**
         * 结束除当前传入以外所有Activity
         */
        public void finishOthersActivity(Class<?> cls) {
            if (mActivityStack != null)
                for (Activity activity : mActivityStack) {
                    if (!activity.getClass().equals(cls)) {
                        activity.finish();
                    }
                }
        }
    
        /**
         * 结束所有Activity
         */
        public void finishAllActivity() {
            if (mActivityStack != null)
                for (Activity activity : mActivityStack) {
                    activity.finish();
                }
            mActivityStack.clear();
        }
    
    
        /**
         * 退出应用程序
         */
        public void AppExit() {
            try {
                finishAllActivity();
                android.os.Process.killProcess(android.os.Process.myPid());// 杀死该应用进程
                System.exit(0);
            } catch (Exception e) {
            }
        }
    }
    

    在MainActivity中入栈
    AppManager.getInstance().addActivity(this);
    然后复写方法

    /**
         * 退出程序逻辑
         *
         * @param keyCode
         * @param event
         * @return
         */
        private long lastBackTime = 0;
        private static final long TIME_INTERVAL = 2 * 1000;
        @Override
        public boolean onKeyDown(int keyCode, KeyEvent event) {
            if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0) {
                long currentBackTime = System.currentTimeMillis();
                Toast.makeText(MainActivity.this,"再按一次退出程序",Toast.LENGTH_SHORT).show();
                //双击退出程序
                if (currentBackTime - lastBackTime > TIME_INTERVAL) {
                    lastBackTime = currentBackTime;
                } else {
                    //退出
                    AppManager.getInstance().AppExit();
                }
                return true;
            }
            return super.onKeyDown(keyCode, event);
        }
    

    相关文章

      网友评论

        本文标题:通用的底部导航栏

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