Fragment Toolbar.

Manage it better.

Introduction

Since I started work commercially I met an opinion that working with Fragments is not always intuitive, at least not as much as working with Activities. Especially after watching this video your mindset in context of Fragments might change significantly. Complicated lifecycle, hard management will not change the way of thinking about it.

Few weeks ago I had to deal with really big thing. I’ve moved big app built in 95% on Activities to Fragments. I was very long way, very hard one. I’ve learnt a lot, so wanted to share this knowledge with you.

Toolbar for Fragment. What is wrong with it ?

Let’s assume that we have only one Activity with bottom navigation and the rest of views are Fragments. Normally on every Fragment change toolbar is set as supportActionBar which gives you possibilities to use methods to create, prepare, manage toolbar options menu. It looks simple, doesn’t it?
But it also creates some problems:

  • Before creating new toolbar on another Fragment you need to clear the old one.
  • If you are clearing it, indeed you are losing state and all data.
  • When you are going back to previous Fragments you have to recreate whole action bar.

As you can see it is a very inconvenient process, hard to maintain and generates a lot of boilerplate code. Especially if you are using searchView all those disadvantages mentioned above are unacceptable.

What is the solution ?

Assuming that we have few types of toolbar in app, you can build it using Builder Pattern and handle all cases in one place. All work comes down to choosing options for your Toolbar.

Starting point is to select one of two possible solutions. First one suggests to create one Toolbar and add it from code to your views. The second, which I have chosen is to implement toolbar in every Fragment’s .xml file. Basically, it was much easier for me because it was already done (refactoring code from Activities), so code below will match the second option.

Lets create FragmentToolbar Builder which contains all options we need in our app. I’m using Kotlin to achieve it, but my Fragments are still in Java, so I had to use implementation readable for Java.

Nothing revealing, let’s add those options to our toolbar.

Create BaseFragment which will be inherited by every Fragment.

Finally we are prepared to create Toolbars for our Fragments! Now every Fragment must specify which options will be used or if the Toolbar should even exist. Following the simple example:

To more complex:

Summary

Everyone knows how much time we spend on adding menu options and how many lines in code we need to write or copy/paste. This solution saves your time and keeps code clean. No need to set toolbar as supportActionBar. You don’t have to worry about keeping state and data for menu when Fragment changes (it lives as long as your Fragment). To sum up, management is as simple as possible and fragmentManager backstack changes (adding / removing Fragments) has no effect on toolbar at all.

Читайте также:  Рдр 2 для андроид

Personally I feel better when I’m dealing with Activities. Working with Fragments pushed me to simplify this process. So when you’ll be in the same situation — don’t fight with it, just do it by your own.

If you like my work hit clap button and let me know what you think in comments!

Источник

Смена title в toolbar во фрагменте

Как выровнять logo,title и subtitle в toolbar
Доброго времени суток, возник такой вопрос, как можно переместить Logo,Title,Subtitle ближе к.

Смена Toolbar при смене фрагментов в Activity
Добрый день! Есть Toolbar, который подключен к MainActivity. При запуске приложение открывается.

Смена и вывод title
Для работы со страницей определяется global $APPLICATION, но в ядре D7 они вроде отказались от.

Смена логотипа возле title
Смена логотипа возле title , при поиске сайт выводиться мой и лого хостинга там висит , как сменить.

Решение

Да что ж этот котлин себе позволяет. методы ворует

Смена title в компоненте com_cotalog
Всем доброго времени суток! Столкнулся с такой проблемой. Воспользовался стандартным каталогом в.

Вывод во втором фрагменте длины текста, введённого в первом фрагменте активити
Создать активити с двумя фрагментами. В первый фрагмент должен содержать поле ввода, второй.

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

Dle тег в alt и title изображений<br/>Хочется реализовать фишку, чтобы в shortstory изображения img не имеющее атрибутов title и alt.</p> <p style="clear: both"> <img decoding="async" style="float: left; margin: 0 10px 5px 0;" src="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%200%200'%3E%3C/svg%3E" data-lazy-src="https://cyberstatic.net/images/misc/tick.png"/><noscript><img decoding="async" style="float: left; margin: 0 10px 5px 0;" src="https://cyberstatic.net/images/misc/tick.png"/></noscript>Парсиг Jsoup. Как спарсить не только title но и дату с ссылкой на новость ? У меня получается только title<br/>Получается спарсить и добавить в listview только title . А мне нужно спарсить еще и дату с url .</p> <p><span class="link" data-link="http://www.cyberforum.ru/android-dev/thread2822735.html" >Источник</span></p> <h2 id="sozdanie-toolbar-v-fragment">Создание ToolBar в Fragment</h2> <p>Создаю активити на нем фрагмент, а в фрагменте должен быть ToolBar! Но его нет! Делаю так</p> <p>высоту/ширену задаю в стилях !</p> <p><b>Вроде все так! Может что-то пропустил? Подскажите в чем ошибка моя !! Спасибо!</b> </p> <p><strong>Обновление fragment из другого fragment</strong><br/>Добрый вечер всем!! Подскажите пожалуйста как обновить один фрагмент из другого (а именно TextView.</p> <p><strong>Создание Toolbar’ а</strong><br/>Необходимо создать Toolbar с 3-я кнопками, по нажатию которых будут вызваны диалоги: a) открытие.</p> <p><strong>Создание Toolbar</strong><br/>Привет! Столкнулся с проблемой, нужно сделать Toolbar ( как VS Windows Form или QT creator).</p> <p><strong>Создание Toolbar</strong><br/>Нужно из имеющего изображения кнопок создать панель инструментов. Делаю все, как описано на MSDN.</p> <p>поместить тулбар во фрагмент можно, но это не кошерно и глупо <br/>в идеале есть активити в которой тулбар и под тулбаром какой-то лаяут <br/>и этот лаяут используется как контейнер для фрагментов</p> <p>если нужно делать свое меню для каждого фрагмента то можно почитать тут </p> <h2 id="reshenie-2">Решение</h2> <p>Создание ToolBar: CreateToolbarEx()<br/>Здравствуйте! Не получается создать ToolBar. На мой взгляд все правильно, но вылазит ошибка .</p> <p>Создание кнопок на ToolBar-е<br/>Создаю Win32 Application, в оконной процедуре главного окна пишу (WM_CREATE): DWORD dwStyle;.</p> <p>Создание toolbar для ie 6+ на C#<br/>Необходимо создать с 0 toolbar для ie 6++ на c#. Был бы благодарен за любую информацию, литературу.</p> <p style="clear: both"> <img decoding="async" style="float: left; margin: 0 10px 5px 0;" src="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%200%200'%3E%3C/svg%3E" data-lazy-src="https://cyberstatic.net/images/misc/tick.png"/><noscript><img decoding="async" style="float: left; margin: 0 10px 5px 0;" src="https://cyberstatic.net/images/misc/tick.png"/></noscript>Динамическая форма — Создание ToolBar<br/>Доброго времени суток, Уважаемые спецы! Столкнулся с необходимостью создания нового ToolBar в окне.</p> <p><span class="link" data-link="http://www.cyberforum.ru/android-dev/thread1686114.html" >Источник</span></p> <h2 id="handling-lifecycle-with-view-binding-in-fragments">Handling Lifecycle with View Binding in Fragments</h2> <p style="clear: both"><img decoding="async" src="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%200%200'%3E%3C/svg%3E" data-lazy-src="https://miro.medium.com/fit/c/96/96/1*PZe0vd_2m33r8IkiTmtvnQ.jpeg"/><noscript><img decoding="async" src="https://miro.medium.com/fit/c/96/96/1*PZe0vd_2m33r8IkiTmtvnQ.jpeg"/></noscript></p> <p style="clear: both"><img decoding="async" src="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%200%200'%3E%3C/svg%3E" data-lazy-src="https://miro.medium.com/max/1400/1*LgPorX7yk1LaccqIzU1Wpg.jpeg"/><noscript><img decoding="async" src="https://miro.medium.com/max/1400/1*LgPorX7yk1LaccqIzU1Wpg.jpeg"/></noscript></p> <p>View Binding is an upcoming feature in Android, available in Android Studio 3.6 Canary 11+ which allows you to more easily interact with Views. It’s quick and easy to enable, and allows for type-safe view access. We’re likely all going to be using it in Fragments. Let’s explore how we can use it, in a safe and easy way!</p> <div style="clear:both; margin-top:0em; margin-bottom:1em;"><a href="https://service-play.ru/what-is-thumbnail-cache-android/" target="_blank" rel="nofollow" class="u57aa3838fc9d9d53b3cfcbaaa60765dd"><!-- INLINE RELATED POSTS 2/3 //--><style> .u57aa3838fc9d9d53b3cfcbaaa60765dd { padding:0px; margin: 0; padding-top:1em!important; padding-bottom:1em!important; width:100%; display: block; font-weight:bold; background-color:#34495E; border:0!important; border-left:4px solid #2C3E50!important; text-decoration:none; } .u57aa3838fc9d9d53b3cfcbaaa60765dd:active, .u57aa3838fc9d9d53b3cfcbaaa60765dd:hover { opacity: 1; transition: opacity 250ms; webkit-transition: opacity 250ms; text-decoration:none; } .u57aa3838fc9d9d53b3cfcbaaa60765dd { transition: background-color 250ms; webkit-transition: background-color 250ms; opacity: 1; transition: opacity 250ms; webkit-transition: opacity 250ms; } .u57aa3838fc9d9d53b3cfcbaaa60765dd .ctaText { font-weight:bold; color:#eaeaea; text-decoration:none; font-size: 16px; } .u57aa3838fc9d9d53b3cfcbaaa60765dd .postTitle { color:#FFFFFF; text-decoration: underline!important; font-size: 16px; } .u57aa3838fc9d9d53b3cfcbaaa60765dd:hover .postTitle { text-decoration: underline!important; } </style><div style="padding-left:1em; padding-right:1em;"><span class="ctaText">Читайте также:</span>  <span class="postTitle">What is thumbnail cache android</span></div></a></div><h2 id="view-binding-in-fragments">View Binding in Fragments</h2> <p>Let’s take a look at the example from the View Binding Documentation. First we define some layout file:</p> <p>This then generates a “binding” class, ResultProfileBinding . This class contains two fields, name and button , which refer to the views in our layout file. Nice!</p> <p>Using this binding in a Fragment takes one more step — inflating it in onCreateView , and returning the root view. For example:</p> <p>Here we’re storing our binding class in a property so that we can access it later. As it turns out, due to the lifecycle of Fragment Views, this isn’t all we have to do.</p> <h2 id="keeping-track-of-lifecycle">Keeping Track of Lifecycle</h2> <p>When our view is destroyed we need to remember to clear our property, otherwise we’ll end up with a memory leak at best, and crashes at worst! The documentation recommends you do the following in your Fragments:</p> <p>This method works, but you can see how adding this to several different Fragment classes could get repetitive, and start to feel like boilerplate. Luckily for us, we can shorten this considerably in our Kotlin Fragments!</p> <p>We now no longer have to override onDestroyView , and we’ve decreased the number of properties we have to write! But wait.. viewLifecycle() isn’t in AndroidX? How did we do that? By writing our own Property Delegate!</p> <p>Let’s look at the full definition of viewLifecycle() and break it down:</p> <p>Wow, there’s a lot going on there. Let’s break it down.</p> <ul> <li>viewLifecycle() is an extension function of Fragment , meaning we can use Fragment -related properties.</li> <li>viewLifecycle() returns a ReadWriteProperty , an implementation of a property of a Fragment, which is of the generic type T .</li> <li>We construct an anonymous class which implements ReadWriteProperty and LifecycleObserver , allowing us to listen to Lifecycle Events.</li> <li>In the init block, we observe the Fragments viewLifecycleOwner . A Fragment’s View can be created and destroyed many times, so it may have more than one Lifecycle. AndroidX Fragment makes it easy for us, by including viewLifecycleOwnerLiveData , which emits the new Lifecycle Owner when the View is recreated.</li> <li>Finally, when the View’s Lifecycle Owner changes, we observe the new Lifecycle. On the ON_DESTROY event , sent when onDestroyView is about to be called, we null out our backing property.</li> </ul> <p>This gives us the same behaviour as in the View Binding Documentation, but with much less code to cart around in our Fragments! You can find a full, more flexible example in this Gist, which you can drop in to your project and start using!</p> <p>Thanks for reading! If you liked this article make sure to 👏 it, and follow me on Twitter! If you’re a fan of Mastodon check out Mammut — the Open Source client I’m building in my spare time.</p> <p><span class="link" data-link="http://medium.com/default-to-open/handling-lifecycle-with-view-binding-in-fragments-a7f237c56832" >Источник</span></p> <h2 id="polnyy-spisok">Полный список</h2> <p>— динамически работаем с фрагментами</p> <p>Размещать статические фрагменты мы уже умеем. Но, ясно дело, что гораздо интереснее работать с ними динамически. Система позволяет нам добавлять, удалять и заменять фрагменты друг другом. При этом мы можем сохранять все эти манипуляции в BackStack и кнопкой Назад отменять. В общем, все удобно и красиво.</p> <p>Создадим простое приложение с двумя фрагментами, которое будет уметь:</p> <p>— добавлять первый фрагмент <br/>— удалять первый фрагмент <br/>— заменять первый фрагмент вторым фрагментом <br/>— переключать режим сохранения в BackStack операций с фрагментами</p> <p><strong>Project name</strong>: P1051_FragmentDynamic <br/><strong>Build Target</strong>: Android 4.1 <br/><strong>Application name</strong>: FragmentDynamic <br/><strong>Package name</strong>: ru.startandroid.develop.p1051fragmentdynamic <br/><strong>Create Activity</strong>: MainActivity</p> <div style="clear:both; margin-top:0em; margin-bottom:1em;"><a href="https://service-play.ru/oshibka-pri-ustanovke-android-studio-unable-to-elevate/" target="_blank" rel="nofollow" class="u9340eb570a0f6789e8d34f8d444e30e7"><!-- INLINE RELATED POSTS 3/3 //--><style> .u9340eb570a0f6789e8d34f8d444e30e7 { padding:0px; margin: 0; padding-top:1em!important; padding-bottom:1em!important; width:100%; display: block; font-weight:bold; background-color:#34495E; border:0!important; border-left:4px solid #2C3E50!important; text-decoration:none; } .u9340eb570a0f6789e8d34f8d444e30e7:active, .u9340eb570a0f6789e8d34f8d444e30e7:hover { opacity: 1; transition: opacity 250ms; webkit-transition: opacity 250ms; text-decoration:none; } .u9340eb570a0f6789e8d34f8d444e30e7 { transition: background-color 250ms; webkit-transition: background-color 250ms; opacity: 1; transition: opacity 250ms; webkit-transition: opacity 250ms; } .u9340eb570a0f6789e8d34f8d444e30e7 .ctaText { font-weight:bold; color:#eaeaea; text-decoration:none; font-size: 16px; } .u9340eb570a0f6789e8d34f8d444e30e7 .postTitle { color:#FFFFFF; text-decoration: underline!important; font-size: 16px; } .u9340eb570a0f6789e8d34f8d444e30e7:hover .postTitle { text-decoration: underline!important; } </style><div style="padding-left:1em; padding-right:1em;"><span class="ctaText">Читайте также:</span>  <span class="postTitle">Ошибка при установке android studio unable to elevate</span></div></a></div><p>В <b>strings.xml</b> добавим строки:</p> <p>Создаем фрагменты. Как мы помним из прошлого урока, для этого нам нужны будут layout-файлы и классы, наследующие android.app.Fragment</p> <p>Все почти аналогично прошлому уроку, только убрали вызовы кучи lifecycle методов с логами.</p> <p>Рисуем основное Activity.</p> <p>Три кнопки для добавления, удаления и замены фрагментов. Чекбокс для включения использования BackStack. И FrameLayout – это контейнер, в котором будет происходить вся работа с фрагментами. Он должен быть типа ViewGroup. А элементы Fragment, которые мы использовали на прошлом уроке для размещения фрагментов, нам не нужны для динамической работы.</p> <p>В <b>onCreate</b> создаем пару фрагментов и находим чекбокс.</p> <p>В <b>onClick</b> мы получаем менеджер фрагментов с помощью метода getFragmentManager. Этот объект является основным для работы с фрагментами. Далее, чтобы добавить/удалить/заменить фрагмент, нам необходимо использовать транзакции. Они аналогичны транзакциям в БД, где мы открываем транзакцию, производим операции с БД, выполняем commit. Здесь мы открываем транзакцию, производим операции с фрагментами (добавляем, удаляем, заменяем), выполняем commit.</p> <p>Итак, мы получили FragmentManager и открыли транзакцию методом beginTransaction. Далее определяем, какая кнопка была нажата:</p> <p>если <b>Add</b>, то вызываем метод add, в который передаем id контейнера (тот самый FrameLayout из main.xml) и объект фрагмента. В итоге, в контейнер будет помещен Fragment1</p> <p>если <b>Remove</b>, то вызываем метод remove, в который передаем объект фрагмента, который хотим убрать. В итоге, фрагмент удалится с экрана.</p> <p>если <b>Replace</b>, то вызываем метод replace, в который передаем id контейнера и объект фрагмента. В итоге, из контейнера удалится его текущий фрагмент (если он там есть) и добавится фрагмент, указанный нами.</p> <p>Далее проверяем чекбокс. Если он включен, то добавляем транзакцию в BackStack. Для этого используем метод addToBackStack. На вход можно подать строку-тэг. Я передаю null.</p> <p>Ну и вызываем commit, транзакция завершена.</p> <p>Давайте смотреть, что получилось. Все сохраняем, запускаем приложение.</p> <p style="clear: both"><img decoding="async" src="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%200%200'%3E%3C/svg%3E" data-lazy-src="https://startandroid.ru/images/stories/lessons/L0105/384x640xL0105_010.jpg.pagespeed.ic.VRpLcha_CK.jpg"/><noscript><img decoding="async" src="https://startandroid.ru/images/stories/lessons/L0105/384x640xL0105_010.jpg.pagespeed.ic.VRpLcha_CK.jpg"/></noscript></p> <p style="clear: both"><img decoding="async" src="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%200%200'%3E%3C/svg%3E" data-lazy-src="https://startandroid.ru/images/stories/lessons/L0105/384x640xL0105_020.jpg.pagespeed.ic.kKKZppqfEy.jpg"/><noscript><img decoding="async" src="https://startandroid.ru/images/stories/lessons/L0105/384x640xL0105_020.jpg.pagespeed.ic.kKKZppqfEy.jpg"/></noscript></p> <p>появился первый фрагмент.</p> <p style="clear: both"><img decoding="async" src="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%200%200'%3E%3C/svg%3E" data-lazy-src="https://startandroid.ru/images/stories/lessons/L0105/384x640xL0105_030.jpg.pagespeed.ic.t0et7l2q0Z.jpg"/><noscript><img decoding="async" src="https://startandroid.ru/images/stories/lessons/L0105/384x640xL0105_030.jpg.pagespeed.ic.t0et7l2q0Z.jpg"/></noscript></p> <p>Еще раз добавим первый фрагмент – жмем <b>Add</b>. И жмем <b>Replace</b></p> <p style="clear: both"><img decoding="async" src="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%200%200'%3E%3C/svg%3E" data-lazy-src="https://startandroid.ru/images/stories/lessons/L0105/384x640xL0105_040.jpg.pagespeed.ic.47baFR5GyT.jpg"/><noscript><img decoding="async" src="https://startandroid.ru/images/stories/lessons/L0105/384x640xL0105_040.jpg.pagespeed.ic.47baFR5GyT.jpg"/></noscript></p> <p>первый фрагмент заменился вторым.</p> <p>Жмем кнопку <b>Назад</b>. Приложение закрылось, т.к. все эти операции с фрагментами не сохранялись в BackStack. Давайте используем эту возможность.</p> <p>Снова запускаем приложение и включаем чекбокс <b>add to Back Stack</b></p> <p style="clear: both"><img decoding="async" src="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%200%200'%3E%3C/svg%3E" data-lazy-src="https://startandroid.ru/images/stories/lessons/L0105/384x640xL0105_050.jpg.pagespeed.ic.0brJ6Z4OoT.jpg"/><noscript><img decoding="async" src="https://startandroid.ru/images/stories/lessons/L0105/384x640xL0105_050.jpg.pagespeed.ic.0brJ6Z4OoT.jpg"/></noscript></p> <p>Выполняем те же операции: <b>Add</b>, <b>Remove</b>, <b>Add</b>, <b>Replace</b>. У нас добавится первый фрагмент, удалится первый фрагмент, добавится первый фрагмент, заменится вторым. В итоге мы снова видим второй фрагмент. Теперь жмем несколько раз кнопку <b>Назад</b> и наблюдаем, как выполняются операции, обратные тем, что мы делали. Когда транзакции, сохраненные в стеке закончатся, кнопка Назад закроет приложение.</p> <p>Т.е. все достаточно просто и понятно. Скажу еще про пару интересных моментов.</p> <p>Я в этом примере выполнял всего одну операцию в каждой транзакции. Но, разумеется, их может быть больше.</p> <p>Когда мы удаляем фрагмент и не добавляем транзакцию в BackStack, то фрагмент уничтожается. Если же транзакция добавляется в BackStack, то, при удалении, фрагмент не уничтожается (onDestroy не вызывается), а останавливается (onStop).</p> <p>В качестве самостоятельной работы: попробуйте немного изменить приложение и добавлять в один контейнер сразу два фрагмента. Возможно, результат вас удивит )</p> <p>На следующем уроке:</p> <p>— рассмотрим взаимодействие между Activity и ее фрагментами</p> <p>Присоединяйтесь к нам в <b>Telegram</b>:</p> <p>— в канале StartAndroid публикуются ссылки на новые статьи с сайта startandroid.ru и интересные материалы с хабра, medium.com и т.п.</p> <p>— в чатах решаем возникающие вопросы и проблемы по различным темам: Android, Kotlin, RxJava, Dagger, Тестирование </p> <p>— ну и если просто хочется поговорить с коллегами по разработке, то есть чат Флудильня</p> <p>— новый чат Performance для обсуждения проблем производительности и для ваших пожеланий по содержанию курса по этой теме</p> <p><span class="link" data-link="http://startandroid.ru/ru/uroki/vse-uroki-spiskom/175-urok-105-android-3-fragments-dinamicheskaja-rabota.html" >Источник</span></p> </div><!-- .entry-content --> </article> <div class="rating-box"> <div class="rating-box__header">Оцените статью</div> <div class="wp-star-rating js-star-rating star-rating--score-0" data-post-id="210402" data-rating-count="0" data-rating-sum="0" data-rating-value="0"><span class="star-rating-item js-star-rating-item" data-score="1"><svg aria-hidden="true" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" class="i-ico"><path fill="currentColor" d="M259.3 17.8L194 150.2 47.9 171.5c-26.2 3.8-36.7 36.1-17.7 54.6l105.7 103-25 145.5c-4.5 26.3 23.2 46 46.4 33.7L288 439.6l130.7 68.7c23.2 12.2 50.9-7.4 46.4-33.7l-25-145.5 105.7-103c19-18.5 8.5-50.8-17.7-54.6L382 150.2 316.7 17.8c-11.7-23.6-45.6-23.9-57.4 0z" class="ico-star"></path></svg></span><span class="star-rating-item js-star-rating-item" data-score="2"><svg aria-hidden="true" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" class="i-ico"><path fill="currentColor" d="M259.3 17.8L194 150.2 47.9 171.5c-26.2 3.8-36.7 36.1-17.7 54.6l105.7 103-25 145.5c-4.5 26.3 23.2 46 46.4 33.7L288 439.6l130.7 68.7c23.2 12.2 50.9-7.4 46.4-33.7l-25-145.5 105.7-103c19-18.5 8.5-50.8-17.7-54.6L382 150.2 316.7 17.8c-11.7-23.6-45.6-23.9-57.4 0z" class="ico-star"></path></svg></span><span class="star-rating-item js-star-rating-item" data-score="3"><svg aria-hidden="true" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" class="i-ico"><path fill="currentColor" d="M259.3 17.8L194 150.2 47.9 171.5c-26.2 3.8-36.7 36.1-17.7 54.6l105.7 103-25 145.5c-4.5 26.3 23.2 46 46.4 33.7L288 439.6l130.7 68.7c23.2 12.2 50.9-7.4 46.4-33.7l-25-145.5 105.7-103c19-18.5 8.5-50.8-17.7-54.6L382 150.2 316.7 17.8c-11.7-23.6-45.6-23.9-57.4 0z" class="ico-star"></path></svg></span><span class="star-rating-item js-star-rating-item" data-score="4"><svg aria-hidden="true" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" class="i-ico"><path fill="currentColor" d="M259.3 17.8L194 150.2 47.9 171.5c-26.2 3.8-36.7 36.1-17.7 54.6l105.7 103-25 145.5c-4.5 26.3 23.2 46 46.4 33.7L288 439.6l130.7 68.7c23.2 12.2 50.9-7.4 46.4-33.7l-25-145.5 105.7-103c19-18.5 8.5-50.8-17.7-54.6L382 150.2 316.7 17.8c-11.7-23.6-45.6-23.9-57.4 0z" class="ico-star"></path></svg></span><span class="star-rating-item js-star-rating-item" data-score="5"><svg aria-hidden="true" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" class="i-ico"><path fill="currentColor" d="M259.3 17.8L194 150.2 47.9 171.5c-26.2 3.8-36.7 36.1-17.7 54.6l105.7 103-25 145.5c-4.5 26.3 23.2 46 46.4 33.7L288 439.6l130.7 68.7c23.2 12.2 50.9-7.4 46.4-33.7l-25-145.5 105.7-103c19-18.5 8.5-50.8-17.7-54.6L382 150.2 316.7 17.8c-11.7-23.6-45.6-23.9-57.4 0z" class="ico-star"></path></svg></span></div> </div> <div class="entry-social"> <div class="social-buttons"><span class="social-button social-button--vkontakte" data-social="vkontakte" data-image=""></span><span class="social-button social-button--facebook" data-social="facebook"></span><span class="social-button social-button--telegram" data-social="telegram"></span><span class="social-button social-button--odnoklassniki" data-social="odnoklassniki"></span><span class="social-button social-button--twitter" data-social="twitter"></span><span class="social-button social-button--sms" data-social="sms"></span><span class="social-button social-button--whatsapp" data-social="whatsapp"></span></div> </div> <meta itemprop="author" content="admin"> <meta itemscope itemprop="mainEntityOfPage" itemType="https://schema.org/WebPage" itemid="https://service-play.ru/210402-2/" content=""> <meta itemprop="dateModified" content="2022-02-15"> <meta itemprop="datePublished" content="2022-02-14T23:38:20+02:00"> <div itemprop="publisher" itemscope itemtype="https://schema.org/Organization" style="display: none;"><meta itemprop="name" content="Ваши гэджеты"><meta itemprop="telephone" content="Ваши гэджеты"><meta itemprop="address" content="https://service-play.ru"></div> </main><!-- #main --> </div><!-- #primary --> <aside id="secondary" class="widget-area" itemscope itemtype="http://schema.org/WPSideBar"> <div class="sticky-sidebar js-sticky-sidebar"> <div id="search-2" class="widget widget_search"> <form role="search" method="get" class="search-form" action="https://service-play.ru/"> <label> <span class="screen-reader-text"><!--noindex-->Search for:<!--/noindex--></span> <input type="search" class="search-field" placeholder="Поиск…" value="" name="s"> </label> <button type="submit" class="search-submit"></button> </form></div> <div id="recent-posts-2" class="widget widget_recent_entries"> <div class="widget-header">Свежие записи</div> <ul> <li> <a href="https://service-play.ru/10-samyh-populyarnyh-gadzhetov-apple-v-istorii/">10 самых популярных гаджетов Apple в истории</a> </li> <li> <a href="https://service-play.ru/puteshestvie-v-buduschee-kak-gadzhety-apple-menyayut-nashu-zhizn/">Путешествие в будущее: как гаджеты Apple меняют нашу жизнь</a> </li> <li> <a href="https://service-play.ru/5-glavnyh-prichin-pereyti-na-gadzhety-apple-obzor-i-sravnenie/">5 главных причин перейти на гаджеты Apple: обзор и сравнение</a> </li> <li> <a href="https://service-play.ru/sekrety-kastomizatsii-gadzhetov-apple-sovety-i-hitrosti/">Секреты кастомизации гаджетов Apple: советы и хитрости</a> </li> <li> <a href="https://service-play.ru/top-10-innovatsionnyh-gadzhetov-apple-o-kotoryh-vy-ne-znali/">Топ-10 инновационных гаджетов Apple, о которых вы не знали</a> </li> </ul> </div><div id="block-2" class="widget widget_block"><div class="flatPM_sidebar" data-top="70"> <div id="Q_sidebar"></div> </div></div> </div> </aside><!-- #secondary --> <div id="related-posts" class="related-posts fixed"><div class="related-posts__header">Вам также может понравиться</div><div class="post-cards post-cards--vertical"> <div class="post-card post-card--related"> <div class="post-card__thumbnail"><a href="https://service-play.ru/kak-deaktivirovat-rezhim-naushnikov-na-smartfone-s-android/"><img width="335" height="220" src="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20335%20220'%3E%3C/svg%3E" class="attachment-reboot_small size-reboot_small wp-post-image" alt="" decoding="async" data-lazy-src="https://service-play.ru/wp-content/uploads/2023/06/41-1-335x220.png"/><noscript><img width="335" height="220" src="https://service-play.ru/wp-content/uploads/2023/06/41-1-335x220.png" class="attachment-reboot_small size-reboot_small wp-post-image" alt="" decoding="async" loading="lazy"/></noscript></a></div><div class="post-card__title"><a href="https://service-play.ru/kak-deaktivirovat-rezhim-naushnikov-na-smartfone-s-android/">Как деактивировать режим наушников на смартфоне с Android?</a></div><div class="post-card__description">Когда к мобильному устройству присоединены наушники</div> </div> <div class="post-card post-card--related"> <div class="post-card__thumbnail"><a href="https://service-play.ru/obzor-igry-dzhelli-dzhu-dlya-android/"><img width="335" height="220" src="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20335%20220'%3E%3C/svg%3E" class="attachment-reboot_small size-reboot_small wp-post-image" alt="" decoding="async" data-lazy-src="https://service-play.ru/wp-content/uploads/2023/06/142-1-335x220.png"/><noscript><img width="335" height="220" src="https://service-play.ru/wp-content/uploads/2023/06/142-1-335x220.png" class="attachment-reboot_small size-reboot_small wp-post-image" alt="" decoding="async" loading="lazy"/></noscript></a></div><div class="post-card__title"><a href="https://service-play.ru/obzor-igry-dzhelli-dzhu-dlya-android/">Обзор игры Джелли-Джу для Android</a></div><div class="post-card__description">В последние годы популярность мобильных игр резко возросла</div> </div> <div class="post-card post-card--related"> <div class="post-card__thumbnail"><a href="https://service-play.ru/luchshie-shahmatnye-prilozheniya-dlya-ios-i-android/"><img width="335" height="220" src="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20335%20220'%3E%3C/svg%3E" class="attachment-reboot_small size-reboot_small wp-post-image" alt="" decoding="async" data-lazy-src="https://service-play.ru/wp-content/uploads/2023/06/31-1-335x220.png"/><noscript><img width="335" height="220" src="https://service-play.ru/wp-content/uploads/2023/06/31-1-335x220.png" class="attachment-reboot_small size-reboot_small wp-post-image" alt="" decoding="async" loading="lazy"/></noscript></a></div><div class="post-card__title"><a href="https://service-play.ru/luchshie-shahmatnye-prilozheniya-dlya-ios-i-android/">Лучшие шахматные приложения для iOS и Android</a></div><div class="post-card__description">Нынешний читерский скандал в шахматном мире сейчас</div> </div> <div class="post-card post-card--related"> <div class="post-card__thumbnail"><a href="https://service-play.ru/chto-hotyat-uvidet-polzovateli-ot-android-5-0-key-lime-pie/"><img width="335" height="220" src="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20335%20220'%3E%3C/svg%3E" class="attachment-reboot_small size-reboot_small wp-post-image" alt="" decoding="async" data-lazy-src="https://service-play.ru/wp-content/uploads/2023/06/131-1-335x220.png"/><noscript><img width="335" height="220" src="https://service-play.ru/wp-content/uploads/2023/06/131-1-335x220.png" class="attachment-reboot_small size-reboot_small wp-post-image" alt="" decoding="async" loading="lazy"/></noscript></a></div><div class="post-card__title"><a href="https://service-play.ru/chto-hotyat-uvidet-polzovateli-ot-android-5-0-key-lime-pie/">Что хотят увидеть пользователи от Android 5.0 Key Lime Pie</a></div><div class="post-card__description">ОС Google Android развивается, и по всему видимому</div> </div> </div></div> </div><!--.site-content-inner--> </div><!--.site-content--> <div class="site-footer-container "> <div class="footer-navigation fixed" itemscope itemtype="http://schema.org/SiteNavigationElement"> <div class="main-navigation-inner full"> <div class="menu-tehnicheskoe-menyu-container"><ul id="footer_menu" class="menu"><li id="menu-item-8" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-8"><a href="https://service-play.ru/pravoobladatelyam/">Правообладателям</a></li> <li id="menu-item-9" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-9"><a href="https://service-play.ru/politika-konfidentsialnosti/">Политика конфиденциальности</a></li> <li id="menu-item-480407" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-480407"><a href="https://service-play.ru/kontakty/">Контакты</a></li> </ul></div> </div> </div><!--footer-navigation--> <footer id="colophon" class="site-footer site-footer--style-gray full"> <div class="site-footer-inner fixed"> <div class="footer-bottom"> <div class="footer-info"> © 2025 Ваши гэджеты </div> <div class="footer-counters"><!-- Yandex.Metrika counter --> <script type="text/javascript" > (function(m,e,t,r,i,k,a){m[i]=m[i]||function(){(m[i].a=m[i].a||[]).push(arguments)}; m[i].l=1*new Date(); for (var j = 0; j < document.scripts.length; j++) {if (document.scripts[j].src === r) { return; }} k=e.createElement(t),a=e.getElementsByTagName(t)[0],k.async=1,k.src=r,a.parentNode.insertBefore(k,a)}) (window, document, "script", "https://mc.yandex.ru/metrika/tag.js", "ym"); ym(95570298, "init", { clickmap:true, trackLinks:true, accurateTrackBounce:true, webvisor:true }); </script> <noscript><div><img src="https://mc.yandex.ru/watch/95570298" style="position:absolute; left:-9999px;" alt=""/></div></noscript> <!-- /Yandex.Metrika counter --></div></div> </div> </footer><!--.site-footer--> </div> <button type="button" class="scrolltop js-scrolltop"></button> </div><!-- #page --> <script>var pseudo_links = document.querySelectorAll(".pseudo-clearfy-link");for (var i=0;i<pseudo_links.length;i++ ) { pseudo_links[i].addEventListener("click", function(e){ window.open( e.target.getAttribute("data-uri") ); }); }</script><script type="text/javascript" id="reboot-scripts-js-extra"> /* <![CDATA[ */ var settings_array = {"rating_text_average":"\u0441\u0440\u0435\u0434\u043d\u0435\u0435","rating_text_from":"\u0438\u0437","lightbox_display":"1","sidebar_fixed":"1"}; var wps_ajax = {"url":"https:\/\/service-play.ru\/wp-admin\/admin-ajax.php","nonce":"12d6e1114e"}; /* ]]> */ </script> <script type="text/javascript" src="https://service-play.ru/wp-content/themes/reboot/assets/js/scripts.min.js" id="reboot-scripts-js"></script> <script type="text/javascript"> /*<![CDATA[*/ jQuery(document).ready(function($){ $('.link').replaceWith(function(){ var id = ( null != $(this).attr('id') ) ? ' id="' + $(this).attr('id') + '"' : '', target = ( null != $(this).attr('data-target') ) ? ' target="' + $(this).attr('data-target') + '"' : ' target="_blank"', title = ( null != $(this).attr('title') ) ? ' title="' + $(this).attr('title') + '"' : '', style = ( null != $(this).attr('style') ) ? ' style="' + $(this).attr('style') + '"' : '', rel = ( null != $(this).attr('data-rel') ) ? ' rel="' + $(this).attr('data-rel') + '"' : '', cl = ( null != $(this).attr('class') ) ? $(this).attr('class').replace('link','').trim() : ''; cl = ( '' != cl ) ? ' class="' + cl + '"' : ''; return '<a href="' + $(this).attr('data-link') + '" ' + title + id + cl + target + style + rel + ' >' + $(this).html() + '</a>'; }); }); /*]]>*/ </script> <script>window.lazyLoadOptions = [{ elements_selector: "img[data-lazy-src],.rocket-lazyload,iframe[data-lazy-src]", data_src: "lazy-src", data_srcset: "lazy-srcset", data_sizes: "lazy-sizes", class_loading: "lazyloading", class_loaded: "lazyloaded", threshold: 300, callback_loaded: function(element) { if ( element.tagName === "IFRAME" && element.dataset.rocketLazyload == "fitvidscompatible" ) { if (element.classList.contains("lazyloaded") ) { if (typeof window.jQuery != "undefined") { if (jQuery.fn.fitVids) { jQuery(element).parent().fitVids(); } } } } }},{ elements_selector: ".rocket-lazyload", data_src: "lazy-src", data_srcset: "lazy-srcset", data_sizes: "lazy-sizes", class_loading: "lazyloading", class_loaded: "lazyloaded", threshold: 300, }]; window.addEventListener('LazyLoad::Initialized', function (e) { var lazyLoadInstance = e.detail.instance; if (window.MutationObserver) { var observer = new MutationObserver(function(mutations) { var image_count = 0; var iframe_count = 0; var rocketlazy_count = 0; mutations.forEach(function(mutation) { for (var i = 0; i < mutation.addedNodes.length; i++) { if (typeof mutation.addedNodes[i].getElementsByTagName !== 'function') { continue; } if (typeof mutation.addedNodes[i].getElementsByClassName !== 'function') { continue; } images = mutation.addedNodes[i].getElementsByTagName('img'); is_image = mutation.addedNodes[i].tagName == "IMG"; iframes = mutation.addedNodes[i].getElementsByTagName('iframe'); is_iframe = mutation.addedNodes[i].tagName == "IFRAME"; rocket_lazy = mutation.addedNodes[i].getElementsByClassName('rocket-lazyload'); image_count += images.length; iframe_count += iframes.length; rocketlazy_count += rocket_lazy.length; if(is_image){ image_count += 1; } if(is_iframe){ iframe_count += 1; } } } ); if(image_count > 0 || iframe_count > 0 || rocketlazy_count > 0){ lazyLoadInstance.update(); } } ); var b = document.getElementsByTagName("body")[0]; var config = { childList: true, subtree: true }; observer.observe(b, config); } }, false);</script><script data-no-minify="1" async src="https://service-play.ru/wp-content/plugins/rocket-lazy-load/assets/js/16.1/lazyload.min.js"></script><script>function lazyLoadThumb(e,alt){var t='<img loading="lazy" src="https://i.ytimg.com/vi/ID/hqdefault.jpg" alt="" width="480" height="360">',a='<button class="play" aria-label="play Youtube video"></button>';t=t.replace('alt=""','alt="'+alt+'"');return t.replace("ID",e)+a}function lazyLoadYoutubeIframe(){var e=document.createElement("iframe"),t="ID?autoplay=1";t+=0===this.parentNode.dataset.query.length?'':'&'+this.parentNode.dataset.query;e.setAttribute("src",t.replace("ID",this.parentNode.dataset.src)),e.setAttribute("frameborder","0"),e.setAttribute("allowfullscreen","1"),e.setAttribute("allow", "accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture"),this.parentNode.parentNode.replaceChild(e,this.parentNode)}document.addEventListener("DOMContentLoaded",function(){var e,t,p,a=document.getElementsByClassName("rll-youtube-player");for(t=0;t<a.length;t++)e=document.createElement("div"),e.setAttribute("data-id",a[t].dataset.id),e.setAttribute("data-query", a[t].dataset.query),e.setAttribute("data-src", a[t].dataset.src),e.innerHTML=lazyLoadThumb(a[t].dataset.id,a[t].dataset.alt),a[t].appendChild(e),p=e.querySelector('.play'),p.onclick=lazyLoadYoutubeIframe});</script> </body> </html>