Статьи

Добавление значков наложения в ImageViews

Во время работы над Serenity для Android одним из многих запросов, которые я получил, было отображение индикатора статуса отслеживания над плакатом. Есть несколько способов сделать это на Android.

  • Используйте холст и нарисуйте значок наложения на существующее растровое изображение
  • Используйте макет и наложите значок по мере необходимости.

Первый подход работает, но оставляет растровое изображение с постоянно встроенным в него изображением, что означает, что если вы хотите иметь переключатель, вам нужно перерисовать растровое изображение снова и отобразить его без него.

Второй подход требует немного большего рефакторинга некоторого кода в Serenity, но оказался более гибким. Используя RelativeLayout и добавив в него два ImageView, я мог бы легко переключать видимость наблюдаемого индикатора, а также довольно легко допускать некоторые будущие наложения в случае необходимости.

Вот этот макет:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
<?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>

RelativeLayout обеспечивает более общее позиционирование видов, поэтому идеально подходит для настройки отображения индикатора наблюдаемого состояния в правом нижнем углу плаката. Чтобы использовать это представление, мне нужно было использовать инфлятор макета, чтобы получить представление, а затем заполнить его изображениями. Основы здесь:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
@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;
}

Выше приведен Адаптер, используемый для визуализации представлений. Он использует адаптер галереи, но также работает и в TwoWayGridView. Он извлечет плакат, который будет использоваться, и настроит параметры макета для представления изображения, а также удостоверится, что сам RelativeLayout установлен в тот же размер, что и ImagePoster, который он инкапсулирует (использование содержимого переноса, похоже, не работает как ожидается с RelativeLayout). Затем он проверяет, является ли количество просмотров видео больше 0, если это так, и устанавливает растровое изображение наложения, которое будет использоваться на плакате. Наконец, он возвращает вновь заполненный вид галереи в галерею для отображения.

Приятно то, что с помощью XML-макета можно легко добавить другие наложения, если необходимо, добавив необходимую разметку и включив их при необходимости. Я уверен, что есть и другие способы сделать это, но это, кажется, работает довольно хорошо и довольно гибко для будущей способности расширения.

Ссылка: Добавление наложенных значков в ImageViews от нашего партнера JCG Дэвида Карвера в блоге Intellectual Cramps .