Особливості мультиоконного режиму на Android-планшетах

Привіт! У цій статті я хочу розповісти, які проблеми можуть виникнути з появою мультиоконного режиму на планшетних версій додатків. Команда Android-розробки компанії Лайв Тайпинг зіткнулася з ними, коли адаптувала додаток ІЛЬ ДЕ БОТЭ під планшет. Будьте готові до того, що ці ж проблеми будуть і у вас.

Як ви всі знаєте, в кінці серпня 2016 року вийшла Android 7.0, і однієї з її основних особливостей є підтримка мультиоконности. Це прекрасна функція, яка піднімає зручність Android на новий рівень. Всі користувачі будуть на сьомому небі від щастя, але те, що є щастям для користувача, може обернутися болем для розробника. На жаль, з мультиоконностью на планшетах саме так і сталося. І саме на планшетах — на телефонах з нею як раз все відмінно, заздалегідь кажу.

Якщо ви робите планшетні версії додатків або ви просто небайдужі до мультиоконному режиму, то ласкаво просимо в статтю!

Корінь всіх зол
Припустимо, ви розробник, який несподівано вирішив зробити в телефонному додатку підтримку мультиоконности. Ви все зробили правильно, верстали під ширину 320dp і взагалі ви молодець, а режим, до вашого щастя, працює просто відмінно. Навіть якщо ви не зовсім молодець, тому що не зробили підтримку маленьких екранів і верстали під 360dp або 480dp, то все ще залишається в порядку. Найжахливіше, що може з вами трапитися — трохи попливе верстка або подекуди текст на кнопці не влізе в один рядок. Але давайте будемо відверті, що це все дрібниці. Пара годин, максимум день і вуаля, PROFIT! Ви знову молодець і можете додавати нові фішки мультиоконности в вашу програму.

Але що, якщо у вас є не тільки телефонна версія програми, але і планшетна?

У вас виникнуть проблеми. Можливо, досить великі проблеми. Навіть, можливо, проблеми виявляться настільки величезними, що вам доведеться радикально змінювати архітектуру програми.

Робота мультиоконности на планшеті
Орієнтація екрану
Для простоти уявімо, що у нас є верстка для телефонів і верстка для 10-дюймових планшетів. Будемо розглядати всі на прикладі layout, тобто наші ресурси будуть лежати у таких папок:

  • layout-port
  • layout-land
  • layout-sw720dp-port
  • layout-sw720dp-land
Почнемо з вертикальній орієнтації. Наше додаток може позичати або весь екран, і буде використана верстка з layout-sw720dp-port:



Або половину екрану, і ресурси будуть братися з layout-land:



Або третина чи дві третини, і ресурси будуть братися з layout-land і layout-sw720dp-land відповідно:



Ви очікуєте, що landscape-режимі land і port просто поміняються місцями, але немає. Все трохи не так.

Якщо зайнятий весь екран, то використовується layout-sw720dp-land:



Якщо половина екрану, то layout-port:



Якщо третина чи дві третини, то layout-port і layout-sw720dp-land відповідно:



Демонстраційне додаток
З розташуванням ми розібралися. Багато хто, напевно, вже починають усвідомлювати можливі проблеми, але давайте по порядку. Спочатку уявімо, що ви зробили абстрактне додаток, яке ідеально працює на Android 6, але у якого будуть проблеми на Android 7. Заздалегідь прошу не чіплятися до того, як воно продумано, бо воно продумано так спеціально для демонстрації можливих проблем.

Отже, нехай додаток буде новинним і має три основні сутності: категорія, підкатегорія і новина. Телефонна версія може знаходиться тільки в портретній орієнтації і має три екрана, кожен з яких є окремим Activity:



  • Головний екран. На ньому є основні категорії новин, які представлені у верхніх табах. Всередині кожного таба є банер з самою головною новиною дня. Нижче представлений список підкатегорій всередині цієї категорії новин. При натисканні на цю підкатегорію ми потрапляємо на екран з її вмістом.


  • Екран списку новин. При натисканні на новину ми потрапляємо на окремий екран цієї новини.


  • Екран окремої новини. Тут ми показуємо новину в повному її обсязі.
Для планшета все влаштовано трохи по-іншому: є тільки два екрани, які також є Activity:




  • Головний екран. Зліва розташовується список категорій з вкладеністю у вигляді підкатегорій. Праворуч відображається список новин. Також в планшеті з'являється нова фішка: можна клікнути по категорії і побачити всі новини по ній.



  • Екран окремої новини. Тут, в принципі, все по-старому, просто трохи змінилася верстка.
Додаток має архітектуру MVP і у кожного екрана є Presenter і View. Як View використовується кастомный ViewGroup зразок такого. Для головного екрану і екрану списку новин використовуються абсолютно різні View і Presenter. Екрани новини на планшеті і на телефоні абсолютно ідентичні один одному за логікою, але з-за великих відмінностей візуальної частини нам потрібно щось більше, ніж просто різні xml. Тому реалізація View влаштована так: абстрактний клас NewsView, в якому знаходиться все загальні і наследующиеся від нього класи PhoneNewsView і TabletNewsView.

Тепер давайте ще трохи напружимо уяву і уявимо, що ми запустили наш додаток на 10-дюймовий планшет під управлінням Android 7 і включили режим мультиоконности.

Уявили? Давайте вже подивимося, що у нас вийшло.



Виглядає не дуже, а все тому, що раніше в телефонній версії ви не підтримували альбомну орієнтацію. Тому він бере ресурси з загальних ресурсів. Хоча в принципі все круто, трохи потягнуло банер, але це дрібниці. На радощах ви тицяєте на першу-ліпшу підкатегорію і потрапляєте на екран списку новин, з яким теж все не так вже погано.



Радість через край, і тут вас осіняє: «А що буде, якщо я знову разверну додаток і перейду на верстку планшета? Адже цього екрану не повинно бути в логіці роботи на планшеті». Ви молодці, це дуже правильна думка. Відбудеться наступне: у вас буде відображатися екран, якого тут не повинно бути. Більше того, вам покажуть його телефонну версію, що зіпсує зовнішній вигляд.

Проблеми
Проблема номер 1: якщо екран планшетній версії поєднує в собі кілька екранів з телефонної, то почнеться хаос.
Які тут є рішення? Ну, можна, наприклад, переробити все на фрагменти, в телефонній версії класти їх один на одного, а в планшетній — поруч. Profit! Але не варто забувати, що це легко зробити тільки на нашому маленькому абстрактному додатку, а в реальному додатку доведеться докласти багато зусиль. Також у вашому додатку може бути заморочена навігація, яку з допомогою фрагментів можна реалізувати із-за того, що вони не можуть зберігати стану своїх дочірніх фрагментів.

Припустимо ви переробили наш абстрактне додаток на фрагменти, але тут же згадуєте про незвичайну особливості планшета — можливості показати всі новини по всіх підкатегоріях якої-небудь категорії.

Проблема номер 2: якщо у планшетній версії є функціональність, якої немає у телефонній версії, і навпаки, то все буде погано.
Що ж робити? Доведеться додавати цю функціональність в телефонну версію, або прибирати її з планшетній. Як ви розумієте, в реальному житті таких функцій може бути дуже багато, і, швидше за все, це зажадає від вас безліч, безліч узгоджень, що в результаті виллється в клапті вирваних волосся і повні стакани гірких сліз. Добре, що в нашому маленькому абстрактному додатку його трохи, а то довелося б попрацювати.

Схоже, зі списком категорій все добре. Ви все налагодили і виправили, ви безумовно молодець. Ви заходите на екран окремої новини і намагаєтеся перейти в мультиоконный режим, але — упс! — додаток впало. У чому ж справа? А все із-за того, що ваш PhoneNewsView і TabletNewsView мають один і той же id. Виходить, що onSaveInstanceState робиться для одного класу, а onRestoreInstanceState вже для іншого.

Проблема номер 3: якщо в xml планшетній версії і телефонної версії різні класи мають один і той же id, то ви напевне втомитеся це виправляти.
Як це обійти? Можна просто поставити їм різні id, але тут відразу вимальовується проблема зі збереженням стану при зміні режиму мультиоконности, а саме те, що його не буде. Вихід є: зробити все так, щоб у коді не було ніяких відмінностей між планшетній і телефонної версією, хіба що в XML. Якщо вже є гостра необхідність додати в планшеті якийсь новий елемент, то краще просто перевірити його на null і вже потім робити з цим елементом.

З цією проблемою ви блискуче впоралися, вітаю. Тут ви несподівано згадуєте, що на цьому ж екрані, в телефонній версії, відразу ж під картинкою новини у вас написано «Якщо у вас є планшет, то спробуйте нашу планшетну версію». Жахливо! Ну, насправді, порівняно з попередніми проблемами це просто квіточки, але все ж неприятненько.

Взагалі, це не проблема номер 4. Просто, я хотів розповісти, як брати планшетні ресурси, якщо програма, по ідеї, повинно брати телефонні.

Так що ж робити? Якщо в режимі мультиоконности брати ресурси від Application, то він буде повертати їх для планшета; якщо від Activity, View, Fragment і всього іншого, що не Application, то буде повертати для їх розміру. Тобто, якщо ділити екран навпіл, то Application буде повертати планшетні ресурси, а все інше — телефонні. Думаю це пов'язано з тим, що, по ідеї, один додаток можна розбити на кілька вікон. Може бути, багато задумали хитрий план — робити setContentView у Activity не по id, а за «в'юсі», яку ви заздалегідь заинфлейтили з допомогою Application. АЛЕ! Робити так не варто. Інакше ваш додаток буде виглядати ось так:



З допомогою Application ви дозволили дилему з непотрібною рядком. Задоволені собою і виконаною роботою, ви откинулись на стільці і подумали про те, навіщо Google ввели стільки додаткових «кейсів» і наскільки тепер ускладнитися життя пересічного Android-розробника.

Важлива деталь про Android SDK
Насправді c мультиоконностью у Google все в порядку. Чому ж виникають проблеми з планшетом? Тому що в Android SDK поняття «планшет» не існує. Взагалі. Є маленькі, середні, великі екрани… Але поняття «планшет» немає. Не повинно бути ніякої окремої логіки, не повинно бути ніякої додаткової функціональності.

Проблема не в тому, що Google зробили все погано, просто як такого «особливого додатка» під планшет не повинно бути в принципі. Звідки взагалі у всіх манія робити програми окремо під планшет? З iOS, але там дійсно є поняття планшета і для нього є можливість зробити все по-іншому.

Android-додатки, на мій погляд, в цьому плані більше схожі на Web: у вас є сторінка і певний набір даних, і вам потрібно зробити так, щоб на всіх екранах і у всіх браузерах все виглядало добре. Нічого не нагадує? Багато видів екранів і дуже велика фрагментація пристроїв, багато з них зі своїми особливостями, ось це ось все? По мені так здається.

Особливість описаних мною проблем, в тому, що їх не повинно бути, але я сподіваюся, що допоміг вам розібратися з ними, якщо вони виникли, або попередив їх виникнення. Погляньте на Google Play: ви можете відкрити його на будь-якому пристрої, і він буде виглядати, може, і не відмінно, але хоча б добре. Це тому, що Google Play спочатку створювали з можливістю відображатися на екрані будь-якого розміру. При тому, що набір даних завжди однаковий.

Це дуже хороша практика. Ви можете змінити кількість стовпців, відступи, розмір елементів, приховувати або відображати якийсь елемент і ще купу всього, але загальна логіка і набір даних повинні залишатися незмінним. Саме це, на мій погляд, заставу крутого програми.

Тема філософська і, само собою, спірна, так що ласкаво просимо в коментарі. Всім пока!
Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.