Android Toolbar Menu Icon "disappear" when image background matches color

861 views Asked by At

Take a look at this image

enter image description here

In the top left is the Android hamburger menu, but it is white. Also, in the right is a search magnifying glass, also white. The problem is the background is dynamically loaded from the server depending on what is being presented.

Is it possible to tint the menu icons, or elevate them, so that they appear when a situation like this occurs? That background image could really be any color, it really depends on what the server has for it. Maybe is it possible to use the Palette library on them as well?

EDIT: My solution so far based on @Steve response:

private void loadBackdrop( String inetref ) {
    Log.i( TAG, "loadBackdrop : inetref=" + inetref );

    String bannerUrl = MainApplication.getInstance().getMasterBackendUrl() + "/Content/GetRecordingArtwork?Inetref=" + inetref + "&Type=banner&Height=256";
    Log.i(TAG, "loadBackdrop : bannerUrl=" + bannerUrl);
    final ImageView imageView = (ImageView) findViewById( R.id.backdrop );
    final PaletteTransformation paletteTransformation = PaletteTransformation.getInstance();
    Picasso.with( this )
            .load( bannerUrl )
            .fit().centerCrop()
            .transform( paletteTransformation )
            .into(imageView, new Callback.EmptyCallback() {

                @Override
                public void onSuccess() {

                    Bitmap bitmap = ((BitmapDrawable) imageView.getDrawable()).getBitmap(); // Ew!
                    Palette palette = PaletteTransformation.getPalette(bitmap);

                    try {

                        int inverseColor = getComplementaryColor(palette.getVibrantColor(R.color.white));
                        Log.i( TAG, "loadBackdrop : inverseColor=" + inverseColor + ", Color.WHITE=" + Color.WHITE + ", Color.BLACK=" + Color.BLACK + ", Color." + ( inverseColor > ( Color.BLACK / 2 ) ? "WHITE" : "BLACK" ) );

                        int color = ( inverseColor > ( Color.BLACK / 2 ) ? Color.WHITE : Color.BLACK );

                        collapsingToolbar.setCollapsedTitleTextColor( color );
                        collapsingToolbar.setExpandedTitleColor( color );

                        Drawable newSearchMenuItem = mSearchMenuItem.getIcon();
                        newSearchMenuItem.mutate().setColorFilter( color, PorterDuff.Mode.SRC_IN );
                        mSearchMenuItem.setIcon( newSearchMenuItem );

                        Drawable newUpMenuItem = getResources().getDrawable( R.drawable.ic_arrow_back_white_24dp );
                        newUpMenuItem.mutate().setColorFilter( color, PorterDuff.Mode.SRC_IN );
                        getSupportActionBar().setHomeAsUpIndicator( newUpMenuItem );

                    } catch( Exception e ) {
                        Log.e( TAG, "error decoding palette from imageView", e );
                    }
                }

                @Override
                public void onError() {

                }

            });

}

public static int getComplementaryColor( int colorToInvert ) {

    float[] hsv = new float[ 3 ];
    Color.RGBToHSV( Color.red( colorToInvert ), Color.green( colorToInvert ), Color.blue( colorToInvert ), hsv );

    hsv[ 0 ] = ( hsv[ 0 ] + 180 ) % 360;

    return Color.HSVToColor( hsv );
}
1

There are 1 answers

6
mlz7 On BEST ANSWER

You should take a look at this. Basically what you can do is either create custom themes with different tinted .png files for the icons you want tinted and then set these themes in code depending on the background color you are given; or you can do something similar to what is shown on that website. Hope this helps!

EDIT: You can do something like this depending on background color:

MenuItem YOUR_MENU_ITEM = menu.findItem(R.id.YOUR_MENU_ITEM_ID);
Drawable NEW_ICON = (Drawable)YOUR_MENU_ITEM.getIcon();
NEW_ICON.mutate().setColorFilter(Color.argb(255, 200, 200, 200),PorterDuff.Mode.SRC_IN);
YOUR_MENU_ITEM.setIcon(NEW_ICON);

This would tint the icon gray but you can just change the color filter's values to suit your needs.

What you could do to solve the issue of dynamically loaded backgrounds is to use a case or nested if statement to check background of server, and then provide a color filter option for the more common colors (red, yellow, blue, etc.) generally black/white will show up on most backgrounds so you can use those as the default value.

EDIT: To do the color matching:

So you could do something like this which would just reverse the given color to its compliment..otherwise let me know if thats not what you are looking for