Как использовать <merge> для оптимизации лейаутов? | OTUS

Курсы

Курсы в разработке Подготовительные курсы
Работа в компаниях Компаниям Блог +7 499 110-61-65

Как использовать <merge> для оптимизации лейаутов?

Android_Deep_19.12_site-5020-4105f9.png

Представим себе простую ситуацию — нам нужно создать вью, отражающий название компании и её рейтинг, и его мы будем пятьдесят раз использовать в приложении. Например, что-то вроде:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   android:orientation="horizontal">

   <ImageView
       android:id="@+id/rating"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:layout_marginRight="16dp" />

   <TextView
       android:id="@+id/name"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content" />
</LinearLayout>

Теперь давайте создадим класс, его описывающий. Допустим, у нас будут два метода: один меняет картинку рейтинга в зависимости от значения, а другой задаёт имя:

public class RatingView extends LinearLayout {

   private TextView nameView;
   private ImageView ratingView;

   public RatingView(Context context, @Nullable AttributeSet attrs) {
       super(context, attrs);
       LayoutInflater.from(context).inflate(R.layout.name_view, this);
       ratingView = findViewById(R.id.rating);
       nameView = findViewById(R.id.name);
   }

   public void setRating(int rating) {
       switch (rating) {
           case 1:
               ratingView.setImageResource(R.drawable.one_star);
               break;
           case 2:
               ratingView.setImageResource(R.drawable.two_star);
               break;
           case 3:
               ratingView.setImageResource(R.drawable.three_star);
               break;
       }
   }


   public void setName(String value) {
       nameView.setText(value);
   }

}

Отлично. Теперь давайте запихнём наш вью в лейаут активити:

<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:app="http://schemas.android.com/apk/res-auto"
   xmlns:tools="http://schemas.android.com/tools"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   tools:context=".MainActivity">

   <com.otus.merge.RatingView
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       app:layout_constraintBottom_toBottomOf="parent"
       app:layout_constraintLeft_toLeftOf="parent"
       app:layout_constraintRight_toRightOf="parent"
       app:layout_constraintTop_toTopOf="parent" />

</android.support.constraint.ConstraintLayout>

Запустим приложение и заглянем в Tools > Android > Layout Inspector — посмотрим, что же у нас там такое:

Android2-20219-a16f11.jpg

Вот как выглядит наше дерево вью:

Android3-20219-a9be8f.jpg

Видим, что RatingView, расширяющий LinearLayout, содержит в себе ещё один LinearLayout, а внутри уже наши вьюшки. Теперь, используя <merge>, посмотрим, удастся ли нам исправить ситуацию:

<merge xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:tools="http://schemas.android.com/tools"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   tools:parentTag="android.widget.LinearLayout"
   android:orientation="horizontal">

   <ImageView
       android:id="@+id/rating"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:layout_marginRight="16dp" />

   <TextView
       android:id="@+id/name"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content" />
</merge>

Запустили приложение. Идём в Tools > Android > Layout Inspector.

И, ура! Android4-20219-8c204f.jpg

Мы убрали лишний LinearLayout.

Делаем выводы

Итак, для чего же был создан <merge>? Для оптимизации лейаутов путём уменьшения количества уровней в дереве вью. Когда LayoutInflater встречает этот тег, он пропускает его и добавляет дочерние элементы <merge> к родителю <merge>. Этот тег очень полезный и может использоваться во множестве ситуаций, а также он прекрасно комбинируется с <include>.

Несколько моментов, которые нужно учитывать: — <merge> всегда должен быть корневым тегом; — в <merge> нужно обязательно указывать parentTag, как мы сделали в примере выше.

Задать дополнительные вопросы по использованию <merge> всегда можно в комментариях.

Не пропустите новые полезные статьи!

Спасибо за подписку!

Мы отправили вам письмо для подтверждения вашего email.
С уважением, OTUS!

Автор
0 комментариев
Для комментирования необходимо авторизоваться