BottomNavigationView - Shadow and Ripple Effect

后端 未结 8 684
闹比i
闹比i 2020-12-14 08:41

I was really happy when BottomNavigationView was released one week ago but I am facing some problems which makes me unable to solve it, like to see a shadow over the BottomN

8条回答
  •  执笔经年
    2020-12-14 09:00

    Take this FrameLayout that draws shadow and this gradient drawable xml:

    public class DrawShadowFrameLayout extends FrameLayout {
        private Drawable mShadowDrawable;
        private final int mShadowElevation = 8;
        private int mWidth;
        private int mHeight;
        private boolean mShadowVisible = true;
    
        public DrawShadowFrameLayout(Context context) {
            this(context, null, 0);
        }
    
        public DrawShadowFrameLayout(Context context, AttributeSet attrs) {
            this(context, attrs, 0);
        }
    
        public DrawShadowFrameLayout(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            init();
        }
    
        private void init() {
            mShadowDrawable = ContextCompat.getDrawable(getContext(), R.drawable.shadow);
            if (mShadowDrawable != null) {
                mShadowDrawable.setCallback(this);
            }
            setWillNotDraw(!mShadowVisible);
        }
    
        @Override
        protected void onSizeChanged(int w, int h, int oldw, int oldh) {
            super.onSizeChanged(w, h, oldw, oldh);
            mWidth = w;
            mHeight = h;
            updateShadowBounds();
        }
    
    
        private void updateShadowBounds() {
            if (mShadowDrawable != null) {
                mShadowDrawable.setBounds(0, 0, mWidth, mShadowElevation);
            }
            ViewCompat.postInvalidateOnAnimation(this);
        }
    
        @Override
        public void draw(Canvas canvas) {
            super.draw(canvas);
            if (mShadowDrawable != null && mShadowVisible) {
                getBackground().setBounds(0, mShadowDrawable.getBounds().bottom, mWidth, mHeight);
                mShadowDrawable.draw(canvas);
            }
        }
    
        public void setShadowVisible(boolean shadowVisible) {
            setWillNotDraw(!mShadowVisible);
            updateShadowBounds();
        }
    
        int getShadowElevation() {
            return mShadowVisible ? mShadowElevation : 0;
        }
    
    }
    

    Wrap your BottomNavigationView inside this this layout like:

    
      
    
    

    Unfortunately, the native shadow is drawn under the view, we have to mimic this upward shadow ourselves.

    Dont forget to add android:elevation="8dp" for the DrawShadowFrameLayout too.

    Another approach is extending BottomNavigationView and overriding draw() to do the same. This will help you loose one FrameLayout in your view hierarchy.

提交回复
热议问题