Search code examples
javaandroidandroid-imageviewalphaandroid-background

How to programmatically show/hide only the background/image of an ImageView in Android?


I have an ImageView, and its alpha is set to 0 in the XML. The XML looks like this:

<LinearLayout

            android:layout_width="match_parent"
            android:layout_height="<height>"
            android:orientation="horizontal">

            <ImageView
                android:id="@+id/<id>"
                android:layout_width="<width>"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:alpha="0"
                android:background="#ff00ff"
                android:clickable="true"
                android:focusable="true"
                app:srcCompat="@drawable/<drawable>" />

            <ImageView
                android:id="@+id/<id>"
                android:layout_width="<width>"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:alpha="0"
                android:background="#0000ff"
                android:clickable="true"
                android:focusable="true"
                app:srcCompat="@drawable/<drawable>" />

</LinearLayout>

I tried searching how to do this, but most questions are about how to hide the background or the entire ImageView, and not just the background. Also, the alpha has to be set to "0". Is there any way to hide only the image so that only the background (solid color) is visible? Only the background colors of both ImageViews have to be displayed, so the container (LinearLayout)'s background cannot be used to do this for both (the background colors are different).

Changing the image's source to an image which is a solid color, the same as the background color, would work, but I need to change this color programmatically, so it might be inefficient. I've also tried different combinations of ImageView.- setAlpha(float), setImageAlpha(int), setImageResource(int) (to 0) and setImageDrawable(Drawable) (to show the image again, with the background [color]), but they produce weird results. Using setImageResource(0) (with alpha 1f) hides the image, showing only the solid background, but I'm not able to display the image again. Is there any easy method I'm unaware of?

I need to do this programmatically, so methods like in Java android Linearlayout set two colors wouldn't work. What is the best way to do this programmatically?


Solution

  • Well, it's not directly possible to work it as expected with two views, and as you said, you have multiple views like that & that's why it's not memory efficient.

    But We can achieve that functionality using CustomView designed according to our needs.

    If you know a little bit of drawing on the canvas and how it works, then it'll be easier.

    Here, I made the custom view to achieve exactly what you want.

    public class ImageAlphaBGView extends View {
        private Bitmap bitmap;
        Paint mPaint;
        Paint mPaintBG;
        Rect bgRect;
    
        private int mWidth;
        private int mHeight;
        float centreX;
        float centreY;
    
        public ImageAlphaBGView(Context context) {
            super(context);
            init();
        }
    
        public ImageAlphaBGView(Context context, @Nullable AttributeSet attrs) {
            super(context, attrs);
            init();
        }
    
        public ImageAlphaBGView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            init();
        }
    
        public ImageAlphaBGView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
            super(context, attrs, defStyleAttr, defStyleRes);
            init();
        }
    
        private void init() {
            mPaint = new Paint();
            mPaint.setColor(Color.RED);
            mPaint.setStyle(Paint.Style.FILL);
            mPaint.setAntiAlias(true);
    
            mPaintBG = new Paint();
            mPaintBG.setColor(Color.parseColor("#000000"));
            mPaintBG.setStyle(Paint.Style.FILL);
            mPaintBG.setAntiAlias(true);
        }
    
        public void setImageBitmap(Bitmap bitmap) {
            this.bitmap = bitmap;
            try {
                centreX = (mWidth - bitmap.getWidth()) / 2;
                centreY = (mHeight - bitmap.getHeight()) / 2;
            } catch (Exception e) {
                e.printStackTrace();
            }
            invalidate();
        }
    
        public void setBGColor(int color) {
            mPaintBG.setColor(color);
            invalidate();
        }
    
        public void setImageAlpha(@IntRange(from = 0, to = 255) int alpha) {
            mPaint.setAlpha(alpha);
            invalidate();
        }
    
        public void setBGAlpha(@IntRange(from = 0, to = 255) int alpha) {
            mPaintBG.setAlpha(alpha);
            invalidate();
        }
    
        @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
            canvas.drawRect(bgRect, mPaintBG);
            if (bitmap != null)
                canvas.drawBitmap(bitmap, centreX, centreY, mPaint);
        }
    
        @Override
        protected void onSizeChanged(int w, int h, int oldw, int oldh) {
            super.onSizeChanged(w, h, oldw, oldh);
            mWidth = w;
            mHeight = h;
    
            bgRect = new Rect(0, 0, mWidth, mHeight);
            invalidate();
        }
    }
    

    Simply put this view in your xml & then you can programmatically pass a bitmap and alpha of the background.

    It supports setting up image alpha, background alpha seperately as well as background color.

    Here is what you need to do :

    In the xml,

    <com.demo.example.views.ImageAlphaBGView
                android:id="@+id/alphaView"
                android:layout_width="150dp"
                android:layout_height="150dp"/>
    

    In the activity or fragment,

    ImageAlphaBGView imageView = findViewById(R.id.alphaView)
    imageView.setImageBitmap(bitmap)
    imageView.setBGColor(Color.RED)
    imageView.setImageAlpha(255)
    

    And you've got it. :)