1

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 );
}
dmfrey
  • 1,230
  • 1
  • 17
  • 33

1 Answers1

1

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

Community
  • 1
  • 1
mlz7
  • 2,067
  • 3
  • 27
  • 51
  • thank you for this. Using your suggestion, this is what I did. I am loading the image with Picasso. Then, when loaded using Palette to pull out colors from the resulting image so that I can dynamically color the search, up arrow and the title. Results are not always ideal but at least the icons are visible. You mentioned about checking the color, how do you go about doing that. I could see using Palette to pull the inverse of what the dominant background color of the image is. – dmfrey Aug 11 '15 at 12:41
  • based on the link you posted, I think a good algorithm would be check the intensity at a spot in the toolbar height and either color the back arrow, search and title black or white based on the intensity. On scroll, the colors of the icons, title and toolbar itself could be set back to their default colors. They animate nicely to an from the expanded and collapsed views. To check the color with the link you posted, is that to check the color on one pixel, or are they determining this based on the image as a whole? – dmfrey Aug 11 '15 at 18:12
  • @dmfrey well you can get the color at a specific pixel by doing something like [this](http://stackoverflow.com/questions/7807360/how-to-get-pixel-colour-in-android) and then go on from there – mlz7 Aug 11 '15 at 18:49
  • i will try both approaches to see if one produces better results than the other. – dmfrey Aug 11 '15 at 19:53
  • thanks for all your help. Check out my edit above. This seems to be enough to make it consistent for the various backgrounds. – dmfrey Aug 12 '15 at 00:47
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/86742/discussion-between-dmfrey-and-steve). – dmfrey Aug 12 '15 at 01:32