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.

About these ads
This entry was posted in android. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s