Затемнение изображения в CollapsingToolbarLayout или Image Scrim

В этой статье я хочу с вами поделиться на мой взгляд нужной и интересной информацией. Речь пойдет о такой вещи, как Image Scrim (скажу сразу, что данное понятие я ввел самостоятельно).




Предисловие


Не так давно занимаясь разработкой проекта, я столкнулся с небольшой неприятностью. Проект был связан с получением данных через Dribbble API. При получении изображения и сортировкой их в RecyclerView мне пришлось передавать имидж из одной активности в другую. Так как в этом проекте нужно было использовать современные решения, все это дело при клике на item в RecyclerView я решил реализовать с помощью CollapsingToolbarLayout и в него вставить Image. 
Чтоб было понятней о чем я говорю (читай «не лить воду»), приведу пример:


Как видно на данной гифке, изображение располагается на белом фоне и если бы не Image Scrim, которые я реализовал, тогда бы названия изображения «Happy Octopus» не было бы видно (белый шрифт на белом изображении).

Ну а теперь приступим к реализации.

Реализация


На самом деле т.н. Image Scrim — это обычные View элементы внутри CollapsingToolbarLayout.

1. В необходимом layout после имиджа внутри CollapsingToolbarLayout создаем две кастомные вьюхи, например так:

<android.support.design.widget.CollapsingToolbarLayout android:id="@+id/collapsing_toolbar" android:layout_width="match_parent" android:layout_height="wrap_content" android:fitsSystemWindows="true" app:contentScrim="?attr/colorPrimary" app:layout_scrollFlags="scroll|exitUntilCollapsed" app:expandedTitleTextAppearance="@style/TextAppearance.AppCompat.Large"> <ImageView android:id="@+id/image_shot" android:layout_width="match_parent" android:layout_height="@dimen/shot_image_height" android:background="@color/colorPrimary" android:scaleType="centerCrop" app:layout_collapseMode="parallax" /> <View android:layout_width="match_parent" android:layout_height="@dimen/text_scrim_height_top" android:background="@drawable/scrim_top" app:layout_collapseMode="pin"/> <View android:layout_width="match_parent" android:layout_height="88dp" android:layout_gravity="@dimen/text_scrim_height_bottom" android:layout_alignBottom="@+id/image_shot" android:background="@drawable/scrim_bottom"/>...

2. Создаем 2 файла в drawable, которые отвечают за тень от верхнего края и нижнего имиджа и назовем их соответсвенно: 

scrim_top.xml

<shape xmlns:android="http://schemas.android.com/apk/res/android"> <gradient android:angle="270" android:startColor="@color/translucent_scrim_top" android:centerColor="@color/translucent_scrim_top_center" android:endColor="@android:color/transparent"/> </shape>

scrim_bottom.xml

<shape xmlns:android="http://schemas.android.com/apk/res/android"> <gradient android:angle="90" android:startColor="@color/translucent_scrim_bottom" android:centerColor="@color/translucent_scrim_bottom_center" android:endColor="@android:color/transparent"/> </shape>

3. Добавляем цвета в colors:

<color name="translucent_scrim_top">#33000000</color> <color name="translucent_scrim_top_center">#26000000</color> <color name="translucent_scrim_bottom">#4D000000</color> <color name="translucent_scrim_bottom_center">#40000000</color>

С прозрачностью цветов можно поиграться, чтоб подобрать более плавные цвета.

4. В dimens.xml добавляем следующие строки: 

<dimen name="text_scrim_height_top">50dp</dimen> <dimen name="text_scrim_height_bottom">88dp</dimen>

Методом тыка выяснил, что эти отступы от верхнего и нижнего края отлично подходят для изображения в 300 dp, поэтому если у вас изображение равностороннее, тогда с dp можно поиграться, то есть привести в соответствие со своими принципами своего дизайна.

P.S. Надеюсь статья оказалось полезной. Буду рад ответить на все вопросы, если таковы будут.

P.P.S. Также может вам быть полезна следующая небольшая табличка с альфа-каналами цветов для того, чтоб подобрать нужную прозрачность для Image Scrim.