Adding Overlay Icons to ImageViews

While working on Serenity for Android, one of the many requests I received was to have a Watched Status indicator appear over the poster. There are a couple of ways to do this on Android.

  • Use a Canvas and draw the overlay icon on to the existing bitmap
  • Use a Layout and overlay the icon as needed.

The first approach works, but leaves the bitmap with the image embedded in it permanetly, meaning if you want to have a toggle you have to redraw the bitmap again and display it without it.

The second approach required a bit more refactoring of some code in Serenity but turned out to be more flexible.  By using a RelativeLayout and emebedding two ImageViews in it, I could easily toggle the visibility of the watched indicator, and also allow for some future overlays if necessary fairly easily.

Here is the layout in question:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/posterIndicatorView"
    android:background="@drawable/gallery_item_background" >

    <us.nineworlds.serenity.ui.views.SerenityPosterImageView
        android:id="@+id/posterImageView"
        android:scaleType="fitXY"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        />
    <ImageView android:id="@+id/posterWatchedIndicator"
        android:scaleType="fitXY"
        android:layout_width="33dp"
        android:layout_height="33dp"
        android:layout_alignParentBottom="true"
        android:layout_alignParentRight="true"
        />
</RelativeLayout>

The RelativeLayout allows for more general positioning of the views, so is ideal for setting the watched status indicator to appear in the lower right corner of the poster. In order to use this view, I needed to use a layout inflator to get the view, and then populate it with the images. The basics are here:

@Override
public View getView(int position, View convertView, ViewGroup parent) {
   View galleryCellView = context.getLayoutInflater().inflate(R.layout.poster_indicator_view, null);
   VideoContentInfo pi = posterList.get(position);
   SerenityPosterImageView mpiv = (SerenityPosterImageView) galleryCellView.findViewById(R.id.posterImageView);
   mpiv.setPosterInfo(pi);
   mpiv.setBackgroundResource(R.drawable.gallery_item_background);
   mpiv.setScaleType(ImageView.ScaleType.FIT_XY);
   int width = 0;
   int height = 0;

   width = ImageUtils.getDPI(130, context);
   height = ImageUtils.getDPI(200, context);
   if (!MovieBrowserActivity.IS_GRID_VIEW) {
      mpiv.setLayoutParams(new RelativeLayout.LayoutParams(width, height));
      galleryCellView.setLayoutParams(new SerenityGallery.LayoutParams(width, height));
   } else {
      width = ImageUtils.getDPI(120, context);
      height = ImageUtils.getDPI(180, context);
      mpiv.setLayoutParams(new RelativeLayout.LayoutParams(width, height));
      galleryCellView.setLayoutParams(new TwoWayAbsListView.LayoutParams(width, height));
   }

   imageLoader.displayImage(pi.getImageURL(), mpiv);

   if (pi.getViewCount() > 0) {
      ImageView viewed = (ImageView) galleryCellView.findViewById(R.id.posterWatchedIndicator);
      viewed.setImageResource(R.drawable.overlaywatched);
   }
   return galleryCellView;
}

The above is in the Adapter used to render the views. It uses a Gallery adapter, but also works in a TwoWayGridView as well. It will fetch the poster to be used, and setup the Layout Parameters for the image view, it will also make sure the RelativeLayout itself is set to the same size as the ImagePoster that it encapsulates (using wrap content doesn’t seem to work as expected with a RelativeLayout). It then checks to see if the view count on the video is greater than 0 if so, it sets the overlay bitmap to be used on the poster. Finally it returns the newly populate gallery view to the Gallery to be displayed.

The nice thing here is that using the XML layout one can easily add other overlays if necessary by adding the necessary markup and enabling them when necessary. I’m sure there are other ways to do this as well, but this seems to work fairly well and is pretty flexible for future expand-ability.
 

Reference: Adding Overlay Icons to ImageViews from our JCG partner David Carver at the Intellectual Cramps blog.
Related Whitepaper:

Rapid Android Development: Build Rich, Sensor-Based Applications with Processing

Create mobile apps for Android phones and tablets faster and more easily than you ever imagined

Use 'Processing', the free, award-winning, graphics-savvy language and development environment, to work with the touchscreens, hardware sensors, cameras, network transceivers, and other devices and software in the latest Android phones and tablets.

Get it Now!  

Leave a Reply


3 + = eight



Java Code Geeks and all content copyright © 2010-2014, Exelixis Media Ltd | Terms of Use
All trademarks and registered trademarks appearing on Java Code Geeks are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries.
Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.

Sign up for our Newsletter

15,153 insiders are already enjoying weekly updates and complimentary whitepapers! Join them now to gain exclusive access to the latest news in the Java world, as well as insights about Android, Scala, Groovy and other related technologies.

As an extra bonus, by joining you will get our brand new e-books, published by Java Code Geeks and their JCG partners for your reading pleasure! Enter your info and stay on top of things,

  • Fresh trends
  • Cases and examples
  • Research and insights
  • Two complimentary e-books