tag:blogger.com,1999:blog-56776059114841641852024-03-19T06:17:15.813+02:00Android programmers blogSimply about difficultdajverhttp://www.blogger.com/profile/09427222798699404442noreply@blogger.comBlogger109125tag:blogger.com,1999:blog-5677605911484164185.post-42061984530217334812019-08-06T15:19:00.000+03:002019-08-06T15:19:00.139+03:00Проектируем приложение с MVP<div dir="ltr" style="text-align: left;" trbidi="on">
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Поговорить об архитектуре всегда интересно, в особенности когда ты ее используешь повсеместно во всех своих приложениях. Сейчас очень популярно и модно везде использовать </span><a href="http://dajver.blogspot.com/2019/07/mvvm.html" style="background-color: white; color: #992298; font-size: 16px;">MVVM</a><span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;"> архитектуру которую я описывал тут буквально недавно. </span><br />
<div style="text-align: center;">
<img alt="image" height="310" src="https://android-tools.ru/wp-content/uploads/2017/08/MVP-Android.png" style="background-color: white; border-style: none; color: #222222; font-size: 16px; height: auto; margin: 0px; max-width: 100%; vertical-align: middle;" width="400" /></div>
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Сегодня я хочу поговорить про такой паттерн который используется в большинстве современных приложений, который называется MVP, на его замену пришел уже названный ранее MVVM который является более простым и понятным паттерном, но MVP в современной разработке используется везде где можно и нельзя, и так же она имеет применение в мобильной разработке, которую я так сильно люблю.</span><br />
<a name='more'></a><br style="background-color: white; color: #222222; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Если кратко что такое MVP то вот вам развертка:</span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">— Model — уровень данных. Все называют его как «уровень бизнес логики», но для меня он очень абстрактный и в большинстве случаев его можно интерпретировать как угодно, но только не так что бы было понятно. Поэтому в своих приложениях я называю его Repository и он работает с базой данных или сервером или какой-то внутреней структурой данных.</span><br />
<br style="background-color: white; color: #222222; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">— View — уровень отображения. Это любая Activity, Fragment или Custom View котоые описывают работу с объектами отображения (TextView, RecyclerView и т.д.). Напомню, что изначально все Android приложения подчинены структуре MVP, где Controller это Activity или Fragment.</span><br />
<br style="background-color: white; color: #222222; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">— Presenter — прослойка между View и Model. View передаёт ему происходящие события, презентер обрабатывает их, при необходимости обращается к Model и возращает View данные на отрисовку.</span><br />
<br style="background-color: white; color: #222222; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Что же мы из этого всего вынесли полезного?</span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">— View — знает о Presenter. Отображает все что возвращает презентер;</span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">— Presenter — знает о View и Model (Repository). Берет данные из модели и отдает во вью;</span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">— Model (Repository) — сама по себе. Она у нас получает данные и отдает тому кто попросит;</span><br />
<br style="background-color: white; color: #222222; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Теперь же перейдем к практической части. У нас нужно провести небольшую подготовку прежде чем реализовывать сам паттерн в нашем проекте. По этому давайте подключим библиотеки, создадим модели и подключим работу с сервером.</span><br />
<br style="background-color: white; color: #222222; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">app/build.gradle</span><br />
<pre style="background-color: white; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow: auto hidden; padding: 0px; word-break: break-all;"><code class="java hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); color: #383a42; display: block; font-family: menlo, monaco, "courier new", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;">dependencies {
implementation <span class="hljs-string" style="color: #50a14f;">'androidx.appcompat:appcompat:1.0.2'</span>
implementation <span class="hljs-string" style="color: #50a14f;">'androidx.recyclerview:recyclerview:1.0.0'</span>
implementation <span class="hljs-string" style="color: #50a14f;">'com.squareup.retrofit2:retrofit:2.6.0'</span>
implementation <span class="hljs-string" style="color: #50a14f;">'com.squareup.retrofit2:converter-gson:2.4.0'</span>
implementation <span class="hljs-string" style="color: #50a14f;">'com.squareup.retrofit2:converter-scalars:2.0.1'</span>
}</code></pre>
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Подключаем Retrofit, RecyclerView и appcompat для работы с сервером, списками и остальными важными частями android sdk.</span><br />
<br style="background-color: white; color: #222222; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Дальше по стандарту описываем работу с сервером как это уже было в сотне статей которые я тут описывал, все будет аналогично десятку примеров которые тут были.</span><br />
<br style="background-color: white; color: #222222; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">PostModel.kt</span><br />
<pre style="background-color: white; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow: auto hidden; padding: 0px; word-break: break-all;"><code class="kotlin hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); color: #383a42; display: block; font-family: menlo, monaco, "courier new", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="color: #a626a4;">import</span> com.google.gson.annotations.Expose
<span class="hljs-keyword" style="color: #a626a4;">import</span> com.google.gson.annotations.SerializedName
<span class="hljs-class"><span class="hljs-keyword" style="color: #a626a4;">class</span> <span class="hljs-title" style="color: #c18401;">PostModel</span> </span>{
<span class="hljs-meta" style="color: #4078f2;">@SerializedName(<span class="hljs-meta-string" style="color: #50a14f;">"userId"</span>)</span>
<span class="hljs-meta" style="color: #4078f2;">@Expose</span>
<span class="hljs-keyword" style="color: #a626a4;">var</span> userId: <span class="hljs-built_in" style="color: #c18401;">Int</span>? = <span class="hljs-literal" style="color: #0184bb;">null</span>
<span class="hljs-meta" style="color: #4078f2;">@SerializedName(<span class="hljs-meta-string" style="color: #50a14f;">"id"</span>)</span>
<span class="hljs-meta" style="color: #4078f2;">@Expose</span>
<span class="hljs-keyword" style="color: #a626a4;">var</span> id: <span class="hljs-built_in" style="color: #c18401;">Int</span>? = <span class="hljs-literal" style="color: #0184bb;">null</span>
<span class="hljs-meta" style="color: #4078f2;">@SerializedName(<span class="hljs-meta-string" style="color: #50a14f;">"title"</span>)</span>
<span class="hljs-meta" style="color: #4078f2;">@Expose</span>
<span class="hljs-keyword" style="color: #a626a4;">var</span> title: String? = <span class="hljs-literal" style="color: #0184bb;">null</span>
<span class="hljs-meta" style="color: #4078f2;">@SerializedName(<span class="hljs-meta-string" style="color: #50a14f;">"body"</span>)</span>
<span class="hljs-meta" style="color: #4078f2;">@Expose</span>
<span class="hljs-keyword" style="color: #a626a4;">var</span> body: String? = <span class="hljs-literal" style="color: #0184bb;">null</span>
}</code></pre>
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Подготавливаем модель для обработки данных с сервера, по традиции получать будем тайтл и описание, и будем потом его отображать в списке.</span><br />
<br style="background-color: white; color: #222222; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">API.kt</span><br />
<pre style="background-color: white; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow: auto hidden; padding: 0px; word-break: break-all;"><code class="kotlin hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); color: #383a42; display: block; font-family: menlo, monaco, "courier new", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="color: #a626a4;">import</span> dajver.com.mvpexample.api.model.PostModel
<span class="hljs-keyword" style="color: #a626a4;">import</span> retrofit2.Call
<span class="hljs-keyword" style="color: #a626a4;">import</span> retrofit2.http.GET
<span class="hljs-class"><span class="hljs-keyword" style="color: #a626a4;">interface</span> <span class="hljs-title" style="color: #c18401;">API</span> </span>{
<span class="hljs-meta" style="color: #4078f2;">@get:GET</span>(<span class="hljs-string" style="color: #50a14f;">"posts"</span>)
<span class="hljs-keyword" style="color: #a626a4;">val</span> posts: Call<List<PostModel>>
}</code></pre>
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Далее описываем запрос к серверу, в нашем случае мы будем получать список постов, в нашу модельку которую создали выше.</span><br />
<br style="background-color: white; color: #222222; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">RestClient.kt</span><br />
<pre style="background-color: white; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow: auto hidden; padding: 0px; word-break: break-all;"><code class="kotlin hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); color: #383a42; display: block; font-family: menlo, monaco, "courier new", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="color: #a626a4;">import</span> retrofit2.Retrofit
<span class="hljs-keyword" style="color: #a626a4;">import</span> retrofit2.converter.gson.GsonConverterFactory
<span class="hljs-keyword" style="color: #a626a4;">import</span> retrofit2.converter.scalars.ScalarsConverterFactory
<span class="hljs-class"><span class="hljs-keyword" style="color: #a626a4;">class</span> <span class="hljs-title" style="color: #c18401;">RestClient</span> </span>{
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-keyword" style="color: #a626a4;">val</span> service: API
<span class="hljs-keyword" style="color: #a626a4;">init</span> {
<span class="hljs-keyword" style="color: #a626a4;">val</span> retrofit = Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(ScalarsConverterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.build()
service = retrofit.create(API::<span class="hljs-class"><span class="hljs-keyword" style="color: #a626a4;">class</span>.<span class="hljs-title" style="color: #c18401;">java</span>)</span>
}
<span class="hljs-keyword" style="color: #a626a4;">companion</span> <span class="hljs-keyword" style="color: #a626a4;">object</span> {
<span class="hljs-keyword" style="color: #a626a4;">const</span> <span class="hljs-keyword" style="color: #a626a4;">val</span> BASE_URL = <span class="hljs-string" style="color: #50a14f;">"https://jsonplaceholder.typicode.com/"</span>
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-keyword" style="color: #a626a4;">val</span> instance = RestClient()
<span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">instance</span><span class="hljs-params">()</span></span>: API {
<span class="hljs-keyword" style="color: #a626a4;">return</span> instance.service
}
}
}</code></pre>
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Дальше создаем класс который абстрагирует работу с сервером, используя интерфейс API, в котором мы описали сам запрос.</span><br />
<br style="background-color: white; color: #222222; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Далее, после того как мы описали работу с сервером, нам нужно описать интерфейсы которые будут иметь методы с которыми мы в дальнейшем будем взаимодействовать между объектами самого MVP.</span><br />
<br style="background-color: white; color: #222222; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">PostRepository.kt</span><br />
<pre style="background-color: white; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow: auto hidden; padding: 0px; word-break: break-all;"><code class="kotlin hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); color: #383a42; display: block; font-family: menlo, monaco, "courier new", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-class"><span class="hljs-keyword" style="color: #a626a4;">interface</span> <span class="hljs-title" style="color: #c18401;">PostsRepository</span> </span>{
<span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">getPosts</span><span class="hljs-params">()</span></span>
}</code></pre>
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Даный интерфейс говорит о том что в нашем имплементации данного интерфейса будет содержать один метод, который будет получать посты с сервера. </span><br />
<br style="background-color: white; color: #222222; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">PostsRepositoryImpl.kt</span><br />
<pre style="background-color: white; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow: auto hidden; padding: 0px; word-break: break-all;"><code class="kotlin hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); color: #383a42; display: block; font-family: menlo, monaco, "courier new", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="color: #a626a4;">import</span> dajver.com.mvpexample.api.RestClient
<span class="hljs-keyword" style="color: #a626a4;">import</span> dajver.com.mvpexample.api.model.PostModel
<span class="hljs-keyword" style="color: #a626a4;">import</span> retrofit2.Call
<span class="hljs-keyword" style="color: #a626a4;">import</span> retrofit2.Callback
<span class="hljs-keyword" style="color: #a626a4;">import</span> retrofit2.Response
<span class="hljs-class"><span class="hljs-keyword" style="color: #a626a4;">class</span> <span class="hljs-title" style="color: #c18401;">PostsRepositoryImpl</span></span>(<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-keyword" style="color: #a626a4;">val</span> onPostsFetchedListener: OnPostsFetchedListener) : PostsRepository {
<span class="hljs-keyword" style="color: #a626a4;">override</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">getPosts</span><span class="hljs-params">()</span></span> {
RestClient.instance().posts.enqueue(<span class="hljs-keyword" style="color: #a626a4;">object</span> : Callback<List<PostModel>> {
<span class="hljs-keyword" style="color: #a626a4;">override</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">onResponse</span><span class="hljs-params">(call: <span class="hljs-type" style="color: #986801;">Call</span><<span class="hljs-type" style="color: #986801;">List</span><<span class="hljs-type" style="color: #986801;">PostModel</span>>>, response: <span class="hljs-type" style="color: #986801;">Response</span><<span class="hljs-type" style="color: #986801;">List</span><<span class="hljs-type" style="color: #986801;">PostModel</span>>>)</span></span> {
<span class="hljs-keyword" style="color: #a626a4;">if</span>(response.code() < <span class="hljs-number" style="color: #986801;">400</span>) {
onPostsFetchedListener.showPosts(response.body()!! <span class="hljs-keyword" style="color: #a626a4;">as</span> ArrayList<PostModel>)
}
}
<span class="hljs-keyword" style="color: #a626a4;">override</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">onFailure</span><span class="hljs-params">(call: <span class="hljs-type" style="color: #986801;">Call</span><<span class="hljs-type" style="color: #986801;">List</span><<span class="hljs-type" style="color: #986801;">PostModel</span>>>, t: <span class="hljs-type" style="color: #986801;">Throwable</span>)</span></span> {
t.printStackTrace()
}
})
}
<span class="hljs-class"><span class="hljs-keyword" style="color: #a626a4;">interface</span> <span class="hljs-title" style="color: #c18401;">OnPostsFetchedListener</span> </span>{
<span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">showPosts</span><span class="hljs-params">(posts: <span class="hljs-type" style="color: #986801;">ArrayList</span><<span class="hljs-type" style="color: #986801;">PostModel</span>>)</span></span>
}
}</code></pre>
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Здесь мы создали класс и заимплементили наш интерфейс, после этого создали метод который описывает работу с сервером, сделали вызов RestClient'a и в onResponse отправляем колбек на подписавшегося на тот коллбек класса, в нашем случае это будет Presenter. Так же в конструкторе мы говорим о том что каждый класс который будет создавать инстанс данного репозитория должен подписаться на коллбек для получения списка постов.</span><br />
<br style="background-color: white; color: #222222; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">PostPresenter.kt</span><br />
<pre style="background-color: white; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow: auto hidden; padding: 0px; word-break: break-all;"><code class="kotlin hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); color: #383a42; display: block; font-family: menlo, monaco, "courier new", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-class"><span class="hljs-keyword" style="color: #a626a4;">interface</span> <span class="hljs-title" style="color: #c18401;">PostsPresenter</span> </span>{
<span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">onItemWasClicked</span><span class="hljs-params">(position: <span class="hljs-type" style="color: #986801;">Int</span>)</span></span>
}</code></pre>
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">В данном интерфейсе мы будем обратаывать клик по айтему в списке. И так же в конструкторе будем подгружать данные с сервера. </span><br />
<br style="background-color: white; color: #222222; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">PostPresenterImpl.kt</span><br />
<pre style="background-color: white; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow: auto hidden; padding: 0px; word-break: break-all;"><code class="kotlin hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); color: #383a42; display: block; font-family: menlo, monaco, "courier new", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="color: #a626a4;">import</span> dajver.com.mvpexample.api.model.PostModel
<span class="hljs-keyword" style="color: #a626a4;">import</span> dajver.com.mvpexample.mvc.repository.PostsRepository
<span class="hljs-keyword" style="color: #a626a4;">import</span> dajver.com.mvpexample.mvc.repository.PostsRepositoryImpl
<span class="hljs-keyword" style="color: #a626a4;">import</span> dajver.com.mvpexample.mvc.PostsView
<span class="hljs-class"><span class="hljs-keyword" style="color: #a626a4;">class</span> <span class="hljs-title" style="color: #c18401;">PostsPresenterImpl</span></span>(<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-keyword" style="color: #a626a4;">val</span> mView: PostsView) : PostsPresenter, PostsRepositoryImpl.OnPostsFetchedListener {
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-keyword" style="color: #a626a4;">val</span> mRepository: PostsRepository
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-keyword" style="color: #a626a4;">var</span> postModelList: ArrayList<PostModel>? = <span class="hljs-literal" style="color: #0184bb;">null</span>
<span class="hljs-keyword" style="color: #a626a4;">init</span> {
mRepository = PostsRepositoryImpl(<span class="hljs-keyword" style="color: #a626a4;">this</span>)
mRepository.getPosts()
}
<span class="hljs-keyword" style="color: #a626a4;">override</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">showPosts</span><span class="hljs-params">(posts: <span class="hljs-type" style="color: #986801;">ArrayList</span><<span class="hljs-type" style="color: #986801;">PostModel</span>>)</span></span> {
postModelList = posts
mView.showPosts(postModelList!!)
}
<span class="hljs-keyword" style="color: #a626a4;">override</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">onItemWasClicked</span><span class="hljs-params">(position: <span class="hljs-type" style="color: #986801;">Int</span>)</span></span> {
mView.onPostClick(postModelList!![position])
}
}</code></pre>
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">В конструкторе мы передаем View, потому что наш активити должен содержать имлемент к View, а презентер будет обращаться к этим элементам View и работать с ними. Так же в init методе мы создаем объект Repository и сразу вызываем метод getPosts что бы получить данные с сервера по запуску приложения. И так же на коллбек showPosts, отображаем посты во View (активити) и по клику onItemWasClicked отправляем клик в View (активити).</span><br />
<br style="background-color: white; color: #222222; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">PostsView.kt</span><br />
<pre style="background-color: white; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow: auto hidden; padding: 0px; word-break: break-all;"><code class="kotlin hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); color: #383a42; display: block; font-family: menlo, monaco, "courier new", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="color: #a626a4;">import</span> dajver.com.mvpexample.api.model.PostModel
<span class="hljs-class"><span class="hljs-keyword" style="color: #a626a4;">interface</span> <span class="hljs-title" style="color: #c18401;">PostsView</span> </span>{
<span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">onPostClick</span><span class="hljs-params">(text: <span class="hljs-type" style="color: #986801;">PostModel</span>)</span></span>
<span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">showPosts</span><span class="hljs-params">(posts: <span class="hljs-type" style="color: #986801;">List</span><<span class="hljs-type" style="color: #986801;">PostModel</span>>)</span></span>
}</code></pre>
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Вот так будут выглядеть три наших интерфейса которые будут взаимодействовать между друг другом. PostsRepository будет получать инфу из сервера и будет передавать ее в PostsPresenter, а PostsView будет отображать с помощью Presenter'a все это безобразие.</span><br />
<br style="background-color: white; color: #222222; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Так же нам еще осталось создать адаптер с холдером для отображения списка, опускать уже эту информацию не буду, и нарисую тут как будет выглядеть эти два класса.</span><br />
<br style="background-color: white; color: #222222; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">PostViewHolder.kt</span><br />
<pre style="background-color: white; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow: auto hidden; padding: 0px; word-break: break-all;"><code class="kotlin hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); color: #383a42; display: block; font-family: menlo, monaco, "courier new", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="color: #a626a4;">import</span> android.view.View
<span class="hljs-keyword" style="color: #a626a4;">import</span> androidx.recyclerview.widget.RecyclerView
<span class="hljs-keyword" style="color: #a626a4;">import</span> dajver.com.mvpexample.adapter.PostRecyclerAdapter
<span class="hljs-keyword" style="color: #a626a4;">import</span> dajver.com.mvpexample.api.model.PostModel
<span class="hljs-keyword" style="color: #a626a4;">import</span> kotlinx.android.synthetic.main.item_posts.view.*
<span class="hljs-class"><span class="hljs-keyword" style="color: #a626a4;">class</span> <span class="hljs-title" style="color: #c18401;">PostViewHolder</span></span>(itemView: View) : RecyclerView.ViewHolder(itemView) {
<span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">bind</span><span class="hljs-params">(postModel: <span class="hljs-type" style="color: #986801;">PostModel</span>, onItemCLickListener: <span class="hljs-type" style="color: #986801;">PostRecyclerAdapter</span>.<span class="hljs-type" style="color: #986801;">OnItemCLickListener</span>?)</span></span> {
itemView.name.text = postModel.title
itemView.content.text = postModel.body
itemView.setOnClickListener {
onItemCLickListener!!.onItemCLick(adapterPosition)
}
}
}</code></pre>
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">В айтеме у нас будет два поля, одно будет как тайтл, второе как дескрипшн, собственно что мы в этом холдере и делаем, берем из данной нам модели данные и отображаем в этих текстовых полях. Так же говорим что весь айтем будет кликабельный и мы по к лику передаем позицию в списке.</span><br />
<br style="background-color: white; color: #222222; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">PostRecyclerAdapter.kt</span><br />
<pre style="background-color: white; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow: auto hidden; padding: 0px; word-break: break-all;"><code class="kotlin hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); color: #383a42; display: block; font-family: menlo, monaco, "courier new", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="color: #a626a4;">import</span> android.view.LayoutInflater
<span class="hljs-keyword" style="color: #a626a4;">import</span> android.view.ViewGroup
<span class="hljs-keyword" style="color: #a626a4;">import</span> androidx.recyclerview.widget.RecyclerView
<span class="hljs-keyword" style="color: #a626a4;">import</span> dajver.com.mvpexample.R
<span class="hljs-keyword" style="color: #a626a4;">import</span> dajver.com.mvpexample.adapter.holder.PostViewHolder
<span class="hljs-keyword" style="color: #a626a4;">import</span> dajver.com.mvpexample.api.model.PostModel
<span class="hljs-class"><span class="hljs-keyword" style="color: #a626a4;">class</span> <span class="hljs-title" style="color: #c18401;">PostRecyclerAdapter</span></span>(<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-keyword" style="color: #a626a4;">val</span> postList: List<PostModel>) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-keyword" style="color: #a626a4;">var</span> onItemCLickListener: OnItemCLickListener? = <span class="hljs-literal" style="color: #0184bb;">null</span>
<span class="hljs-keyword" style="color: #a626a4;">override</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">onCreateViewHolder</span><span class="hljs-params">(parent: <span class="hljs-type" style="color: #986801;">ViewGroup</span>, viewType: <span class="hljs-type" style="color: #986801;">Int</span>)</span></span>: RecyclerView.ViewHolder {
<span class="hljs-keyword" style="color: #a626a4;">return</span> PostViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.item_posts, parent, <span class="hljs-literal" style="color: #0184bb;">false</span>))
}
<span class="hljs-keyword" style="color: #a626a4;">override</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">onBindViewHolder</span><span class="hljs-params">(holder: <span class="hljs-type" style="color: #986801;">RecyclerView</span>.<span class="hljs-type" style="color: #986801;">ViewHolder</span>, position: <span class="hljs-type" style="color: #986801;">Int</span>)</span></span> {
<span class="hljs-keyword" style="color: #a626a4;">val</span> viewHolder = holder <span class="hljs-keyword" style="color: #a626a4;">as</span> PostViewHolder
viewHolder.bind(postList[position], onItemCLickListener)
}
<span class="hljs-keyword" style="color: #a626a4;">override</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">getItemCount</span><span class="hljs-params">()</span></span>: <span class="hljs-built_in" style="color: #c18401;">Int</span> {
<span class="hljs-keyword" style="color: #a626a4;">return</span> postList.size
}
<span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">setOnItemClickListener</span><span class="hljs-params">(onItemClickListener: <span class="hljs-type" style="color: #986801;">OnItemCLickListener</span>)</span></span> {
<span class="hljs-keyword" style="color: #a626a4;">this</span>.onItemCLickListener = onItemClickListener
}
<span class="hljs-class"><span class="hljs-keyword" style="color: #a626a4;">interface</span> <span class="hljs-title" style="color: #c18401;">OnItemCLickListener</span> </span>{
<span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">onItemCLick</span><span class="hljs-params">(position: <span class="hljs-type" style="color: #986801;">Int</span>)</span></span>
}
}</code></pre>
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Стандартно рисуем адаптер, инициализируем холдер, передаем туда список полученый с сервера и лисенер который будет контролировать клики по списку.</span><br />
<br style="background-color: white; color: #222222; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">item_posts.xml</span><br />
<pre style="background-color: white; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow: auto hidden; padding: 0px; word-break: break-all;"><code class="xml hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); color: #383a42; display: block; font-family: menlo, monaco, "courier new", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-meta" style="color: #4078f2;"><?xml version="1.0" encoding="utf-8"?></span>
<span class="hljs-tag"><<span class="hljs-name" style="color: #e45649;">LinearLayout</span> <span class="hljs-attr" style="color: #986801;">xmlns:android</span>=<span class="hljs-string" style="color: #50a14f;">"http://schemas.android.com/apk/res/android"</span>
<span class="hljs-attr" style="color: #986801;">android:orientation</span>=<span class="hljs-string" style="color: #50a14f;">"vertical"</span>
<span class="hljs-attr" style="color: #986801;">android:layout_width</span>=<span class="hljs-string" style="color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="color: #986801;">android:layout_height</span>=<span class="hljs-string" style="color: #50a14f;">"wrap_content"</span>
<span class="hljs-attr" style="color: #986801;">android:padding</span>=<span class="hljs-string" style="color: #50a14f;">"10dp"</span>></span>
<span class="hljs-tag"><<span class="hljs-name" style="color: #e45649;">TextView</span>
<span class="hljs-attr" style="color: #986801;">android:text</span>=<span class="hljs-string" style="color: #50a14f;">"TextView"</span>
<span class="hljs-attr" style="color: #986801;">android:layout_width</span>=<span class="hljs-string" style="color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="color: #986801;">android:layout_height</span>=<span class="hljs-string" style="color: #50a14f;">"wrap_content"</span>
<span class="hljs-attr" style="color: #986801;">android:id</span>=<span class="hljs-string" style="color: #50a14f;">"@+id/name"</span>
<span class="hljs-attr" style="color: #986801;">android:textColor</span>=<span class="hljs-string" style="color: #50a14f;">"@android:color/black"</span>
<span class="hljs-attr" style="color: #986801;">android:textStyle</span>=<span class="hljs-string" style="color: #50a14f;">"bold"</span>
<span class="hljs-attr" style="color: #986801;">android:padding</span>=<span class="hljs-string" style="color: #50a14f;">"10dp"</span>/></span>
<span class="hljs-tag"><<span class="hljs-name" style="color: #e45649;">TextView</span>
<span class="hljs-attr" style="color: #986801;">android:text</span>=<span class="hljs-string" style="color: #50a14f;">"TextView"</span>
<span class="hljs-attr" style="color: #986801;">android:layout_width</span>=<span class="hljs-string" style="color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="color: #986801;">android:layout_height</span>=<span class="hljs-string" style="color: #50a14f;">"wrap_content"</span>
<span class="hljs-attr" style="color: #986801;">android:id</span>=<span class="hljs-string" style="color: #50a14f;">"@+id/content"</span>
<span class="hljs-attr" style="color: #986801;">android:padding</span>=<span class="hljs-string" style="color: #50a14f;">"10dp"</span>
<span class="hljs-attr" style="color: #986801;">android:textSize</span>=<span class="hljs-string" style="color: #50a14f;">"18sp"</span>/></span>
<span class="hljs-tag"></<span class="hljs-name" style="color: #e45649;">LinearLayout</span>></span></code></pre>
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Вот так будет выглядеть айтем списка. Два текстовых поля с небольшими отступами.</span><br />
<br style="background-color: white; color: #222222; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Далее нам нужно заимплементировать PostsView в нашей MainActivity и подписаться на коллбеки которые будут возвращать нам или респонс или клик по айтему из презентера.</span><br />
<br style="background-color: white; color: #222222; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">MainActivity.kt</span><br />
<pre style="background-color: white; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow: auto hidden; padding: 0px; word-break: break-all;"><code class="kotlin hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); color: #383a42; display: block; font-family: menlo, monaco, "courier new", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="color: #a626a4;">import</span> android.os.Bundle
<span class="hljs-keyword" style="color: #a626a4;">import</span> android.widget.Toast
<span class="hljs-keyword" style="color: #a626a4;">import</span> androidx.appcompat.app.AppCompatActivity
<span class="hljs-keyword" style="color: #a626a4;">import</span> dajver.com.mvpexample.adapter.PostRecyclerAdapter
<span class="hljs-keyword" style="color: #a626a4;">import</span> dajver.com.mvpexample.mvc.PostsView
<span class="hljs-keyword" style="color: #a626a4;">import</span> dajver.com.mvpexample.api.model.PostModel
<span class="hljs-keyword" style="color: #a626a4;">import</span> dajver.com.mvpexample.mvc.presenter.PostsPresenter
<span class="hljs-keyword" style="color: #a626a4;">import</span> dajver.com.mvpexample.mvc.presenter.PostsPresenterImpl
<span class="hljs-keyword" style="color: #a626a4;">import</span> kotlinx.android.synthetic.main.activity_main.*
<span class="hljs-class"><span class="hljs-keyword" style="color: #a626a4;">class</span> <span class="hljs-title" style="color: #c18401;">MainActivity</span> : <span class="hljs-type" style="color: #986801;">AppCompatActivity</span></span>(), PostsView {
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-keyword" style="color: #a626a4;">var</span> mPresenter: PostsPresenter? = <span class="hljs-literal" style="color: #0184bb;">null</span>
<span class="hljs-keyword" style="color: #a626a4;">override</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">onCreate</span><span class="hljs-params">(savedInstanceState: <span class="hljs-type" style="color: #986801;">Bundle</span>?)</span></span> {
<span class="hljs-keyword" style="color: #a626a4;">super</span>.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
mPresenter = PostsPresenterImpl(<span class="hljs-keyword" style="color: #a626a4;">this</span>)
}
<span class="hljs-keyword" style="color: #a626a4;">override</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">showPosts</span><span class="hljs-params">(posts: <span class="hljs-type" style="color: #986801;">List</span><<span class="hljs-type" style="color: #986801;">PostModel</span>>)</span></span> {
<span class="hljs-keyword" style="color: #a626a4;">val</span> adapter = PostRecyclerAdapter(posts)
adapter.setOnItemClickListener(<span class="hljs-keyword" style="color: #a626a4;">object</span>: PostRecyclerAdapter.OnItemCLickListener {
<span class="hljs-keyword" style="color: #a626a4;">override</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">onItemCLick</span><span class="hljs-params">(position: <span class="hljs-type" style="color: #986801;">Int</span>)</span></span> {
mPresenter!!.onItemWasClicked(position)
}
})
recyclerView.adapter = adapter
}
<span class="hljs-keyword" style="color: #a626a4;">override</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">onPostClick</span><span class="hljs-params">(text: <span class="hljs-type" style="color: #986801;">PostModel</span>)</span></span> {
Toast.makeText(<span class="hljs-keyword" style="color: #a626a4;">this</span>, text.body, Toast.LENGTH_LONG).show()
}
}</code></pre>
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">В onCreate мы создали инстанс нашего Presenter'a и подписались на колбеки, дальше создали два метода которые у нас будут отображать список (showPosts) и делать какие-то действия по клику на айтем (onPostClick). Собственно эти два метода которые мы описали в интерфейсе PostsView. </span><br />
<br style="background-color: white; color: #222222; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">activity_main.xml</span><br />
<pre style="background-color: white; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow: auto hidden; padding: 0px; word-break: break-all;"><code class="xml hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); color: #383a42; display: block; font-family: menlo, monaco, "courier new", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-meta" style="color: #4078f2;"><?xml version="1.0" encoding="utf-8"?></span>
<span class="hljs-tag"><<span class="hljs-name" style="color: #e45649;">LinearLayout</span>
<span class="hljs-attr" style="color: #986801;">xmlns:android</span>=<span class="hljs-string" style="color: #50a14f;">"http://schemas.android.com/apk/res/android"</span>
<span class="hljs-attr" style="color: #986801;">xmlns:tools</span>=<span class="hljs-string" style="color: #50a14f;">"http://schemas.android.com/tools"</span>
<span class="hljs-attr" style="color: #986801;">android:layout_width</span>=<span class="hljs-string" style="color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="color: #986801;">android:layout_height</span>=<span class="hljs-string" style="color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="color: #986801;">xmlns:app</span>=<span class="hljs-string" style="color: #50a14f;">"http://schemas.android.com/apk/res-auto"</span>
<span class="hljs-attr" style="color: #986801;">tools:context</span>=<span class="hljs-string" style="color: #50a14f;">".MainActivity"</span>></span>
<span class="hljs-tag"><<span class="hljs-name" style="color: #e45649;">androidx.recyclerview.widget.RecyclerView</span>
<span class="hljs-attr" style="color: #986801;">android:id</span>=<span class="hljs-string" style="color: #50a14f;">"@+id/recyclerView"</span>
<span class="hljs-attr" style="color: #986801;">android:layout_width</span>=<span class="hljs-string" style="color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="color: #986801;">android:layout_height</span>=<span class="hljs-string" style="color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="color: #986801;">app:layoutManager</span>=<span class="hljs-string" style="color: #50a14f;">"androidx.recyclerview.widget.LinearLayoutManager"</span> /></span>
<span class="hljs-tag"></<span class="hljs-name" style="color: #e45649;">LinearLayout</span>></span></code></pre>
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Наша активити будет в себе содержать только список в котором сразу будет прописан леяут менеджер для удобства что бы не требовалось это делать в коде.</span><br />
<br style="background-color: white; color: #222222; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">AndroidManifest.xml</span><br />
<pre style="background-color: white; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow: auto hidden; padding: 0px; word-break: break-all;"><code class="xml hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); color: #383a42; display: block; font-family: menlo, monaco, "courier new", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-tag"><<span class="hljs-name" style="color: #e45649;">uses-permission</span> <span class="hljs-attr" style="color: #986801;">android:name</span>=<span class="hljs-string" style="color: #50a14f;">"android.permission.INTERNET"</span> /></span></code></pre>
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Так же нужно еще прописать работу с интернетом в манифесте, и собственно на этом можно запускать и смотреть как работает наше идеальное приложение. </span><br />
<br style="background-color: white; color: #222222; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">В активити теперь минимум кода, все скрыто под капотом нашей архитектуры. Но при этом что бы добавить что-то новое теперь совершенно не составит труда, добавить например новый запрос в Repository очень просто — создаем просто еще один метод в интерфейсе, и потом описываем его работу в имплементе данного интерфейса, так же и с остальным, все что нам нунжно сперва создаем в интерфейсе, потом имплементим в классах которые это требуют. Все очень гибко и красиво.</span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;"><br /></span><span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif;"><b><span style="font-size: large;">Исходники:</span></b></span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif;"><b><span style="font-size: large;"><a href="https://github.com/dajver/MVPExample">GitHub</a></span></b></span></div>
dajverhttp://www.blogger.com/profile/09427222798699404442noreply@blogger.com1tag:blogger.com,1999:blog-5677605911484164185.post-50642675283964578872019-08-04T18:23:00.000+03:002019-08-04T18:23:08.651+03:00Программная нарезка видео с помощью mp4parser<div dir="ltr" style="text-align: left;" trbidi="on">
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Продолжаем работать с видосиками. У меня недавно был случай что потребовалось нарезать один видео файл на много маленьких файлов вырезая ненужные части. И я такое запедалил с помощью замечательной библиотеки от Google которая называется </span><a href="https://github.com/sannies/mp4parser" style="background-color: white; color: #992298; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px; text-decoration-line: none;">mp4parser</a><span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">. </span><br />
<br />
<div style="text-align: center;">
<img alt="image" height="400" src="https://github.com/dajver/VideoTrimmerExample/blob/master/images/sample.gif?raw=true" style="background-color: white; border-style: none; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px; height: auto; margin: 0px; max-width: 100%; vertical-align: middle;" width="224" /></div>
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Эта библиотека позволяет помимо нарезки так же:</span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">— соединять файлы у которых одинаковые настройки енкодинга;</span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">— накладывать аудио дорожку на видео;</span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">— изменение или добавление меты;</span><br />
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Библиотека очень мощная, вот прям не могу даже ничего плохого про нее сказать. Очень быстро справляется со всеми задачами, прямо вот в долю секунды. Однажды пробовал нарезать огромный видео файл на несколько частей, так либа справлялась за 2 — 3 секунды, даже боюсь представить как они это сделали, там реально какая-то магия.</span><br />
<a name='more'></a><span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;"><br /></span>
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">app/build.gradle</span><br />
<pre style="background-color: white; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow: auto hidden; padding: 0px; word-break: break-all;"><code class="java hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;">dependencies {
implementation <span class="hljs-string" style="color: #50a14f;">'androidx.appcompat:appcompat:1.0.2'</span>
implementation <span class="hljs-string" style="color: #50a14f;">"com.googlecode.mp4parser:isoparser:1.1.22"</span>
}</code></pre>
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">По традиции изначально подключаем библиотеки, у нас их будет две, одни это androidx, а вторая mp4parser.</span><br />
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">RangesModel.kt</span><br />
<pre style="background-color: white; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow: auto hidden; padding: 0px; word-break: break-all;"><code class="kotlin hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-class"><span class="hljs-keyword" style="color: #a626a4;">class</span> <span class="hljs-title" style="color: #c18401;">RangesModel</span></span>(<span class="hljs-keyword" style="color: #a626a4;">var</span> name: String?, <span class="hljs-keyword" style="color: #a626a4;">var</span> startTime: <span class="hljs-built_in" style="color: #c18401;">Double</span>, <span class="hljs-keyword" style="color: #a626a4;">var</span> endTime: <span class="hljs-built_in" style="color: #c18401;">Double</span>)</code></pre>
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">В этой модели у нас будет в конструкторе передаваться название файла который будем создавать после нарезки, так же начальное время видоса, с какого момента резать и до какого момента резать. То есть если видео допустим длится 10 минут, а мы хотим вырезать видео с 3 секунды и до 8 секунды, будем передавать в startTime = 3, а в endTime = 8 и на выходе получим видео в 5 секунд в котором будет кусок видоса.</span><br />
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">TrimmerEndWorkListener.kt</span><br />
<pre style="background-color: white; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow: auto hidden; padding: 0px; word-break: break-all;"><code class="kotlin hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="color: #a626a4;">import</span> dajver.com.videotrimmerexample.timmer.model.RangesModel
<span class="hljs-keyword" style="color: #a626a4;">import</span> java.io.File
<span class="hljs-class"><span class="hljs-keyword" style="color: #a626a4;">interface</span> <span class="hljs-title" style="color: #c18401;">TrimmerEndWorkListener</span> </span>{
<span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">onTrimEnds</span><span class="hljs-params">(file: <span class="hljs-type" style="color: #986801;">File</span>, newRange: <span class="hljs-type" style="color: #986801;">RangesModel</span>)</span></span>
<span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">onTrimError</span><span class="hljs-params">(error: <span class="hljs-type" style="color: #986801;">Exception</span>)</span></span>
<span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">onEmptyFileError</span><span class="hljs-params">(error: <span class="hljs-type" style="color: #986801;">Exception</span>)</span></span>
}</code></pre>
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Дальше создадим один лисенер который будет нам возвращать статусы по поводу нарезки видео из самого класса описывающего работу по нарезке. Будет возвращат нам ошибки и по окончанию нарезки будет возвращать нам видос и рендж с которым было нарезанно видео.</span><br />
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Далее опишем сам класс по нарезке видео. Этот код в принципе довольно распостраненный, его можно найти в куче проектов на github'e, я его немного модифицировал для своих нужд, по этому он чуть-чуть выглядеть будет иначе. Но основной функционал стандартный для этой библиотеки.</span><br />
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">VideoTrimmer.kt</span><br />
<pre style="background-color: white; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow: auto hidden; padding: 0px; word-break: break-all;"><code class="kotlin hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="color: #a626a4;">import</span> android.content.Context
<span class="hljs-keyword" style="color: #a626a4;">import</span> android.os.Environment
<span class="hljs-keyword" style="color: #a626a4;">import</span> com.coremedia.iso.IsoFile
<span class="hljs-keyword" style="color: #a626a4;">import</span> com.googlecode.mp4parser.FileDataSourceImpl
<span class="hljs-keyword" style="color: #a626a4;">import</span> com.googlecode.mp4parser.authoring.Track
<span class="hljs-keyword" style="color: #a626a4;">import</span> com.googlecode.mp4parser.authoring.builder.DefaultMp4Builder
<span class="hljs-keyword" style="color: #a626a4;">import</span> com.googlecode.mp4parser.authoring.container.mp4.MovieCreator
<span class="hljs-keyword" style="color: #a626a4;">import</span> com.googlecode.mp4parser.authoring.tracks.AppendTrack
<span class="hljs-keyword" style="color: #a626a4;">import</span> com.googlecode.mp4parser.authoring.tracks.CroppedTrack
<span class="hljs-keyword" style="color: #a626a4;">import</span> dajver.com.videotrimmerexample.timmer.interfaces.TrimmerEndWorkListener
<span class="hljs-keyword" style="color: #a626a4;">import</span> dajver.com.videotrimmerexample.timmer.model.RangesModel
<span class="hljs-keyword" style="color: #a626a4;">import</span> java.io.File
<span class="hljs-keyword" style="color: #a626a4;">import</span> java.io.FileOutputStream
<span class="hljs-keyword" style="color: #a626a4;">import</span> java.io.IOException
<span class="hljs-keyword" style="color: #a626a4;">import</span> java.util.*
<span class="hljs-class"><span class="hljs-keyword" style="color: #a626a4;">class</span> <span class="hljs-title" style="color: #c18401;">VideoTrimmer</span></span>(<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-keyword" style="color: #a626a4;">val</span> context: Context, <span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-keyword" style="color: #a626a4;">val</span> srcPath: File, <span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-keyword" style="color: #a626a4;">val</span> callback: TrimmerEndWorkListener) {
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-keyword" style="color: #a626a4;">var</span> videoTimeScale: <span class="hljs-built_in" style="color: #c18401;">Long</span> = <span class="hljs-number" style="color: #986801;">0</span>
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-keyword" style="color: #a626a4;">var</span> totalLength: <span class="hljs-built_in" style="color: #c18401;">Double</span> = <span class="hljs-number" style="color: #986801;">0.0</span>
<span class="hljs-keyword" style="color: #a626a4;">init</span> {
<span class="hljs-keyword" style="color: #a626a4;">try</span> {
<span class="hljs-keyword" style="color: #a626a4;">val</span> isoFile = IsoFile(srcPath.absolutePath)
<span class="hljs-keyword" style="color: #a626a4;">if</span> (isoFile.movieBox == <span class="hljs-literal" style="color: #0184bb;">null</span>) {
callback.onEmptyFileError(Exception(<span class="hljs-string" style="color: #50a14f;">"Bad video error"</span>))
} <span class="hljs-keyword" style="color: #a626a4;">else</span> {
videoTimeScale = isoFile.movieBox.movieHeaderBox.timescale
totalLength = isoFile.movieBox.movieHeaderBox.duration.toDouble() / videoTimeScale
}
} <span class="hljs-keyword" style="color: #a626a4;">catch</span> (e: IOException) {
e.printStackTrace()
callback.onTrimError(e)
}
}
<span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">startTrim</span><span class="hljs-params">(range: <span class="hljs-type" style="color: #986801;">RangesModel</span>)</span></span> {
<span class="hljs-keyword" style="color: #a626a4;">try</span> {
genVideoUsingMp4Parser(range)
} <span class="hljs-keyword" style="color: #a626a4;">catch</span> (ex: Exception) {
callback.onTrimError(ex)
}
}
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">genVideoUsingMp4Parser</span><span class="hljs-params">(range: <span class="hljs-type" style="color: #986801;">RangesModel</span>)</span></span> {
<span class="hljs-keyword" style="color: #a626a4;">try</span> {
<span class="hljs-keyword" style="color: #a626a4;">val</span> createdFile: File?
<span class="hljs-keyword" style="color: #a626a4;">var</span> actualRange: RangesModel? = <span class="hljs-literal" style="color: #0184bb;">null</span>
<span class="hljs-keyword" style="color: #a626a4;">val</span> movie = MovieCreator.build(FileDataSourceImpl(srcPath.absolutePath))
<span class="hljs-keyword" style="color: #a626a4;">val</span> tracks = movie.tracks
movie.tracks = LinkedList()
<span class="hljs-keyword" style="color: #a626a4;">var</span> startTime1 = range.startTime
<span class="hljs-keyword" style="color: #a626a4;">var</span> endTime1 = range.endTime
<span class="hljs-keyword" style="color: #a626a4;">var</span> timeCorrected = <span class="hljs-literal" style="color: #0184bb;">false</span>
<span class="hljs-keyword" style="color: #a626a4;">for</span> (track <span class="hljs-keyword" style="color: #a626a4;">in</span> tracks) {
<span class="hljs-keyword" style="color: #a626a4;">if</span> (track.syncSamples != <span class="hljs-literal" style="color: #0184bb;">null</span> && track.syncSamples.isNotEmpty()) {
<span class="hljs-keyword" style="color: #a626a4;">if</span> (timeCorrected) {
callback.onTrimError(RuntimeException(<span class="hljs-string" style="color: #50a14f;">"The startTime has already been corrected by another track with SyncSample. Not Supported."</span>))
}
<span class="hljs-keyword" style="color: #a626a4;">val</span> correctedStartTime = correctTimeToSyncSample(track, startTime1, <span class="hljs-literal" style="color: #0184bb;">false</span>)
<span class="hljs-keyword" style="color: #a626a4;">if</span> (correctedStartTime < startTime1 || (startTime1 == <span class="hljs-number" style="color: #986801;">0.0</span> && range.startTime != <span class="hljs-number" style="color: #986801;">0.0</span> && correctedStartTime != <span class="hljs-number" style="color: #986801;">0.0</span>)) {
startTime1 = correctedStartTime
}
<span class="hljs-keyword" style="color: #a626a4;">val</span> correctedEndTime = correctTimeToSyncSample(track, endTime1, <span class="hljs-literal" style="color: #0184bb;">true</span>)
<span class="hljs-keyword" style="color: #a626a4;">if</span> (correctedEndTime > endTime1 || (endTime1 == <span class="hljs-number" style="color: #986801;">0.0</span> && range.endTime != <span class="hljs-number" style="color: #986801;">0.0</span> && correctedEndTime != <span class="hljs-number" style="color: #986801;">0.0</span>)) {
endTime1 = correctedEndTime
}
timeCorrected = <span class="hljs-literal" style="color: #0184bb;">true</span>
}
}
<span class="hljs-keyword" style="color: #a626a4;">var</span> finalCutPointStartTime = <span class="hljs-number" style="color: #986801;">0.0</span>
<span class="hljs-keyword" style="color: #a626a4;">var</span> finalCutPointEndTime = <span class="hljs-number" style="color: #986801;">0.0</span>
<span class="hljs-keyword" style="color: #a626a4;">var</span> realCutPointsCalculated = <span class="hljs-literal" style="color: #0184bb;">false</span>
<span class="hljs-keyword" style="color: #a626a4;">for</span> (track <span class="hljs-keyword" style="color: #a626a4;">in</span> tracks) {
<span class="hljs-keyword" style="color: #a626a4;">var</span> currentSample: <span class="hljs-built_in" style="color: #c18401;">Long</span> = <span class="hljs-number" style="color: #986801;">0</span>
<span class="hljs-keyword" style="color: #a626a4;">var</span> currentTime = <span class="hljs-number" style="color: #986801;">0.0</span>
<span class="hljs-keyword" style="color: #a626a4;">var</span> lastTime = -<span class="hljs-number" style="color: #986801;">1.0</span>
<span class="hljs-keyword" style="color: #a626a4;">var</span> startSample1: <span class="hljs-built_in" style="color: #c18401;">Long</span> = -<span class="hljs-number" style="color: #986801;">1</span>
<span class="hljs-keyword" style="color: #a626a4;">var</span> endSample1: <span class="hljs-built_in" style="color: #c18401;">Long</span> = -<span class="hljs-number" style="color: #986801;">1</span>
track.sampleDurations.forEach {
<span class="hljs-keyword" style="color: #a626a4;">if</span> (currentTime > lastTime && currentTime <= startTime1) {
startSample1 = currentSample
finalCutPointStartTime = currentTime
}
<span class="hljs-keyword" style="color: #a626a4;">if</span> (currentTime > lastTime && currentTime <= endTime1) {
endSample1 = currentSample
finalCutPointEndTime = currentTime + (it.toDouble() / track.trackMetaData.timescale.toDouble())
}
lastTime = currentTime
currentTime += it.toDouble() / track.trackMetaData.timescale.toDouble()
currentSample++
}
<span class="hljs-keyword" style="color: #a626a4;">if</span> (!realCutPointsCalculated) {
<span class="hljs-keyword" style="color: #a626a4;">if</span> (finalCutPointStartTime > <span class="hljs-number" style="color: #986801;">0</span>) {
finalCutPointStartTime *= <span class="hljs-number" style="color: #986801;">1000</span>
}
<span class="hljs-keyword" style="color: #a626a4;">val</span> newRange = RangesModel(range.name, finalCutPointStartTime, finalCutPointEndTime * <span class="hljs-number" style="color: #986801;">1000</span>)
actualRange = newRange
realCutPointsCalculated = <span class="hljs-literal" style="color: #0184bb;">true</span>
}
movie.addTrack(AppendTrack(CroppedTrack(track, startSample1, endSample1)))
}
<span class="hljs-keyword" style="color: #a626a4;">val</span> created = File(context.getExternalFilesDir(Environment.DIRECTORY_DCIM), range.name + <span class="hljs-string" style="color: #50a14f;">".mp4"</span>)
<span class="hljs-keyword" style="color: #a626a4;">if</span> (!created.exists())
created.createNewFile()
createdFile = created
<span class="hljs-keyword" style="color: #a626a4;">val</span> <span class="hljs-keyword" style="color: #a626a4;">out</span> = DefaultMp4Builder().build(movie)
<span class="hljs-keyword" style="color: #a626a4;">val</span> fos = FileOutputStream(created)
<span class="hljs-keyword" style="color: #a626a4;">val</span> fc = fos.channel
<span class="hljs-keyword" style="color: #a626a4;">out</span>.writeContainer(fc)
fc.close()
fos.close()
callback.onTrimEnds(createdFile, actualRange!!)
} <span class="hljs-keyword" style="color: #a626a4;">catch</span> (e: OutOfMemoryError) {
callback.onTrimError(java.lang.Exception(e.localizedMessage))
} <span class="hljs-keyword" style="color: #a626a4;">catch</span> (e1: Throwable) {
callback.onTrimError(java.lang.Exception(e1.localizedMessage))
}
}
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">correctTimeToSyncSample</span><span class="hljs-params">(track: <span class="hljs-type" style="color: #986801;">Track</span>, cutHere: <span class="hljs-type" style="color: #986801;">Double</span>, next: <span class="hljs-type" style="color: #986801;">Boolean</span>)</span></span>: <span class="hljs-built_in" style="color: #c18401;">Double</span> {
<span class="hljs-keyword" style="color: #a626a4;">val</span> timeOfSyncSamples = DoubleArray(track.syncSamples.size)
<span class="hljs-keyword" style="color: #a626a4;">var</span> currentSample: <span class="hljs-built_in" style="color: #c18401;">Long</span> = <span class="hljs-number" style="color: #986801;">0</span>
<span class="hljs-keyword" style="color: #a626a4;">var</span> currentTime = <span class="hljs-number" style="color: #986801;">0.0</span>
track.sampleDurations.forEach {
<span class="hljs-keyword" style="color: #a626a4;">if</span> (Arrays.binarySearch(track.syncSamples, currentSample + <span class="hljs-number" style="color: #986801;">1</span>) >= <span class="hljs-number" style="color: #986801;">0</span>) {
timeOfSyncSamples[Arrays.binarySearch(track.syncSamples, currentSample + <span class="hljs-number" style="color: #986801;">1</span>)] = currentTime
}
currentTime += it.toDouble() / track.trackMetaData.timescale.toDouble()
currentSample++
}
<span class="hljs-keyword" style="color: #a626a4;">var</span> previous = <span class="hljs-number" style="color: #986801;">0.0</span>
<span class="hljs-keyword" style="color: #a626a4;">for</span> (timeOfSyncSample <span class="hljs-keyword" style="color: #a626a4;">in</span> timeOfSyncSamples) {
<span class="hljs-keyword" style="color: #a626a4;">if</span> (timeOfSyncSample > cutHere) {
<span class="hljs-keyword" style="color: #a626a4;">return</span> <span class="hljs-keyword" style="color: #a626a4;">if</span> (next) {
timeOfSyncSample
} <span class="hljs-keyword" style="color: #a626a4;">else</span> {
previous
}
}
previous = timeOfSyncSample
}
<span class="hljs-keyword" style="color: #a626a4;">return</span> timeOfSyncSamples[timeOfSyncSamples.size - <span class="hljs-number" style="color: #986801;">1</span>]
}
}</code></pre>
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">В кратце если сказать что тут происходит — то тут в конструктор мы передаем контекст для работы с путями в файловой системе, передаем файл который мы будем нарезать, и коллбек для получения результатов по окончанию работы библиотеки. Дальше мы в конструкторе получаем длинну видео, создаем трек с помощью которого дальше нарезаем в цикле видео по ренжам которые мы задали. Так же мы проверяем что у нас endTime не больше чем startTime, корректируем ренжи если это требуется и потом уже нарезаем видео.</span><br />
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Если все хорошо, и видео нормально записалось без каких либо проблем, мы получаем коллбек в активити что все ок, если нет то получаем эксепшены в которых понятно в чем проблема. Если более детально описать то</span><br />
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Если более детально разложить по методам, то это выглядит немного сложнее. В конструкторе init — мы проверяем длинну видео, что бы она была не 0, если все нормально то записываем длинну видео и дальше переходим в startTrim — который запускает если видео файл корректный — метод по нарезке genVideoUsingMp4Parser, иначе если файл битый или у него какие-то проблемы с метой, try выкинет эксепшн в catch и нам прилетит колбек с ексепшином о том что случилось во время старта нарезки видео.</span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">— genVideoUsingMp4Parser — самый главный метод в данном классе. В нем мы создаем инстанс MovieCreator в который передаем путь к файлу который мы хотим нарезать, создаем треки исходя из этого файла. Далее корректируем тайминг у видео, если это требуется, бывает такое что тайминг уже откорректирован у видео, на пример если оно было уже пропущено через эту библиотеку. Далее исходя из треков которые мы создали ранее на основе видео в цикле нарезаем видео. По окончанию всех действий над видео, мы записываем в наш инстанс MovieCreator начало видео с какого момента мы будем писать видео в файл, и конец видео на котором у нас будет видео заканчиваться. Дальше мы записываем ренжи и видео в отдельный файл и если все прошло успешно то мы отправляем коллбек в активити, если же на каком-то из этих этапов у нас произошла ошибка, то кидаем туда ексепшн.</span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">— correctTimeToSyncSample — здесь мы пытаемся найти трек с синхронизированными сэмплами. Тут мы должны убедиться, что начало нового фрагмента точно тот кадр который был указан в ренжах, что бы не обрезать ничего лишнего. Это стандартный метод который описан в документации к библиотеке mp4parser.</span><br />
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">activity_main.xml</span><br />
<pre style="background-color: white; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow: auto hidden; padding: 0px; word-break: break-all;"><code class="xml hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-meta" style="color: #4078f2;"><?xml version="1.0" encoding="utf-8"?></span>
<span class="hljs-tag"><<span class="hljs-name" style="color: #e45649;">LinearLayout</span>
<span class="hljs-attr" style="color: #986801;">xmlns:android</span>=<span class="hljs-string" style="color: #50a14f;">"http://schemas.android.com/apk/res/android"</span>
<span class="hljs-attr" style="color: #986801;">android:layout_width</span>=<span class="hljs-string" style="color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="color: #986801;">android:layout_height</span>=<span class="hljs-string" style="color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="color: #986801;">android:orientation</span>=<span class="hljs-string" style="color: #50a14f;">"vertical"</span>
<span class="hljs-attr" style="color: #986801;">android:gravity</span>=<span class="hljs-string" style="color: #50a14f;">"center"</span>></span>
<span class="hljs-tag"><<span class="hljs-name" style="color: #e45649;">LinearLayout</span>
<span class="hljs-attr" style="color: #986801;">android:orientation</span>=<span class="hljs-string" style="color: #50a14f;">"horizontal"</span>
<span class="hljs-attr" style="color: #986801;">android:layout_width</span>=<span class="hljs-string" style="color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="color: #986801;">android:layout_height</span>=<span class="hljs-string" style="color: #50a14f;">"wrap_content"</span>></span>
<span class="hljs-tag"><<span class="hljs-name" style="color: #e45649;">LinearLayout</span>
<span class="hljs-attr" style="color: #986801;">android:orientation</span>=<span class="hljs-string" style="color: #50a14f;">"vertical"</span>
<span class="hljs-attr" style="color: #986801;">android:layout_width</span>=<span class="hljs-string" style="color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="color: #986801;">android:layout_height</span>=<span class="hljs-string" style="color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="color: #986801;">android:layout_weight</span>=<span class="hljs-string" style="color: #50a14f;">"0.1"</span>
<span class="hljs-attr" style="color: #986801;">android:layout_margin</span>=<span class="hljs-string" style="color: #50a14f;">"20dp"</span>
<span class="hljs-attr" style="color: #986801;">android:gravity</span>=<span class="hljs-string" style="color: #50a14f;">"center"</span>></span>
<span class="hljs-tag"><<span class="hljs-name" style="color: #e45649;">TextView</span>
<span class="hljs-attr" style="color: #986801;">android:text</span>=<span class="hljs-string" style="color: #50a14f;">"Start trim time"</span>
<span class="hljs-attr" style="color: #986801;">android:layout_width</span>=<span class="hljs-string" style="color: #50a14f;">"wrap_content"</span>
<span class="hljs-attr" style="color: #986801;">android:layout_height</span>=<span class="hljs-string" style="color: #50a14f;">"wrap_content"</span>
<span class="hljs-attr" style="color: #986801;">android:layout_weight</span>=<span class="hljs-string" style="color: #50a14f;">"0.1"</span>/></span>
<span class="hljs-tag"><<span class="hljs-name" style="color: #e45649;">EditText</span>
<span class="hljs-attr" style="color: #986801;">android:layout_width</span>=<span class="hljs-string" style="color: #50a14f;">"wrap_content"</span>
<span class="hljs-attr" style="color: #986801;">android:layout_height</span>=<span class="hljs-string" style="color: #50a14f;">"wrap_content"</span>
<span class="hljs-attr" style="color: #986801;">android:inputType</span>=<span class="hljs-string" style="color: #50a14f;">"textPersonName"</span>
<span class="hljs-attr" style="color: #986801;">android:ems</span>=<span class="hljs-string" style="color: #50a14f;">"10"</span>
<span class="hljs-attr" style="color: #986801;">android:id</span>=<span class="hljs-string" style="color: #50a14f;">"@+id/startTrim"</span>
<span class="hljs-attr" style="color: #986801;">android:layout_weight</span>=<span class="hljs-string" style="color: #50a14f;">"0.1"</span>
<span class="hljs-attr" style="color: #986801;">android:gravity</span>=<span class="hljs-string" style="color: #50a14f;">"center|center_horizontal"</span>/></span>
<span class="hljs-tag"></<span class="hljs-name" style="color: #e45649;">LinearLayout</span>></span>
<span class="hljs-tag"><<span class="hljs-name" style="color: #e45649;">LinearLayout</span>
<span class="hljs-attr" style="color: #986801;">android:orientation</span>=<span class="hljs-string" style="color: #50a14f;">"vertical"</span>
<span class="hljs-attr" style="color: #986801;">android:layout_width</span>=<span class="hljs-string" style="color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="color: #986801;">android:layout_height</span>=<span class="hljs-string" style="color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="color: #986801;">android:layout_weight</span>=<span class="hljs-string" style="color: #50a14f;">"0.1"</span>
<span class="hljs-attr" style="color: #986801;">android:layout_margin</span>=<span class="hljs-string" style="color: #50a14f;">"20dp"</span>
<span class="hljs-attr" style="color: #986801;">android:gravity</span>=<span class="hljs-string" style="color: #50a14f;">"center"</span>></span>
<span class="hljs-tag"><<span class="hljs-name" style="color: #e45649;">TextView</span>
<span class="hljs-attr" style="color: #986801;">android:text</span>=<span class="hljs-string" style="color: #50a14f;">"End trim time"</span>
<span class="hljs-attr" style="color: #986801;">android:layout_width</span>=<span class="hljs-string" style="color: #50a14f;">"wrap_content"</span>
<span class="hljs-attr" style="color: #986801;">android:layout_height</span>=<span class="hljs-string" style="color: #50a14f;">"wrap_content"</span>
<span class="hljs-attr" style="color: #986801;">android:layout_weight</span>=<span class="hljs-string" style="color: #50a14f;">"0.1"</span>/></span>
<span class="hljs-tag"><<span class="hljs-name" style="color: #e45649;">EditText</span>
<span class="hljs-attr" style="color: #986801;">android:layout_width</span>=<span class="hljs-string" style="color: #50a14f;">"wrap_content"</span>
<span class="hljs-attr" style="color: #986801;">android:layout_height</span>=<span class="hljs-string" style="color: #50a14f;">"wrap_content"</span>
<span class="hljs-attr" style="color: #986801;">android:inputType</span>=<span class="hljs-string" style="color: #50a14f;">"textPersonName"</span>
<span class="hljs-attr" style="color: #986801;">android:ems</span>=<span class="hljs-string" style="color: #50a14f;">"10"</span>
<span class="hljs-attr" style="color: #986801;">android:id</span>=<span class="hljs-string" style="color: #50a14f;">"@+id/endTrim"</span>
<span class="hljs-attr" style="color: #986801;">android:layout_weight</span>=<span class="hljs-string" style="color: #50a14f;">"0.1"</span>
<span class="hljs-attr" style="color: #986801;">android:gravity</span>=<span class="hljs-string" style="color: #50a14f;">"center|center_horizontal"</span>/></span>
<span class="hljs-tag"></<span class="hljs-name" style="color: #e45649;">LinearLayout</span>></span>
<span class="hljs-tag"></<span class="hljs-name" style="color: #e45649;">LinearLayout</span>></span>
<span class="hljs-tag"><<span class="hljs-name" style="color: #e45649;">Button</span>
<span class="hljs-attr" style="color: #986801;">android:text</span>=<span class="hljs-string" style="color: #50a14f;">"Start Trim"</span>
<span class="hljs-attr" style="color: #986801;">android:layout_width</span>=<span class="hljs-string" style="color: #50a14f;">"wrap_content"</span>
<span class="hljs-attr" style="color: #986801;">android:layout_height</span>=<span class="hljs-string" style="color: #50a14f;">"wrap_content"</span>
<span class="hljs-attr" style="color: #986801;">android:id</span>=<span class="hljs-string" style="color: #50a14f;">"@+id/trimButton"</span>/></span>
<span class="hljs-tag"></<span class="hljs-name" style="color: #e45649;">LinearLayout</span>></span></code></pre>
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Наше приложение будет иметь два текстовых поля и два поля для ввода времени начала набрезки и конца нарезки видео. Так же у нас будет кнопка по нажатию на которую у нас будет вызываться метод startTrim и будет происходится нарезка видео.</span><br />
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">MainActivity.kt</span><br />
<pre style="background-color: white; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow: auto hidden; padding: 0px; word-break: break-all;"><code class="kotlin hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="color: #a626a4;">import</span> android.content.Intent
<span class="hljs-keyword" style="color: #a626a4;">import</span> android.net.Uri
<span class="hljs-keyword" style="color: #a626a4;">import</span> android.os.Bundle
<span class="hljs-keyword" style="color: #a626a4;">import</span> android.os.Environment
<span class="hljs-keyword" style="color: #a626a4;">import</span> androidx.appcompat.app.AppCompatActivity
<span class="hljs-keyword" style="color: #a626a4;">import</span> com.coremedia.iso.IsoFile
<span class="hljs-keyword" style="color: #a626a4;">import</span> dajver.com.videotrimmerexample.timmer.VideoTrimmer
<span class="hljs-keyword" style="color: #a626a4;">import</span> dajver.com.videotrimmerexample.timmer.interfaces.TrimmerEndWorkListener
<span class="hljs-keyword" style="color: #a626a4;">import</span> dajver.com.videotrimmerexample.timmer.model.RangesModel
<span class="hljs-keyword" style="color: #a626a4;">import</span> kotlinx.android.synthetic.main.activity_main.*
<span class="hljs-keyword" style="color: #a626a4;">import</span> java.io.File
<span class="hljs-class"><span class="hljs-keyword" style="color: #a626a4;">class</span> <span class="hljs-title" style="color: #c18401;">MainActivity</span> : <span class="hljs-type" style="color: #986801;">AppCompatActivity</span></span>(), TrimmerEndWorkListener {
<span class="hljs-keyword" style="color: #a626a4;">override</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">onCreate</span><span class="hljs-params">(savedInstanceState: <span class="hljs-type" style="color: #986801;">Bundle</span>?)</span></span> {
<span class="hljs-keyword" style="color: #a626a4;">super</span>.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
<span class="hljs-keyword" style="color: #a626a4;">val</span> fileToTrim = File(getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), <span class="hljs-string" style="color: #50a14f;">"sample.mp4"</span>)
<span class="hljs-keyword" style="color: #a626a4;">val</span> fileDuration = getFileDuration(fileToTrim)
startTrim.setText(<span class="hljs-number" style="color: #986801;">0</span>.toString())
endTrim.setText(fileDuration.toString())
trimButton.setOnClickListener {
<span class="hljs-keyword" style="color: #a626a4;">val</span> startTime = startTrim.text.toString().toDouble()
<span class="hljs-keyword" style="color: #a626a4;">val</span> endTime = endTrim.text.toString().toDouble()
<span class="hljs-keyword" style="color: #a626a4;">val</span> rangeModel = RangesModel(<span class="hljs-string" style="color: #50a14f;">"trimmed_file"</span>, startTime, endTime)
<span class="hljs-keyword" style="color: #a626a4;">val</span> trimmer = VideoTrimmer(<span class="hljs-symbol" style="color: #4078f2;">MainActivity@</span><span class="hljs-keyword" style="color: #a626a4;">this</span>, fileToTrim, <span class="hljs-symbol" style="color: #4078f2;">MainActivity@</span><span class="hljs-keyword" style="color: #a626a4;">this</span>)
trimmer.startTrim(rangeModel)
}
}
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">getFileDuration</span><span class="hljs-params">(file: <span class="hljs-type" style="color: #986801;">File</span>)</span></span> : <span class="hljs-built_in" style="color: #c18401;">Double</span> {
<span class="hljs-keyword" style="color: #a626a4;">val</span> videoTimeScale: <span class="hljs-built_in" style="color: #c18401;">Long</span>?
<span class="hljs-keyword" style="color: #a626a4;">var</span> totalLength: <span class="hljs-built_in" style="color: #c18401;">Double</span>? = <span class="hljs-literal" style="color: #0184bb;">null</span>
<span class="hljs-keyword" style="color: #a626a4;">val</span> isoFile = IsoFile(file.absolutePath)
<span class="hljs-keyword" style="color: #a626a4;">if</span> (isoFile.movieBox != <span class="hljs-literal" style="color: #0184bb;">null</span>) {
videoTimeScale = isoFile.movieBox.movieHeaderBox.timescale
totalLength = isoFile.movieBox.movieHeaderBox.duration.toDouble() / videoTimeScale
}
<span class="hljs-keyword" style="color: #a626a4;">return</span> totalLength!!
}
<span class="hljs-keyword" style="color: #a626a4;">override</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">onTrimEnds</span><span class="hljs-params">(file: <span class="hljs-type" style="color: #986801;">File</span>, newRange: <span class="hljs-type" style="color: #986801;">RangesModel</span>)</span></span> {
<span class="hljs-keyword" style="color: #a626a4;">val</span> intent = Intent(Intent.ACTION_VIEW, Uri.parse(file!!.path))
intent.setDataAndType(Uri.parse(file.path), <span class="hljs-string" style="color: #50a14f;">"video/mp4"</span>)
startActivity(intent)
}
<span class="hljs-keyword" style="color: #a626a4;">override</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">onTrimError</span><span class="hljs-params">(error: <span class="hljs-type" style="color: #986801;">Exception</span>)</span></span> {
error.printStackTrace()
}
<span class="hljs-keyword" style="color: #a626a4;">override</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">onEmptyFileError</span><span class="hljs-params">(error: <span class="hljs-type" style="color: #986801;">Exception</span>)</span></span> {
error.printStackTrace()
}
}</code></pre>
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">В onCreate мы задаем файл который мы будем обрезать, я решил что бы не добавлять лишнего ничего просто загружу файл на девайс и с памяти девайса буду брать его. Файл для примера можно скачать </span><a href="https://github.com/dajver/VideoTrimmerExample/blob/master/sample/sample.mp4" style="background-color: white; color: #992298; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px; text-decoration-line: none;">отсюда</a><span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">. Это видео должно быть загружено в папку /storage/emulated/0/Android/data/dajver.com.videotrimmerexample/files/Download/. Если есть большое желание то можно переделать в выбор из галереи например. Так вот, получаем видео, дальше получаем длинну видео с помощью метода getFileDuration() и отображаем ее в поле для ввода endTime. По клику на trimButton мы запускаем нашего триммера, подписываемся на коллбек, передаем файл который нарезаем и создаем методы лисенеров которые попросит создать студия.</span><br />
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">И после того как у нас вернется успешный результат о том что видео нарезано и все хорошо — мы открываем видео в видео плеере с помощью интента.</span><br />
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Вот такая штуковина эта нарезка видео с помощью mp4parser. Надеюсь кому-то это пригодится.</span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;"><br /></span>
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif;"><b><span style="font-size: large;">Исходники:</span></b></span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif;"><b><span style="font-size: large;"><a href="https://github.com/dajver/VideoTrimmerExample">GitHub</a></span></b></span></div>
dajverhttp://www.blogger.com/profile/09427222798699404442noreply@blogger.com0tag:blogger.com,1999:blog-5677605911484164185.post-89878170629667163542019-08-02T18:35:00.000+03:002019-08-05T17:18:34.670+03:00Реализация очереди задач в Android<div dir="ltr" style="text-align: left;" trbidi="on">
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Бывают такие задачи в которых приходится распределять работу функционала, что бы каждая задача выполнялась после окончания предыдущей. В таких случаях обычно пихают внутри колбека об окончании процесса что бы стартовал новый процесс, это выглядит не очень красиво, сильно грубо и нагромождено. </span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;"><br /></span>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://github.com/dajver/QueueFlowExample/blob/master/images/example.gif?raw=true" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img alt="image" border="0" height="400" src="https://github.com/dajver/QueueFlowExample/blob/master/images/example.gif?raw=true" style="background-color: white; border-style: none; color: #222222; font-size: 16px; height: auto; margin-top: 0px; max-width: 100%; vertical-align: middle;" width="224" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">В таких случаях обычно стараются использовать такую штуку как очередь. Она помогает поставить процесс понятно и легкоизменяемо, каждый просесс выполняется в отдельном потоке, отдельном классе, и никак не задевает работу следующего или предыдущего процесса, все предельно понятно и логично.</span><br />
<a name='more'></a><span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">В моем примере будет пример очереди в которой будет три этапа:</span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">— CREATE — это будет какой-нибудь этап на пример создания видео файла или чего-то.</span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">— WORK — далее мы образно говоря делаем какие-то действия над ним, режем файл, меняем кодек или еще что-то и отправляем на сервер.</span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">— CLEAN — стираем все файлы которые были созданы с памяти девайса.</span><br />
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Это очень абстрактно говоря тот флоу который я буду сегодня тут описывать. В реальности у нас не будет никаких действий над файлами, я просто добавлю задержку между процессами что бы показать что там что-то происходит. </span><br />
<div style="text-align: center;">
</div>
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Визуально выглядеть это все будет на экране как два текстовых поля которые показывают задержку между процессами и текущий процесс который выполняется. По нажатию на кноку у нас стартует очередь.</span><br />
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Давайте для начала решим какие статусы у нас будут, я их уже описал выше, теперь нам надо их перенести в енам.</span><br />
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">Statuses.kt</span><br />
<pre style="background-color: white; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow: auto hidden; padding: 0px; word-break: break-all;"><code class="kotlin hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="color: #a626a4;">object</span> Statuses {
<span class="hljs-keyword" style="color: #a626a4;">const</span> <span class="hljs-keyword" style="color: #a626a4;">val</span> CREATE = <span class="hljs-string" style="color: #50a14f;">"create"</span>
<span class="hljs-keyword" style="color: #a626a4;">const</span> <span class="hljs-keyword" style="color: #a626a4;">val</span> WORK = <span class="hljs-string" style="color: #50a14f;">"work"</span>
<span class="hljs-keyword" style="color: #a626a4;">const</span> <span class="hljs-keyword" style="color: #a626a4;">val</span> CLEAN = <span class="hljs-string" style="color: #50a14f;">"clean"</span>
}</code></pre>
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Как я и говорил выше, три статуса, они у нас будут описывать какие процессы у нас будут в очереди.</span><br />
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Далее нам нужно создать модель с которой у нас будет происходить сбор и получение данных, и в которой у нас будет хранится статусы и стейты процессов. Обычно это нужно делать где нибудь в БД, для того что бы эта информация хранилась постоянно и к ней можно было обратиться в случае ошибки или сбоя в очереди. Но я для упрощения примера решил это все хранить только во время жизни приложения, по этому все будем хранить в модельке. </span><br />
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">MetaDataModel.kt</span><br />
<pre style="background-color: white; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow: auto hidden; padding: 0px; word-break: break-all;"><code class="kotlin hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="color: #a626a4;">import</span> dajver.com.taskqueueexample.queue.enums.Statuses
<span class="hljs-class"><span class="hljs-keyword" style="color: #a626a4;">class</span> <span class="hljs-title" style="color: #c18401;">MetaDataModel</span></span>(<span class="hljs-keyword" style="color: #a626a4;">var</span> id: <span class="hljs-built_in" style="color: #c18401;">Int</span>?) {
<span class="hljs-keyword" style="color: #a626a4;">var</span> state: String? = Statuses.CREATE
<span class="hljs-keyword" style="color: #a626a4;">var</span> statusReason: String? = <span class="hljs-literal" style="color: #0184bb;">null</span>
<span class="hljs-keyword" style="color: #a626a4;">var</span> stateBeforeFail: String? = <span class="hljs-literal" style="color: #0184bb;">null</span>
}</code></pre>
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Данный класс у нас хранит в себе всю самую важную информацию касательно процесса, но так же в нем может быть информация касательно какого-то на пример файла который мы режем, меняем или отправляем на сервер, или что-то подобное. У меня все минимально, только то что потребуется в дальнейшем. state — стоит по дефолту CREATE, возможно в другом случае по дефолту статуса быть не может, по этому его придется убрать и он будет ставится или через конструктор или через сеттер.</span><br />
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Потом мы создаем несколько базовых классов и интерфейсов, которые будут у нас иметь основной функционал для работы с очередью.</span><br />
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">BaseWorkItem.kt</span><br />
<pre style="background-color: white; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow: auto hidden; padding: 0px; word-break: break-all;"><code class="kotlin hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="color: #a626a4;">import</span> dajver.com.taskqueueexample.models.MetaDataModel
<span class="hljs-keyword" style="color: #a626a4;">open</span> <span class="hljs-class"><span class="hljs-keyword" style="color: #a626a4;">class</span> <span class="hljs-title" style="color: #c18401;">BaseWorkItem</span></span>(<span class="hljs-keyword" style="color: #a626a4;">open</span> <span class="hljs-keyword" style="color: #a626a4;">var</span> metadata: MetaDataModel) {
<span class="hljs-keyword" style="color: #a626a4;">override</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">hashCode</span><span class="hljs-params">()</span></span>: <span class="hljs-built_in" style="color: #c18401;">Int</span> {
<span class="hljs-keyword" style="color: #a626a4;">return</span> <span class="hljs-number" style="color: #986801;">0</span>
}
<span class="hljs-keyword" style="color: #a626a4;">override</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">equals</span><span class="hljs-params">(other: <span class="hljs-type" style="color: #986801;">Any</span>?)</span></span>: <span class="hljs-built_in" style="color: #c18401;">Boolean</span> {
<span class="hljs-keyword" style="color: #a626a4;">if</span> (<span class="hljs-keyword" style="color: #a626a4;">this</span> === other) {
<span class="hljs-keyword" style="color: #a626a4;">return</span> <span class="hljs-literal" style="color: #0184bb;">true</span>
}
<span class="hljs-keyword" style="color: #a626a4;">if</span> (other == <span class="hljs-literal" style="color: #0184bb;">null</span> || <span class="hljs-keyword" style="color: #a626a4;">this</span>::<span class="hljs-class"><span class="hljs-keyword" style="color: #a626a4;">class</span> != <span class="hljs-title" style="color: #c18401;">other</span>:<span class="hljs-type" style="color: #986801;">:class) {</span></span>
<span class="hljs-keyword" style="color: #a626a4;">return</span> <span class="hljs-literal" style="color: #0184bb;">false</span>
}
<span class="hljs-keyword" style="color: #a626a4;">return</span> metadata.id == (other <span class="hljs-keyword" style="color: #a626a4;">as</span> BaseWorkItem).metadata.id
}
}</code></pre>
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Этот work item у нас является базовой точкой в которой у нас идет переопределение метода equals, для того что-бы мы могли понять являются ли work item's которые мы хотим сравнить — одинаковые или нет. Это мы будем понимать по ID которые у нас будут уникальные и которые мы сравниваем в методе equals. Так же у нас каждый work item с которым мы будем дальше работать будет наследником BaseWorkItem, по этому любой из имеющихся work item's мы сможем сравнить и использовать в базовых классах.</span><br />
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Далее создаем несколько лисенеров которые мы будем использовать для кидания колбеков из базовых классов в наши процессы и наоборот из процессов в базовый класс.</span><br />
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">BaseWorkListener.kt</span><br />
<pre style="background-color: white; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow: auto hidden; padding: 0px; word-break: break-all;"><code class="kotlin hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="color: #a626a4;">import</span> dajver.com.taskqueueexample.queue.base.model.BaseWorkItem
<span class="hljs-class"><span class="hljs-keyword" style="color: #a626a4;">interface</span> <span class="hljs-title" style="color: #c18401;">BaseWorkListener</span> </span>{
<span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">onJobComplete</span><span class="hljs-params">(workItem: <span class="hljs-type" style="color: #986801;">BaseWorkItem</span>)</span></span>
<span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">onJobFailed</span><span class="hljs-params">(exception: <span class="hljs-type" style="color: #986801;">Exception</span>, workItem: <span class="hljs-type" style="color: #986801;">BaseWorkItem</span>)</span></span>
}</code></pre>
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Этот листенер мы будем использовать для сигнализации в класс менеджер о том что данный процесс или закончил свою работу или зафейлился и упал и в классе менеджере мы будем уже дальше решать что делать, или двигаться на следующий процесс или выводить сообщение об ошибке.</span><br />
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">BaseProcessCallback.kt</span><br />
<pre style="background-color: white; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow: auto hidden; padding: 0px; word-break: break-all;"><code class="kotlin hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="color: #a626a4;">import</span> dajver.com.taskqueueexample.queue.base.model.BaseWorkItem
<span class="hljs-class"><span class="hljs-keyword" style="color: #a626a4;">interface</span> <span class="hljs-title" style="color: #c18401;">BaseProcessCallback</span><<span class="hljs-type" style="color: #986801;">T</span>> <span class="hljs-title" style="color: #c18401;">where</span> <span class="hljs-title" style="color: #c18401;">T</span> : <span class="hljs-type" style="color: #986801;">BaseWorkItem {</span></span>
<span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">onSuccess</span><span class="hljs-params">(workItem: <span class="hljs-type" style="color: #986801;">T</span>)</span></span>
<span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">onError</span><span class="hljs-params">(workItem: <span class="hljs-type" style="color: #986801;">T</span>, error: <span class="hljs-type" style="color: #986801;">String</span>?)</span></span>
}</code></pre>
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Так же у нас будет вот такой еще один лисенер, который будет кидать колбеки в базовый класс процессов, и в зависимости от прилетевшего колбека наш базовый класс будет уже проверять есть ли у нас в очереди еще какие-то задачи, и если есть то будет двигать их дальше, иначе если они остуствуют то просто выходить и останавливать работу.</span><br />
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">BaseTaskProcessor.kt</span><br />
<pre style="background-color: white; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow: auto hidden; padding: 0px; word-break: break-all;"><code class="kotlin hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="color: #a626a4;">import</span> dajver.com.taskqueueexample.queue.base.interfaces.BaseProcessCallback
<span class="hljs-keyword" style="color: #a626a4;">import</span> dajver.com.taskqueueexample.queue.base.interfaces.BaseWorkListener
<span class="hljs-keyword" style="color: #a626a4;">import</span> dajver.com.taskqueueexample.queue.base.model.BaseWorkItem
<span class="hljs-keyword" style="color: #a626a4;">abstract</span> <span class="hljs-class"><span class="hljs-keyword" style="color: #a626a4;">class</span> <span class="hljs-title" style="color: #c18401;">BaseTaskProcessor</span><<span class="hljs-type" style="color: #986801;">T</span>> : <span class="hljs-type" style="color: #986801;">BaseProcessCallback</span><<span class="hljs-type" style="color: #986801;">T</span>> <span class="hljs-title" style="color: #c18401;">where</span> <span class="hljs-title" style="color: #c18401;">T</span> : <span class="hljs-type" style="color: #986801;">BaseWorkItem {</span></span>
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-keyword" style="color: #a626a4;">var</span> queue = LinkedHashSet<T>()
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-keyword" style="color: #a626a4;">var</span> currentProcessingWorkItem: BaseWorkItem? = <span class="hljs-literal" style="color: #0184bb;">null</span>
<span class="hljs-keyword" style="color: #a626a4;">protected</span> <span class="hljs-keyword" style="color: #a626a4;">var</span> listener: BaseWorkListener? = <span class="hljs-literal" style="color: #0184bb;">null</span>
<span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">queueWorkItem</span><span class="hljs-params">(workItem: <span class="hljs-type" style="color: #986801;">T</span>)</span></span> {
<span class="hljs-keyword" style="color: #a626a4;">if</span> (currentProcessingWorkItem == <span class="hljs-literal" style="color: #0184bb;">null</span> || currentProcessingWorkItem!! != workItem) {
queue.add(workItem)
checkWorkQueue()
}
}
<span class="hljs-keyword" style="color: #a626a4;">override</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">onSuccess</span><span class="hljs-params">(workItem: <span class="hljs-type" style="color: #986801;">T</span>)</span></span> {
currentProcessingWorkItem = <span class="hljs-literal" style="color: #0184bb;">null</span>
checkWorkQueue()
}
<span class="hljs-keyword" style="color: #a626a4;">override</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">onError</span><span class="hljs-params">(workItem: <span class="hljs-type" style="color: #986801;">T</span>, error: <span class="hljs-type" style="color: #986801;">String</span>?)</span></span> {
currentProcessingWorkItem = <span class="hljs-literal" style="color: #0184bb;">null</span>
checkWorkQueue()
}
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">checkWorkQueue</span><span class="hljs-params">()</span></span> {
<span class="hljs-keyword" style="color: #a626a4;">if</span> (currentProcessingWorkItem == <span class="hljs-literal" style="color: #0184bb;">null</span> && queue.isNotEmpty()) {
<span class="hljs-keyword" style="color: #a626a4;">val</span> currentItem = queue.first()
queue.remove(currentItem)
currentProcessingWorkItem = currentItem
processWorkItem(currentItem, <span class="hljs-keyword" style="color: #a626a4;">this</span>)
}
}
<span class="hljs-keyword" style="color: #a626a4;">open</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">cancelAll</span><span class="hljs-params">()</span></span> {
currentProcessingWorkItem = <span class="hljs-literal" style="color: #0184bb;">null</span>
queue.clear()
}
<span class="hljs-keyword" style="color: #a626a4;">protected</span> <span class="hljs-keyword" style="color: #a626a4;">abstract</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">processWorkItem</span><span class="hljs-params">(item: <span class="hljs-type" style="color: #986801;">T</span>, baseProcessCallback: <span class="hljs-type" style="color: #986801;">BaseProcessCallback</span><<span class="hljs-type" style="color: #986801;">T</span>>)</span></span>
}</code></pre>
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Вот собственно наш базовый класс который будет следить за очередью, данный класс наследуются от BaseProcessCallback для получения колбеков из процессов которые подпишутся на изменения в данном классе. Так же у нас есть какая-то «Т» которая у нас обозначена как BaseWorkItem, а это значит что мы будем передавать WorkItem который будет наследником BaseWorkItem и в котором будут находится какие-то дополнительные поля которые понадобятся в ходе работы процессов.</span><br />
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">— queueWorkItem — добавляет все процессы в очередь и проверяет если список не пуст и в нем находятся какие-то процессы.</span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">— checkWorkQueue — берем первый айтем из списка и выполняем его с помощью метода processWorkItem который является абстрактным методом, он будет описываться в дочерних классах этого базового класса.</span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">— onSuccess / onError — у нас проверяет есть ли что-то еще в очереди и запускает его если еще что-то есть.</span><br />
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">С базовой частью мы закончили. Это по сути список всех классов которые у нас на данный момент будут использоваться в дочерних классах, кроме MetaDataModel. Далее мы будем создавать сами процессы которые будут дальше запускаться в очереди в менеджере процессов. </span><br />
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Как я говорил раньше, у нас будет три процесса: CREATE, WORK, CLEAN. Для каждого из этих процессов нам нужно создать отдельный WorkItem и Process в которые мы будем передавать нужные данные и получать колбеки с результатами работы.</span><br />
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">CreateWorkItem.kt</span><br />
<pre style="background-color: white; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow: auto hidden; padding: 0px; word-break: break-all;"><code class="kotlin hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="color: #a626a4;">import</span> dajver.com.taskqueueexample.models.MetaDataModel
<span class="hljs-keyword" style="color: #a626a4;">import</span> dajver.com.taskqueueexample.queue.base.model.BaseWorkItem
<span class="hljs-class"><span class="hljs-keyword" style="color: #a626a4;">class</span> <span class="hljs-title" style="color: #c18401;">CreateWorkItem</span></span>(<span class="hljs-keyword" style="color: #a626a4;">override</span> <span class="hljs-keyword" style="color: #a626a4;">var</span> metadata: MetaDataModel) : BaseWorkItem(metadata)</code></pre>
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">В данном айтеме у нас в конструкторе передаем MetaDataModel в которой задаем уникальный ID процесса и статус. Так же мы унаследовали для данного класса BaseWorkItem и передали metadata который мы передали в конструкторе.</span><br />
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">CreateProcess.kt</span><br />
<pre style="background-color: white; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow: auto hidden; padding: 0px; word-break: break-all;"><code class="kotlin hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="color: #a626a4;">import</span> android.os.Handler
<span class="hljs-keyword" style="color: #a626a4;">import</span> dajver.com.taskqueueexample.queue.base.BaseTaskProcessor
<span class="hljs-keyword" style="color: #a626a4;">import</span> dajver.com.taskqueueexample.queue.base.interfaces.BaseProcessCallback
<span class="hljs-keyword" style="color: #a626a4;">import</span> dajver.com.taskqueueexample.queue.base.interfaces.BaseWorkListener
<span class="hljs-keyword" style="color: #a626a4;">import</span> dajver.com.taskqueueexample.queue.flow.QueueFlowManager.Companion.SECONDS_IN_ONE_PROCESS
<span class="hljs-class"><span class="hljs-keyword" style="color: #a626a4;">class</span> <span class="hljs-title" style="color: #c18401;">CreateProcess</span></span>(<span class="hljs-keyword" style="color: #a626a4;">var</span> workListener: BaseWorkListener) : BaseTaskProcessor<CreateWorkItem>() {
<span class="hljs-keyword" style="color: #a626a4;">init</span> {
listener = workListener
}
<span class="hljs-keyword" style="color: #a626a4;">override</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">processWorkItem</span><span class="hljs-params">(item: <span class="hljs-type" style="color: #986801;">CreateWorkItem</span>, baseProcessCallback: <span class="hljs-type" style="color: #986801;">BaseProcessCallback</span><<span class="hljs-type" style="color: #986801;">CreateWorkItem</span>>)</span></span> {
Handler().postDelayed({
<span class="hljs-comment" style="color: #a0a1a7; font-style: italic;">// do something here and on success call - onSuccess and on fail - onError</span>
<span class="hljs-keyword" style="color: #a626a4;">try</span> {
baseProcessCallback.onSuccess(item)
workListener.onJobComplete(item)
} <span class="hljs-keyword" style="color: #a626a4;">catch</span> (e: Exception) {
baseProcessCallback.onError(item, e.message!!)
workListener.onJobFailed(e, item)
}
}, SECONDS_IN_ONE_PROCESS!!)
}
}</code></pre>
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Что же мы тут видим? Мы подписались в конструкторе на лисенера который будет кидать коллбеки в BaseTaskProcessor, так же мы унаследовались от BaseTaskProcessor для определения метода processWorkItem и описали работу данного класса в этом методе. В данном случае у нас просто хендлер который 5 секунду будет ничего не делать, а дальше кинет колбеки в BaseTaskProcessor и в менеджера процессов, который мы опишем далее. Таких классов у нас еще будет два, я сюда их добавлять не буду, их можно будет найти по этим двум ссылкам: WORK — </span><a href="https://github.com/dajver/QueueFlowExample/blob/master/app/src/main/java/dajver/com/taskqueueexample/queue/flow/work/WorkWorkItem.kt" style="background-color: white; color: #992298; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px; text-decoration-line: none;">WorkWorkItem.kt</a><span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">, </span><a href="https://github.com/dajver/QueueFlowExample/blob/master/app/src/main/java/dajver/com/taskqueueexample/queue/flow/work/WorkProcess.kt" style="background-color: white; color: #992298; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px; text-decoration-line: none;">WorkProcess.kt</a><span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">, CLEAN — </span><a href="https://github.com/dajver/QueueFlowExample/blob/master/app/src/main/java/dajver/com/taskqueueexample/queue/flow/clean/CleanWorkItem.kt" style="background-color: white; color: #992298; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px; text-decoration-line: none;">CleanWorkItem.kt</a><span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">, </span><a href="https://github.com/dajver/QueueFlowExample/blob/master/app/src/main/java/dajver/com/taskqueueexample/queue/flow/clean/CleanProcess.kt" style="background-color: white; color: #992298; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px; text-decoration-line: none;">CleanProcess.kt</a><br />
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Далее нам нужно создать менеджера который будет управлять этими всеми процессами и запускать их по колбекам которые будут прилетать из этих же процессов. Для начала создадим интерфейс для визуализации работы очереди.</span><br />
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">QueueFlowListener.kt</span><br />
<pre style="background-color: white; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow: auto hidden; padding: 0px; word-break: break-all;"><code class="kotlin hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="color: #a626a4;">import</span> dajver.com.taskqueueexample.models.MetaDataModel
<span class="hljs-class"><span class="hljs-keyword" style="color: #a626a4;">interface</span> <span class="hljs-title" style="color: #c18401;">QueueFlowListener</span> </span>{
<span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">onWorkItemStateChange</span><span class="hljs-params">(metaDataModel: <span class="hljs-type" style="color: #986801;">MetaDataModel</span>)</span></span>
}</code></pre>
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Данный интерфейс нам нужен для отправки колбека о статусе текущего процесса в активити для отображения в текстовых полях, какой на данный момент процесс в очереди, и сколько до окончания работы онного.</span><br />
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">QueueFlowManager.kt </span><br />
<pre style="background-color: white; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow: auto hidden; padding: 0px; word-break: break-all;"><code class="kotlin hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="color: #a626a4;">import</span> android.util.Log
<span class="hljs-keyword" style="color: #a626a4;">import</span> dajver.com.taskqueueexample.models.MetaDataModel
<span class="hljs-keyword" style="color: #a626a4;">import</span> dajver.com.taskqueueexample.queue.base.interfaces.BaseWorkListener
<span class="hljs-keyword" style="color: #a626a4;">import</span> dajver.com.taskqueueexample.queue.base.model.BaseWorkItem
<span class="hljs-keyword" style="color: #a626a4;">import</span> dajver.com.taskqueueexample.queue.enums.Statuses.CLEAN
<span class="hljs-keyword" style="color: #a626a4;">import</span> dajver.com.taskqueueexample.queue.enums.Statuses.CREATE
<span class="hljs-keyword" style="color: #a626a4;">import</span> dajver.com.taskqueueexample.queue.enums.Statuses.WORK
<span class="hljs-keyword" style="color: #a626a4;">import</span> dajver.com.taskqueueexample.queue.flow.clean.CleanProcess
<span class="hljs-keyword" style="color: #a626a4;">import</span> dajver.com.taskqueueexample.queue.flow.clean.CleanWorkItem
<span class="hljs-keyword" style="color: #a626a4;">import</span> dajver.com.taskqueueexample.queue.flow.create.CreateWorkItem
<span class="hljs-keyword" style="color: #a626a4;">import</span> dajver.com.taskqueueexample.queue.flow.work.WorkProcess
<span class="hljs-keyword" style="color: #a626a4;">import</span> dajver.com.taskqueueexample.queue.flow.work.WorkWorkItem
<span class="hljs-keyword" style="color: #a626a4;">import</span> dajver.com.taskqueueexample.queue.flow.create.CreateProcess
<span class="hljs-class"><span class="hljs-keyword" style="color: #a626a4;">class</span> <span class="hljs-title" style="color: #c18401;">QueueFlowManager</span></span>(<span class="hljs-keyword" style="color: #a626a4;">var</span> queueFlowListener: QueueFlowListener) : BaseWorkListener {
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-keyword" style="color: #a626a4;">var</span> createProcess: CreateProcess? = <span class="hljs-literal" style="color: #0184bb;">null</span>
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-keyword" style="color: #a626a4;">var</span> workProcess: WorkProcess? = <span class="hljs-literal" style="color: #0184bb;">null</span>
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-keyword" style="color: #a626a4;">var</span> cleanProcess: CleanProcess? = <span class="hljs-literal" style="color: #0184bb;">null</span>
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-keyword" style="color: #a626a4;">var</span> metaDataModel: MetaDataModel? = <span class="hljs-literal" style="color: #0184bb;">null</span>
<span class="hljs-keyword" style="color: #a626a4;">init</span> {
createProcess = CreateProcess(<span class="hljs-keyword" style="color: #a626a4;">this</span>)
workProcess = WorkProcess(<span class="hljs-keyword" style="color: #a626a4;">this</span>)
cleanProcess = CleanProcess(<span class="hljs-keyword" style="color: #a626a4;">this</span>)
metaDataModel = MetaDataModel(<span class="hljs-number" style="color: #986801;">1234</span>)
makeSequentialStatusMap()
}
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">makeSequentialStatusMap</span><span class="hljs-params">()</span></span> {
<span class="hljs-keyword" style="color: #a626a4;">val</span> statusMap = ArrayList<String>()
statusMap.add(CREATE)
statusMap.add(WORK)
statusMap.add(CLEAN)
sequentialStatusMap = statusMap
}
<span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">startFlow</span><span class="hljs-params">()</span></span> {
onStateChanged(metaDataModel!!.state!!)
}
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">onStateChanged</span><span class="hljs-params">(state: <span class="hljs-type" style="color: #986801;">String</span>)</span></span> {
metaDataModel!!.state = state
<span class="hljs-keyword" style="color: #a626a4;">when</span> (state) {
CREATE -> {
<span class="hljs-keyword" style="color: #a626a4;">val</span> createWorkItem = CreateWorkItem(metaDataModel!!)
createProcess!!.queueWorkItem(createWorkItem)
}
WORK -> {
<span class="hljs-keyword" style="color: #a626a4;">val</span> workWorkItem = WorkWorkItem(metaDataModel!!)
workProcess!!.queueWorkItem(workWorkItem)
}
CLEAN -> {
<span class="hljs-keyword" style="color: #a626a4;">val</span> cleanWorkItem = CleanWorkItem(metaDataModel!!)
cleanProcess!!.queueWorkItem(cleanWorkItem)
}
<span class="hljs-keyword" style="color: #a626a4;">else</span> -> Log.e(TAG, <span class="hljs-string" style="color: #50a14f;">"error of the flow, something went wrong"</span>)
}
queueFlowListener.onWorkItemStateChange(metaDataModel!!)
}
<span class="hljs-keyword" style="color: #a626a4;">override</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">onJobComplete</span><span class="hljs-params">(workItem: <span class="hljs-type" style="color: #986801;">BaseWorkItem</span>)</span></span> {
<span class="hljs-keyword" style="color: #a626a4;">val</span> currentState = workItem.metadata.state
<span class="hljs-keyword" style="color: #a626a4;">val</span> nextStateIndex = sequentialStatusMap!!.indexOf(currentState)
<span class="hljs-keyword" style="color: #a626a4;">val</span> nextState = sequentialStatusMap!![nextStateIndex + <span class="hljs-number" style="color: #986801;">1</span>]
onStateChanged(nextState)
}
<span class="hljs-keyword" style="color: #a626a4;">override</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">onJobFailed</span><span class="hljs-params">(e: <span class="hljs-type" style="color: #986801;">Exception</span>, workItem: <span class="hljs-type" style="color: #986801;">BaseWorkItem</span>)</span></span> {
workItem.metadata.statusReason = e.message
workItem.metadata.stateBeforeFail = workItem.metadata.state
}
<span class="hljs-keyword" style="color: #a626a4;">companion</span> <span class="hljs-keyword" style="color: #a626a4;">object</span> {
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-keyword" style="color: #a626a4;">val</span> TAG : String? = QueueFlowManager::<span class="hljs-class"><span class="hljs-keyword" style="color: #a626a4;">class</span>.<span class="hljs-title" style="color: #c18401;">java</span>.<span class="hljs-title" style="color: #c18401;">simpleName</span></span>
<span class="hljs-keyword" style="color: #a626a4;">val</span> SECONDS_IN_ONE_PROCESS : <span class="hljs-built_in" style="color: #c18401;">Long</span>? = <span class="hljs-number" style="color: #986801;">5</span> * <span class="hljs-number" style="color: #986801;">1000</span>
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-keyword" style="color: #a626a4;">var</span> sequentialStatusMap: List<String>? = <span class="hljs-literal" style="color: #0184bb;">null</span>
}
}</code></pre>
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">В init мы прописываем все процессы которые у нас будут и подписываемся на их коллбеки, что бы по результату получать какой-то фидбек и стартовать новый процесс.</span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">— makeSequentialStatusMap — мы создаем список в который задаем все процессы которые мы будем запускать. </span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">— onStateChanged — изменяет текущий стейт в модели которая у нас является текущей для работы с очередью. В нем же по порядку, в зависимости от полученного стейта запускается нужный процесс. Далее вызывается onWorkItemStateChange для отправки колбека о текущем стейте в активити.</span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">— onJobComplete — мы получаем текущий стейт, увеличиваем его индекс и запускаем следующий стейт в работу.</span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">— onJobFailed — записываем ошибки с которой упала очередь и стейт на котором оно упало.</span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">— startFlow — запускает флоу с последнего который ему задали в onStateChange.</span><br />
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">activity_main.xml</span><br />
<pre style="background-color: white; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow: auto hidden; padding: 0px; word-break: break-all;"><code class="xml hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-meta" style="color: #4078f2;"><?xml version="1.0" encoding="utf-8"?></span>
<span class="hljs-tag"><<span class="hljs-name" style="color: #e45649;">LinearLayout</span>
<span class="hljs-attr" style="color: #986801;">xmlns:android</span>=<span class="hljs-string" style="color: #50a14f;">"http://schemas.android.com/apk/res/android"</span>
<span class="hljs-attr" style="color: #986801;">xmlns:tools</span>=<span class="hljs-string" style="color: #50a14f;">"http://schemas.android.com/tools"</span>
<span class="hljs-attr" style="color: #986801;">android:layout_width</span>=<span class="hljs-string" style="color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="color: #986801;">android:layout_height</span>=<span class="hljs-string" style="color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="color: #986801;">tools:context</span>=<span class="hljs-string" style="color: #50a14f;">".MainActivity"</span>
<span class="hljs-attr" style="color: #986801;">android:gravity</span>=<span class="hljs-string" style="color: #50a14f;">"center"</span>
<span class="hljs-attr" style="color: #986801;">android:orientation</span>=<span class="hljs-string" style="color: #50a14f;">"vertical"</span>></span>
<span class="hljs-tag"><<span class="hljs-name" style="color: #e45649;">TextView</span>
<span class="hljs-attr" style="color: #986801;">android:layout_width</span>=<span class="hljs-string" style="color: #50a14f;">"wrap_content"</span>
<span class="hljs-attr" style="color: #986801;">android:layout_height</span>=<span class="hljs-string" style="color: #50a14f;">"wrap_content"</span>
<span class="hljs-attr" style="color: #986801;">android:id</span>=<span class="hljs-string" style="color: #50a14f;">"@+id/timer"</span>
<span class="hljs-attr" style="color: #986801;">android:textColor</span>=<span class="hljs-string" style="color: #50a14f;">"@android:color/black"</span>/></span>
<span class="hljs-tag"><<span class="hljs-name" style="color: #e45649;">TextView</span>
<span class="hljs-attr" style="color: #986801;">android:id</span>=<span class="hljs-string" style="color: #50a14f;">"@+id/text"</span>
<span class="hljs-attr" style="color: #986801;">android:layout_width</span>=<span class="hljs-string" style="color: #50a14f;">"wrap_content"</span>
<span class="hljs-attr" style="color: #986801;">android:layout_height</span>=<span class="hljs-string" style="color: #50a14f;">"wrap_content"</span>
<span class="hljs-attr" style="color: #986801;">android:textColor</span>=<span class="hljs-string" style="color: #50a14f;">"@android:color/black"</span>
<span class="hljs-attr" style="color: #986801;">android:textSize</span>=<span class="hljs-string" style="color: #50a14f;">"24sp"</span>/></span>
<span class="hljs-tag"><<span class="hljs-name" style="color: #e45649;">Button</span>
<span class="hljs-attr" style="color: #986801;">android:text</span>=<span class="hljs-string" style="color: #50a14f;">"Start"</span>
<span class="hljs-attr" style="color: #986801;">android:layout_width</span>=<span class="hljs-string" style="color: #50a14f;">"wrap_content"</span>
<span class="hljs-attr" style="color: #986801;">android:layout_height</span>=<span class="hljs-string" style="color: #50a14f;">"wrap_content"</span>
<span class="hljs-attr" style="color: #986801;">android:id</span>=<span class="hljs-string" style="color: #50a14f;">"@+id/startButton"</span>/></span>
<span class="hljs-tag"></<span class="hljs-name" style="color: #e45649;">LinearLayout</span>></span></code></pre>
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Вот так будет выглядеть наш леяут, на нем будет три элемента, два текстовых поля и одна кнопка, по нажатию на которую мы будем стартовать нашу очередь.</span><br />
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">MainActivity.kt</span><br />
<pre style="background-color: white; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow: auto hidden; padding: 0px; word-break: break-all;"><code class="kotlin hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="color: #a626a4;">import</span> android.os.Bundle
<span class="hljs-keyword" style="color: #a626a4;">import</span> android.os.CountDownTimer
<span class="hljs-keyword" style="color: #a626a4;">import</span> android.view.View
<span class="hljs-keyword" style="color: #a626a4;">import</span> androidx.appcompat.app.AppCompatActivity
<span class="hljs-keyword" style="color: #a626a4;">import</span> dajver.com.taskqueueexample.models.MetaDataModel
<span class="hljs-keyword" style="color: #a626a4;">import</span> dajver.com.taskqueueexample.queue.enums.Statuses
<span class="hljs-keyword" style="color: #a626a4;">import</span> dajver.com.taskqueueexample.queue.flow.QueueFlowListener
<span class="hljs-keyword" style="color: #a626a4;">import</span> dajver.com.taskqueueexample.queue.flow.QueueFlowManager
<span class="hljs-keyword" style="color: #a626a4;">import</span> kotlinx.android.synthetic.main.activity_main.*
<span class="hljs-keyword" style="color: #a626a4;">import</span> java.util.concurrent.TimeUnit
<span class="hljs-class"><span class="hljs-keyword" style="color: #a626a4;">class</span> <span class="hljs-title" style="color: #c18401;">MainActivity</span> : <span class="hljs-type" style="color: #986801;">AppCompatActivity</span></span>(), QueueFlowListener {
<span class="hljs-keyword" style="color: #a626a4;">override</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">onCreate</span><span class="hljs-params">(savedInstanceState: <span class="hljs-type" style="color: #986801;">Bundle</span>?)</span></span> {
<span class="hljs-keyword" style="color: #a626a4;">super</span>.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
startButton.setOnClickListener {
QueueFlowManager(<span class="hljs-keyword" style="color: #a626a4;">this</span>).startFlow()
}
}
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-keyword" style="color: #a626a4;">val</span> countDownTimer = <span class="hljs-keyword" style="color: #a626a4;">object</span> : CountDownTimer(<span class="hljs-number" style="color: #986801;">6000</span>, <span class="hljs-number" style="color: #986801;">1000</span>) {
<span class="hljs-keyword" style="color: #a626a4;">override</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">onTick</span><span class="hljs-params">(millisUntilFinished: <span class="hljs-type" style="color: #986801;">Long</span>)</span></span> {
<span class="hljs-keyword" style="color: #a626a4;">val</span> convertedTime = TimeUnit.MILLISECONDS.toSeconds(millisUntilFinished).toString()
timer.text = <span class="hljs-string" style="color: #50a14f;">"Time left to next state: <span class="hljs-variable" style="color: #986801;">$convertedTime</span>"</span>
}
<span class="hljs-keyword" style="color: #a626a4;">override</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">onFinish</span><span class="hljs-params">()</span></span> { }
}
<span class="hljs-keyword" style="color: #a626a4;">override</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">onWorkItemStateChange</span><span class="hljs-params">(metaDataModel: <span class="hljs-type" style="color: #986801;">MetaDataModel</span>)</span></span> {
text.text = <span class="hljs-string" style="color: #50a14f;">"Current state of queue: <span class="hljs-subst" style="color: #e45649;">${metaDataModel.state}</span>"</span>
startButton.visibility = <span class="hljs-keyword" style="color: #a626a4;">if</span>(metaDataModel.state == Statuses.CLEAN) View.VISIBLE <span class="hljs-keyword" style="color: #a626a4;">else</span> View.INVISIBLE
<span class="hljs-keyword" style="color: #a626a4;">if</span>(metaDataModel.state != Statuses.CLEAN) {
countDownTimer.start()
}
}
}</code></pre>
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Из самого важного что я могу отметить в данной активити — это onCreate в котором по нажатию на кнопку мы стартуем очередь. В onWorkItemStateChange мы отображаем стейт и рестартуем таймер каждый раз когда меняется стейт процесса. countDownTimer — нужен чисто для визуального понимания через сколько запустится новый процесс в очереди. Ну и в onTick в countDownTimer'e мы обновляем текстовое поле которое касается таймера.</span><br />
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Вот такая штука эта очередь, надеюсь кому-то это будет полезно и когда нибудь пригодится, я лично с этим столкнулся и долго мучался что бы правильно это реализовать, как практика показала такой способ очень удобный и стабильный, очередь работает как часы, добавление нового элемента в очередь не составит никакого труда так как архитектура построена на принципе SOLID — каждый класс ответственнен за выполнение одного действия.</span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;"><br /></span>
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif;"><b><span style="font-size: large;">Исходники:</span></b></span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif;"><b><span style="font-size: large;"><a href="https://github.com/dajver/QueueFlowExample">GitHub</a></span></b></span></div>
dajverhttp://www.blogger.com/profile/09427222798699404442noreply@blogger.com0tag:blogger.com,1999:blog-5677605911484164185.post-27809653698691913492019-07-19T22:27:00.002+03:002019-07-25T19:40:01.106+03:00Запись экрана с помощью фонового сервиса.<div dir="ltr" style="text-align: left;" trbidi="on">
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Бывют такие не типичные задачи, когда нужно на пример записывать экран смартфона, то что там происходит, паузить, резюмить и останавливать запись. Записывать это все в видео файл, и дальше уже выполнять над ним какие-то действия.</span><br />
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Данный функционал требует нескольких этапов для старта записи. Первый этап — это старт сервиса который проверяет есть ли перманентный доступ на запись, если его нету, то мы переходим ко второму этапу — это запрашиваем доступ на запись, если пользователь дает доступ на запись, тогда мы переходим на третий этап — мы начинаем запись. Это такой небольшой алгоритм который будет при вызове метода startRecording.</span><br />
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Наше приложение будет представлять из себя один экран с кнопкой по нажатию на которую мы будем запускать наш сервис по записи экрана, после повторной записи мы будем останавливать запись и отображать нотфикейшн который будет по клику запускать видео что бы его можно было просмотреть.</span><br />
<br />
<div style="text-align: center;">
<img alt="image" height="91" src="https://github.com/dajver/RecordScreenExample/blob/master/images/notification.png?raw=true" style="background-color: white; border-style: none; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px; height: auto; margin: 0px; max-width: 100%; vertical-align: middle;" width="400" /></div>
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Наш сервис будет сам по себе отдельным модулем который можно просто перенести в любой другой проект, и он будет независимо выполнять свою функцию. Для начала нам нужно будет создать сервис который мы будем вызывать из хелпера, котороый в свою очередь будет вызывать диалог с вопросом можно ли записывать экран, и после получения разрешения начнет записывать. Так же можно расширить функционал и добавить <a href="http://dajver.blogspot.com/2015/10/messanger.html">сервис с плавающей кнопкой</a> по нажатию на которую будет останавливаться запись или какие-то другие действия.</span><br />
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Вот такой у нас будет флоу действия. Теперь можно приступать к разработке. И начнем мы с сервиса который будет производить запись экрана. Но для начала нам нужно создать несколько листенеров которые будут кидать колбеки в хелперов и получать их обратно.</span><br />
<a href="https://www.blogger.com/null" name="habracut" style="background-color: white; color: #548eaa; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;"></a><br />
<a name='more'></a><br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Давайте посмотрим какаие библиотеки мы будем использовать в gradle файле.</span><br />
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">app/build.gradle</span><br />
<pre style="background-color: white; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow: auto hidden; padding: 0px; word-break: break-all;"><code class="java hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;">dependencies {
implementation <span class="hljs-string" style="color: #50a14f;">'androidx.appcompat:appcompat:1.0.2'</span>
implementation <span class="hljs-string" style="color: #50a14f;">'com.karumi:dexter:5.0.0'</span>
}</code></pre>
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Всего лишь два, как оказалось, ой как же это удивительно. </span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">— appcompat — нужен для использования всех прелестей androidX.</span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">— dexter — для того что бы спросить пользователя дать пермишены на запись экрана и запись и тение файлов.</span><br />
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Дальше нам нужно будет создать пару листенеров которые нам будут нужны чуть папизже.</span><br />
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">RecordingPermissionListener.kt</span><br />
<pre style="background-color: white; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow: auto hidden; padding: 0px; word-break: break-all;"><code class="kotlin hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-class"><span class="hljs-keyword" style="color: #a626a4;">interface</span> <span class="hljs-title" style="color: #c18401;">RecordingPermissionListener</span> </span>{
<span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">onPermissionGranted</span><span class="hljs-params">()</span></span>
<span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">onPermissionDenied</span><span class="hljs-params">()</span></span>
}
</code></pre>
<br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">RecordListener.kt</span><br />
<pre style="background-color: white; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow: auto hidden; padding: 0px; word-break: break-all;"><code class="kotlin hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-class"><span class="hljs-keyword" style="color: #a626a4;">interface</span> <span class="hljs-title" style="color: #c18401;">RecordListener</span> </span>{
<span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">onStartRecording</span><span class="hljs-params">()</span></span>
<span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">onStopRecording</span><span class="hljs-params">()</span></span>
}
</code></pre>
<br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">StopRecordingListener.kt</span><br />
<pre style="background-color: white; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow: auto hidden; padding: 0px; word-break: break-all;"><code class="kotlin hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-class"><span class="hljs-keyword" style="color: #a626a4;">interface</span> <span class="hljs-title" style="color: #c18401;">StopRecordingListener</span> </span>{
<span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">onStopRecording</span><span class="hljs-params">()</span></span>
<span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">onSystemStopRecording</span><span class="hljs-params">()</span></span>
}</code></pre>
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Эти три интерфейса будут встречаться нам очень часто в этой статье, они будут использоваться почти в каждом классе который относится к записи экрана. Они будут передавать в наши хелперы и менеджеры нужные состояния.</span><br />
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">RecordService.kt</span><br />
<pre style="background-color: white; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow: auto hidden; padding: 0px; word-break: break-all;"><code class="kotlin hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="color: #a626a4;">import</span> android.app.Service
<span class="hljs-keyword" style="color: #a626a4;">import</span> android.content.Context
<span class="hljs-keyword" style="color: #a626a4;">import</span> android.content.Intent
<span class="hljs-keyword" style="color: #a626a4;">import</span> android.os.Binder
<span class="hljs-keyword" style="color: #a626a4;">import</span> android.os.IBinder
<span class="hljs-keyword" style="color: #a626a4;">import</span> dajver.com.recordscreenexample.recorder.activity.RequestMediaProjectionActivity
<span class="hljs-keyword" style="color: #a626a4;">import</span> dajver.com.recordscreenexample.recorder.helpers.ScreenRecorderHelper
<span class="hljs-keyword" style="color: #a626a4;">import</span> dajver.com.recordscreenexample.recorder.service.listeners.RecordListener
<span class="hljs-keyword" style="color: #a626a4;">import</span> dajver.com.recordscreenexample.recorder.service.listeners.RecordingPermissionListener
<span class="hljs-keyword" style="color: #a626a4;">import</span> dajver.com.recordscreenexample.recorder.service.listeners.StopRecordingListener
<span class="hljs-keyword" style="color: #a626a4;">import</span> java.io.File
<span class="hljs-keyword" style="color: #a626a4;">import</span> java.io.IOException
<span class="hljs-class"><span class="hljs-keyword" style="color: #a626a4;">class</span> <span class="hljs-title" style="color: #c18401;">RecordService</span> : <span class="hljs-type" style="color: #986801;">Service</span></span>(), RecordListener {
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-keyword" style="color: #a626a4;">var</span> mStartRecordingListener: RecordingPermissionListener? = <span class="hljs-literal" style="color: #0184bb;">null</span>
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-keyword" style="color: #a626a4;">var</span> mStopRecordingListener: StopRecordingListener? = <span class="hljs-literal" style="color: #0184bb;">null</span>
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-keyword" style="color: #a626a4;">var</span> mSystemStopRecordingListener: StopRecordingListener? = <span class="hljs-literal" style="color: #0184bb;">null</span>
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-keyword" style="color: #a626a4;">var</span> mScreenRecorderHelper: ScreenRecorderHelper? = <span class="hljs-literal" style="color: #0184bb;">null</span>
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-keyword" style="color: #a626a4;">val</span> mIBinder = RecordServiceBinder()
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-keyword" style="color: #a626a4;">val</span> isRecording: <span class="hljs-built_in" style="color: #c18401;">Boolean</span> <span class="hljs-keyword" style="color: #a626a4;">get</span>() = mScreenRecorderHelper!!.isRecording
<span class="hljs-keyword" style="color: #a626a4;">override</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">onCreate</span><span class="hljs-params">()</span></span> {
<span class="hljs-keyword" style="color: #a626a4;">super</span>.onCreate()
mScreenRecorderHelper = ScreenRecorderHelper(<span class="hljs-keyword" style="color: #a626a4;">this</span>)
mScreenRecorderHelper!!.setRecordListener(<span class="hljs-keyword" style="color: #a626a4;">this</span>)
}
<span class="hljs-keyword" style="color: #a626a4;">override</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">onDestroy</span><span class="hljs-params">()</span></span> {
mScreenRecorderHelper!!.setRecordListener(<span class="hljs-literal" style="color: #0184bb;">null</span>)
mScreenRecorderHelper!!.release()
<span class="hljs-keyword" style="color: #a626a4;">super</span>.onDestroy()
}
<span class="hljs-keyword" style="color: #a626a4;">override</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">onStartCommand</span><span class="hljs-params">(intent: <span class="hljs-type" style="color: #986801;">Intent</span>?, flags: <span class="hljs-type" style="color: #986801;">Int</span>, startId: <span class="hljs-type" style="color: #986801;">Int</span>)</span></span>: <span class="hljs-built_in" style="color: #c18401;">Int</span> {
<span class="hljs-keyword" style="color: #a626a4;">if</span> (intent != <span class="hljs-literal" style="color: #0184bb;">null</span> && intent.hasExtra(ACTION_CODE_EXTRA_DATA)) {
<span class="hljs-keyword" style="color: #a626a4;">when</span> (intent.getIntExtra(ACTION_CODE_EXTRA_DATA, -<span class="hljs-number" style="color: #986801;">1</span>)) {
ACTION_START_RECORDING -> onActionStartRecording(intent)
ACTION_STOP_RECORDING -> onActionStopRecording()
}
}
<span class="hljs-keyword" style="color: #a626a4;">return</span> START_STICKY
}
<span class="hljs-keyword" style="color: #a626a4;">override</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">onBind</span><span class="hljs-params">(intent: <span class="hljs-type" style="color: #986801;">Intent</span>)</span></span>: IBinder? {
<span class="hljs-keyword" style="color: #a626a4;">return</span> mIBinder
}
<span class="hljs-keyword" style="color: #a626a4;">override</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">onUnbind</span><span class="hljs-params">(intent: <span class="hljs-type" style="color: #986801;">Intent</span>)</span></span>: <span class="hljs-built_in" style="color: #c18401;">Boolean</span> {
stopThis()
<span class="hljs-keyword" style="color: #a626a4;">return</span> <span class="hljs-keyword" style="color: #a626a4;">super</span>.onUnbind(intent)
}
<span class="hljs-keyword" style="color: #a626a4;">override</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">onStartRecording</span><span class="hljs-params">()</span></span> {
<span class="hljs-keyword" style="color: #a626a4;">if</span> (mStartRecordingListener != <span class="hljs-literal" style="color: #0184bb;">null</span>)
mStartRecordingListener!!.onPermissionGranted()
}
<span class="hljs-keyword" style="color: #a626a4;">override</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">onStopRecording</span><span class="hljs-params">()</span></span> {
<span class="hljs-keyword" style="color: #a626a4;">if</span> (mStopRecordingListener != <span class="hljs-literal" style="color: #0184bb;">null</span>) {
mStopRecordingListener!!.onStopRecording()
stopThis()
} <span class="hljs-keyword" style="color: #a626a4;">else</span> <span class="hljs-keyword" style="color: #a626a4;">if</span> (mSystemStopRecordingListener != <span class="hljs-literal" style="color: #0184bb;">null</span>) {
mSystemStopRecordingListener!!.onSystemStopRecording()
stopThis()
}
}
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">onActionStartRecording</span><span class="hljs-params">(intent: <span class="hljs-type" style="color: #986801;">Intent</span>)</span></span> {
<span class="hljs-keyword" style="color: #a626a4;">if</span> (!intent.hasExtra(OUTPUT_FILE_PATH_EXTRA_DATA)) {
<span class="hljs-keyword" style="color: #a626a4;">return</span>
}
<span class="hljs-keyword" style="color: #a626a4;">if</span> (intent.hasExtra(STATE_RESULT_CODE) && intent.hasExtra(STATE_RESULT_DATA)) {
<span class="hljs-keyword" style="color: #a626a4;">val</span> resultCode = intent.getIntExtra(STATE_RESULT_CODE, <span class="hljs-number" style="color: #986801;">0</span>)
<span class="hljs-keyword" style="color: #a626a4;">val</span> resultData = intent.getParcelableExtra<Intent>(STATE_RESULT_DATA)
<span class="hljs-comment" style="color: #a0a1a7; font-style: italic;">// Checking the action from the user, Granted or Denied permission</span>
<span class="hljs-keyword" style="color: #a626a4;">if</span> (!mScreenRecorderHelper!!.onScreenRecordPermissionResult(resultCode, resultData)) {
<span class="hljs-keyword" style="color: #a626a4;">if</span> (mStartRecordingListener != <span class="hljs-literal" style="color: #0184bb;">null</span>)
mStartRecordingListener!!.onPermissionDenied()
stopThis()
<span class="hljs-keyword" style="color: #a626a4;">return</span>
}
}
startRecording(intent.getStringExtra(OUTPUT_FILE_PATH_EXTRA_DATA))
}
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">onActionStopRecording</span><span class="hljs-params">()</span></span> {
stopRecording()
}
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">startRecording</span><span class="hljs-params">(outputFilePath: <span class="hljs-type" style="color: #986801;">String</span>?)</span></span> {
<span class="hljs-keyword" style="color: #a626a4;">if</span> (hasScreenRecordPermission()) {
<span class="hljs-keyword" style="color: #a626a4;">try</span> {
mScreenRecorderHelper!!.startRecording(File(outputFilePath!!))
} <span class="hljs-keyword" style="color: #a626a4;">catch</span> (e: IOException) {
e.printStackTrace()
stopThis()
} <span class="hljs-keyword" style="color: #a626a4;">catch</span> (ignore: IllegalStateException) { }
} <span class="hljs-keyword" style="color: #a626a4;">else</span> {
<span class="hljs-comment" style="color: #a0a1a7; font-style: italic;">// Requesting media projection</span>
requestPermission(outputFilePath)
}
}
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">stopRecording</span><span class="hljs-params">()</span></span> {
mScreenRecorderHelper!!.stopRecording()
}
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">hasScreenRecordPermission</span><span class="hljs-params">()</span></span>: <span class="hljs-built_in" style="color: #c18401;">Boolean</span> {
<span class="hljs-keyword" style="color: #a626a4;">return</span> mScreenRecorderHelper!!.hasScreenRecordPermission()
}
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">requestPermission</span><span class="hljs-params">(outputFilePath: <span class="hljs-type" style="color: #986801;">String</span>?)</span></span> {
<span class="hljs-comment" style="color: #a0a1a7; font-style: italic;">// Requesting media projection</span>
startActivity(RequestMediaProjectionActivity.createIntent(<span class="hljs-keyword" style="color: #a626a4;">this</span><span class="hljs-symbol" style="color: #4078f2;">@RecordService</span>, ACTION_START_RECORDING, outputFilePath!!))
}
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">stopThis</span><span class="hljs-params">()</span></span> {
stopForeground(<span class="hljs-literal" style="color: #0184bb;">true</span>)
stopSelf()
}
<span class="hljs-keyword" style="color: #a626a4;">inner</span> <span class="hljs-class"><span class="hljs-keyword" style="color: #a626a4;">class</span> <span class="hljs-title" style="color: #c18401;">RecordServiceBinder</span> : <span class="hljs-type" style="color: #986801;">Binder</span></span>() {
<span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">startRecording</span><span class="hljs-params">(outputFilePath: <span class="hljs-type" style="color: #986801;">String</span>, startRecordingListener: <span class="hljs-type" style="color: #986801;">RecordingPermissionListener</span>, stopCurrentIfRecording: <span class="hljs-type" style="color: #986801;">Boolean</span>, systemStopRecordingListener: <span class="hljs-type" style="color: #986801;">StopRecordingListener</span>)</span></span> {
<span class="hljs-keyword" style="color: #a626a4;">if</span> (stopCurrentIfRecording && <span class="hljs-keyword" style="color: #a626a4;">this</span><span class="hljs-symbol" style="color: #4078f2;">@RecordService</span>.isRecording) {
<span class="hljs-keyword" style="color: #a626a4;">this</span><span class="hljs-symbol" style="color: #4078f2;">@RecordService</span>.stopRecording()
}
mStartRecordingListener = startRecordingListener
mSystemStopRecordingListener = systemStopRecordingListener
<span class="hljs-keyword" style="color: #a626a4;">this</span><span class="hljs-symbol" style="color: #4078f2;">@RecordService</span>.startRecording(outputFilePath)
}
<span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">stopRecording</span><span class="hljs-params">(listener: <span class="hljs-type" style="color: #986801;">StopRecordingListener</span>)</span></span> {
mStopRecordingListener = listener
<span class="hljs-keyword" style="color: #a626a4;">this</span><span class="hljs-symbol" style="color: #4078f2;">@RecordService</span>.stopRecording()
}
}
<span class="hljs-keyword" style="color: #a626a4;">companion</span> <span class="hljs-keyword" style="color: #a626a4;">object</span> {
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-keyword" style="color: #a626a4;">const</span> <span class="hljs-keyword" style="color: #a626a4;">val</span> STATE_RESULT_CODE = <span class="hljs-string" style="color: #50a14f;">"result_code"</span>
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-keyword" style="color: #a626a4;">const</span> <span class="hljs-keyword" style="color: #a626a4;">val</span> STATE_RESULT_DATA = <span class="hljs-string" style="color: #50a14f;">"result_data"</span>
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-keyword" style="color: #a626a4;">const</span> <span class="hljs-keyword" style="color: #a626a4;">val</span> OUTPUT_FILE_PATH_EXTRA_DATA = <span class="hljs-string" style="color: #50a14f;">"output_file_path"</span>
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-keyword" style="color: #a626a4;">const</span> <span class="hljs-keyword" style="color: #a626a4;">val</span> ACTION_CODE_EXTRA_DATA = <span class="hljs-string" style="color: #50a14f;">"action_code"</span>
<span class="hljs-keyword" style="color: #a626a4;">const</span> <span class="hljs-keyword" style="color: #a626a4;">val</span> ACTION_START_RECORDING = <span class="hljs-number" style="color: #986801;">0</span>
<span class="hljs-keyword" style="color: #a626a4;">const</span> <span class="hljs-keyword" style="color: #a626a4;">val</span> ACTION_STOP_RECORDING = <span class="hljs-number" style="color: #986801;">1</span>
<span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">createIntent</span><span class="hljs-params">(context: <span class="hljs-type" style="color: #986801;">Context</span>, actionCode: <span class="hljs-type" style="color: #986801;">Int</span>, outputFilePath: <span class="hljs-type" style="color: #986801;">String</span>, resultCode: <span class="hljs-type" style="color: #986801;">Int</span>, resultData: <span class="hljs-type" style="color: #986801;">Intent</span>)</span></span>: Intent {
<span class="hljs-keyword" style="color: #a626a4;">val</span> intent = Intent(context, RecordService::<span class="hljs-class"><span class="hljs-keyword" style="color: #a626a4;">class</span>.<span class="hljs-title" style="color: #c18401;">java</span>)</span>
intent.putExtra(ACTION_CODE_EXTRA_DATA, actionCode)
intent.putExtra(OUTPUT_FILE_PATH_EXTRA_DATA, outputFilePath)
intent.putExtra(STATE_RESULT_CODE, resultCode)
intent.putExtra(STATE_RESULT_DATA, resultData)
<span class="hljs-keyword" style="color: #a626a4;">return</span> intent
}
}
}</code></pre>
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Данный сервис довольно типичный. Нас интересует в данном сервисе один класс и один метод.</span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">— onStartCommand — выполняет запуск старта записи и остановки записи.</span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">— RecordServiceBinder — класс через который будет выполнятся запуск или останвока записи, его мы будем вызывать из другого класса-хелпера который будет оборачивать в себе все нужные функции для старта и стопа записи.</span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Остальные методы выполняют функционал создания записи или остановки, вызов диалога с запросом на запись и так далее… Названия говорят сами за себя.</span><br />
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Далее нам нужно создать активити которая будет показывать диалог с вопросом можно ли записывать.</span><br />
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">RequestMediaProjectionActivity.kt</span><br />
<pre style="background-color: white; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow: auto hidden; padding: 0px; word-break: break-all;"><code class="kotlin hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="color: #a626a4;">import</span> android.content.Context
<span class="hljs-keyword" style="color: #a626a4;">import</span> android.content.Intent
<span class="hljs-keyword" style="color: #a626a4;">import</span> android.media.projection.MediaProjectionManager
<span class="hljs-keyword" style="color: #a626a4;">import</span> androidx.appcompat.app.AppCompatActivity
<span class="hljs-keyword" style="color: #a626a4;">import</span> dajver.com.recordscreenexample.recorder.service.RecordService
<span class="hljs-class"><span class="hljs-keyword" style="color: #a626a4;">class</span> <span class="hljs-title" style="color: #c18401;">RequestMediaProjectionActivity</span> : <span class="hljs-type" style="color: #986801;">AppCompatActivity</span></span>() {
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-keyword" style="color: #a626a4;">var</span> mRequestMediaProjection = <span class="hljs-literal" style="color: #0184bb;">true</span>
<span class="hljs-keyword" style="color: #a626a4;">override</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">onActivityResult</span><span class="hljs-params">(requestCode: <span class="hljs-type" style="color: #986801;">Int</span>, resultCode: <span class="hljs-type" style="color: #986801;">Int</span>, <span class="hljs-keyword" style="color: #a626a4;">data</span>: <span class="hljs-type" style="color: #986801;">Intent</span>?)</span></span> {
<span class="hljs-keyword" style="color: #a626a4;">if</span> (requestCode == REQUEST_MEDIA_PROJECTION_CODE) {
mRequestMediaProjection = <span class="hljs-literal" style="color: #0184bb;">false</span>
startService(RecordService.createIntent(<span class="hljs-keyword" style="color: #a626a4;">this</span>,
intent.getIntExtra(ACTION_CODE_EXTRA_DATA, -<span class="hljs-number" style="color: #986801;">1</span>),
intent.getStringExtra(OUTPUT_FILE_PATH_EXTRA_DATA)!!,
resultCode, <span class="hljs-keyword" style="color: #a626a4;">data</span>!!
)
)
finishAndRemoveTask()
}
<span class="hljs-keyword" style="color: #a626a4;">super</span>.onActivityResult(requestCode, resultCode, <span class="hljs-keyword" style="color: #a626a4;">data</span>)
}
<span class="hljs-keyword" style="color: #a626a4;">override</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">onResume</span><span class="hljs-params">()</span></span> {
<span class="hljs-keyword" style="color: #a626a4;">super</span>.onResume()
<span class="hljs-keyword" style="color: #a626a4;">if</span> (mRequestMediaProjection) {
requestScreenRecordPermission()
} <span class="hljs-keyword" style="color: #a626a4;">else</span> {
finishAndRemoveTask()
}
}
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">requestScreenRecordPermission</span><span class="hljs-params">()</span></span> {
<span class="hljs-keyword" style="color: #a626a4;">val</span> mediaProjectionManager = getSystemService(Context.MEDIA_PROJECTION_SERVICE) <span class="hljs-keyword" style="color: #a626a4;">as</span> MediaProjectionManager
<span class="hljs-keyword" style="color: #a626a4;">if</span> (mediaProjectionManager != <span class="hljs-literal" style="color: #0184bb;">null</span>) {
startActivityForResult(
mediaProjectionManager.createScreenCaptureIntent(),
REQUEST_MEDIA_PROJECTION_CODE
)
}
}
<span class="hljs-keyword" style="color: #a626a4;">companion</span> <span class="hljs-keyword" style="color: #a626a4;">object</span> {
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-keyword" style="color: #a626a4;">const</span> <span class="hljs-keyword" style="color: #a626a4;">val</span> REQUEST_MEDIA_PROJECTION_CODE = <span class="hljs-number" style="color: #986801;">613</span>
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-keyword" style="color: #a626a4;">const</span> <span class="hljs-keyword" style="color: #a626a4;">val</span> ACTION_CODE_EXTRA_DATA = <span class="hljs-string" style="color: #50a14f;">"action_code"</span>
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-keyword" style="color: #a626a4;">const</span> <span class="hljs-keyword" style="color: #a626a4;">val</span> OUTPUT_FILE_PATH_EXTRA_DATA = <span class="hljs-string" style="color: #50a14f;">"output_file_path"</span>
<span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">createIntent</span><span class="hljs-params">(context: <span class="hljs-type" style="color: #986801;">Context</span>, actionCode: <span class="hljs-type" style="color: #986801;">Int</span>, outputFilePath: <span class="hljs-type" style="color: #986801;">String</span>)</span></span>: Intent {
<span class="hljs-keyword" style="color: #a626a4;">val</span> intent = Intent(context, RequestMediaProjectionActivity::<span class="hljs-class"><span class="hljs-keyword" style="color: #a626a4;">class</span>.<span class="hljs-title" style="color: #c18401;">java</span>)</span>
intent.putExtra(ACTION_CODE_EXTRA_DATA, actionCode)
intent.putExtra(OUTPUT_FILE_PATH_EXTRA_DATA, outputFilePath)
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
<span class="hljs-keyword" style="color: #a626a4;">return</span> intent
}
}
}</code></pre>
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Здесь нас интересует так же пара методов, остальные нуны чисто что бы эти пара методов жили так как мы хотим.</span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">— createIntent — метод который вызывает RequestMediaProjectionActivity и задает параметры по которым мы дальше будем создавать видео-файл и передаем код для onActivityResult</span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">— onActivityResult в свою очередь запускает сервис через метод который задает путь файла для записи.</span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">— requestScreenRecordPermission — запрашивает разрашение у пользователя на запись экрана.</span><br />
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Далее нам нужно создать класс который будет создавать инстанс MediaRecorder и работать с этим инстансом для создания собственно видео-файла и последующей записи в него.</span><br />
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">State.kt</span><br />
<pre style="background-color: white; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow: auto hidden; padding: 0px; word-break: break-all;"><code class="kotlin hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="color: #a626a4;">enum</span> <span class="hljs-class"><span class="hljs-keyword" style="color: #a626a4;">class</span> <span class="hljs-title" style="color: #c18401;">State</span> </span>{
INITIAL, RECORDING
}</code></pre>
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Но для начала нам нужно создать енам с нужными нам параметрами для сохранения стейтов записи. Создали, а дальше уже смотрим что из себя представляет наш ScreenRecorder.</span><br />
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">ScreenRecorder.kt</span><br />
<pre style="background-color: white; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow: auto hidden; padding: 0px; word-break: break-all;"><code class="kotlin hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="color: #a626a4;">import</span> android.graphics.Point
<span class="hljs-keyword" style="color: #a626a4;">import</span> android.hardware.display.DisplayManager
<span class="hljs-keyword" style="color: #a626a4;">import</span> android.hardware.display.VirtualDisplay
<span class="hljs-keyword" style="color: #a626a4;">import</span> android.media.MediaRecorder
<span class="hljs-keyword" style="color: #a626a4;">import</span> android.media.projection.MediaProjection
<span class="hljs-keyword" style="color: #a626a4;">import</span> android.util.SparseIntArray
<span class="hljs-keyword" style="color: #a626a4;">import</span> android.view.Surface
<span class="hljs-keyword" style="color: #a626a4;">import</span> android.view.WindowManager
<span class="hljs-keyword" style="color: #a626a4;">import</span> dajver.com.recordscreenexample.recorder.enums.State
<span class="hljs-keyword" style="color: #a626a4;">import</span> java.io.File
<span class="hljs-keyword" style="color: #a626a4;">import</span> java.io.IOException
<span class="hljs-class"><span class="hljs-keyword" style="color: #a626a4;">class</span> <span class="hljs-title" style="color: #c18401;">ScreenRecorder</span> <span class="hljs-keyword" style="color: #a626a4;">internal</span> <span class="hljs-keyword" style="color: #a626a4;">constructor</span></span>(<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-keyword" style="color: #a626a4;">val</span> mWindowManager: WindowManager, <span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-keyword" style="color: #a626a4;">val</span> mScreenDensity: <span class="hljs-built_in" style="color: #c18401;">Int</span>) {
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-keyword" style="color: #a626a4;">val</span> mScreenSize = Point()
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-keyword" style="color: #a626a4;">var</span> mOutputFile: File? = <span class="hljs-literal" style="color: #0184bb;">null</span>
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-keyword" style="color: #a626a4;">var</span> mVirtualDisplay: VirtualDisplay? = <span class="hljs-literal" style="color: #0184bb;">null</span>
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-keyword" style="color: #a626a4;">var</span> mMediaRecorder: MediaRecorder? = <span class="hljs-literal" style="color: #0184bb;">null</span>
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-keyword" style="color: #a626a4;">var</span> mDisplayWidth: <span class="hljs-built_in" style="color: #c18401;">Int</span> = <span class="hljs-number" style="color: #986801;">0</span>
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-keyword" style="color: #a626a4;">var</span> mDisplayHeight: <span class="hljs-built_in" style="color: #c18401;">Int</span> = <span class="hljs-number" style="color: #986801;">0</span>
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-keyword" style="color: #a626a4;">var</span> mVideoBitRate: <span class="hljs-built_in" style="color: #c18401;">Int</span> = <span class="hljs-number" style="color: #986801;">0</span>
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-keyword" style="color: #a626a4;">var</span> mVideoFrameRate: <span class="hljs-built_in" style="color: #c18401;">Int</span> = <span class="hljs-number" style="color: #986801;">0</span>
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-keyword" style="color: #a626a4;">var</span> mState = State.INITIAL
<span class="hljs-keyword" style="color: #a626a4;">val</span> isRecording: <span class="hljs-built_in" style="color: #c18401;">Boolean</span> <span class="hljs-keyword" style="color: #a626a4;">get</span>() = mState == State.RECORDING
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-keyword" style="color: #a626a4;">val</span> displayHeight: <span class="hljs-built_in" style="color: #c18401;">Int</span> <span class="hljs-keyword" style="color: #a626a4;">get</span>() = <span class="hljs-keyword" style="color: #a626a4;">if</span> (mScreenSize.y == <span class="hljs-number" style="color: #986801;">0</span>) mDisplayHeight <span class="hljs-keyword" style="color: #a626a4;">else</span> mScreenSize.y
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-keyword" style="color: #a626a4;">val</span> screenWidth: <span class="hljs-built_in" style="color: #c18401;">Int</span> <span class="hljs-keyword" style="color: #a626a4;">get</span>() = <span class="hljs-keyword" style="color: #a626a4;">if</span> (mScreenSize.x == <span class="hljs-number" style="color: #986801;">0</span>) mDisplayWidth <span class="hljs-keyword" style="color: #a626a4;">else</span> mScreenSize.x
<span class="hljs-keyword" style="color: #a626a4;">init</span> {
mWindowManager.defaultDisplay.getSize(mScreenSize)
setupVideoQualitySettings()
}
<span class="hljs-meta" style="color: #4078f2;">@Throws(IOException::class)</span>
<span class="hljs-keyword" style="color: #a626a4;">internal</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">startRecord</span><span class="hljs-params">(mediaProjection: <span class="hljs-type" style="color: #986801;">MediaProjection</span>, outputFile: <span class="hljs-type" style="color: #986801;">File</span>)</span></span> {
<span class="hljs-comment" style="color: #a0a1a7; font-style: italic;">// Checking the arguments</span>
mOutputFile = outputFile
<span class="hljs-comment" style="color: #a0a1a7; font-style: italic;">// Checking the file</span>
<span class="hljs-keyword" style="color: #a626a4;">if</span> (mOutputFile!!.isDirectory) {
<span class="hljs-keyword" style="color: #a626a4;">throw</span> IllegalArgumentException(<span class="hljs-string" style="color: #50a14f;">"It is a directory not a file!"</span>)
}
<span class="hljs-keyword" style="color: #a626a4;">if</span> (mState != State.INITIAL) {
<span class="hljs-keyword" style="color: #a626a4;">throw</span> IllegalStateException(<span class="hljs-string" style="color: #50a14f;">"You can start recording only on the initial state!"</span>)
}
<span class="hljs-comment" style="color: #a0a1a7; font-style: italic;">// Set up media recorder</span>
mMediaRecorder = MediaRecorder()
initMediaRecorder()
<span class="hljs-comment" style="color: #a0a1a7; font-style: italic;">// Sharing the screen</span>
shareScreen(mediaProjection)
mState = State.RECORDING
}
<span class="hljs-keyword" style="color: #a626a4;">internal</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">stopRecord</span><span class="hljs-params">()</span></span> {
<span class="hljs-keyword" style="color: #a626a4;">if</span> (mState != State.RECORDING) {
<span class="hljs-keyword" style="color: #a626a4;">return</span>
}
<span class="hljs-keyword" style="color: #a626a4;">if</span> (mMediaRecorder == <span class="hljs-literal" style="color: #0184bb;">null</span>)
<span class="hljs-keyword" style="color: #a626a4;">return</span>
<span class="hljs-keyword" style="color: #a626a4;">try</span> {
mMediaRecorder!!.stop()
} <span class="hljs-keyword" style="color: #a626a4;">catch</span> (ignore: RuntimeException) { }
stopScreenSharing()
mMediaRecorder!!.reset()
mMediaRecorder!!.release()
mMediaRecorder = <span class="hljs-literal" style="color: #0184bb;">null</span>
mState = State.INITIAL
}
<span class="hljs-meta" style="color: #4078f2;">@Throws(IOException::class)</span>
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">initMediaRecorder</span><span class="hljs-params">()</span></span> {
mMediaRecorder!!.setVideoSource(MediaRecorder.VideoSource.SURFACE)
mMediaRecorder!!.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4)
mMediaRecorder!!.setOutputFile(mOutputFile!!.path)
mMediaRecorder!!.setVideoSize(mDisplayWidth, mDisplayHeight)
mMediaRecorder!!.setVideoEncoder(MediaRecorder.VideoEncoder.H264)
mMediaRecorder!!.setVideoEncodingBitRate(mVideoBitRate)
mMediaRecorder!!.setVideoFrameRate(mVideoFrameRate)
<span class="hljs-keyword" style="color: #a626a4;">val</span> rotation = mWindowManager.defaultDisplay.rotation
<span class="hljs-keyword" style="color: #a626a4;">val</span> orientation = ORIENTATIONS.<span class="hljs-keyword" style="color: #a626a4;">get</span>(rotation + <span class="hljs-number" style="color: #986801;">90</span>)
mMediaRecorder!!.setOrientationHint(orientation)
mMediaRecorder!!.prepare()
}
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">setupVideoQualitySettings</span><span class="hljs-params">()</span></span> {
mDisplayWidth = <span class="hljs-number" style="color: #986801;">1280</span>
mDisplayHeight = <span class="hljs-number" style="color: #986801;">720</span>
mVideoBitRate = <span class="hljs-number" style="color: #986801;">1600000</span>
mVideoFrameRate = <span class="hljs-number" style="color: #986801;">24</span>
}
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">setUpVirtualDisplay</span><span class="hljs-params">(mediaProjection: <span class="hljs-type" style="color: #986801;">MediaProjection</span>)</span></span> {
mVirtualDisplay = mediaProjection.createVirtualDisplay(<span class="hljs-string" style="color: #50a14f;">"ScreenRecorder"</span>,
mDisplayWidth, mDisplayHeight, mScreenDensity,
DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR,
mMediaRecorder!!.surface, <span class="hljs-literal" style="color: #0184bb;">null</span>, <span class="hljs-literal" style="color: #0184bb;">null</span>
)
}
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">shareScreen</span><span class="hljs-params">(mediaProjection: <span class="hljs-type" style="color: #986801;">MediaProjection</span>)</span></span> {
<span class="hljs-keyword" style="color: #a626a4;">try</span> {
setUpVirtualDisplay(mediaProjection)
mMediaRecorder!!.start()
} <span class="hljs-keyword" style="color: #a626a4;">catch</span> (e: SecurityException) {
e.printStackTrace()
}
}
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">stopScreenSharing</span><span class="hljs-params">()</span></span> {
<span class="hljs-keyword" style="color: #a626a4;">if</span> (mVirtualDisplay != <span class="hljs-literal" style="color: #0184bb;">null</span>) {
mVirtualDisplay!!.release()
mVirtualDisplay = <span class="hljs-literal" style="color: #0184bb;">null</span>
}
}
<span class="hljs-keyword" style="color: #a626a4;">companion</span> <span class="hljs-keyword" style="color: #a626a4;">object</span> {
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-keyword" style="color: #a626a4;">val</span> ORIENTATIONS = SparseIntArray()
<span class="hljs-keyword" style="color: #a626a4;">init</span> {
ORIENTATIONS.append(Surface.ROTATION_0, <span class="hljs-number" style="color: #986801;">90</span>)
ORIENTATIONS.append(Surface.ROTATION_90, <span class="hljs-number" style="color: #986801;">0</span>)
ORIENTATIONS.append(Surface.ROTATION_180, <span class="hljs-number" style="color: #986801;">270</span>)
ORIENTATIONS.append(Surface.ROTATION_270, <span class="hljs-number" style="color: #986801;">180</span>)
}
}
}</code></pre>
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">В инициализации мы задаем ширину экрана какую мы хотим записывать, собствнно берем всю ширину экрана возможную и так же указываем качество которое мы хотим что бы было у записанного видео. Видео будет с шириной 1200 пикселей и с высотой в 720 пикселей, битрейт (частоту записи видео) мы задали 1600000 бит / секунду и фрейм рейт (колиество кадров в секунду) мы задали в 24 к / с.</span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">— initMediaRecorder — этот метод у нас инициализирует и задает важные параметры такие как адрес куда будет писаться видео, с каким качеством, битрейтом, фрейм рейтом и так далее…</span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">— startRecord — у нас создает MediaRecorder, инициализирует его и стартует запись экрана. И в конце ставим стейт что у нас видео записывается.</span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">— stopRecord — останавливаем запись, и ставим стейт что у нас рекордер проинициализирован.</span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">— setUpVirtualDisplay — задает ширину и высоту и создает с ней VirtualDisplay который позволит записать экран.</span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">— shareScreen — начинает запись экрана.</span><br />
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Далее мы создадим отдельный хелпер который будет расширять возможности нашего ScreenRecorder'a, так как сам собственно класс рекордера у нас включает в себя инициализацию и старт / стоп записи. А вот в хелпере мы будем запрашивать возможность записи у пользователя и записывать или не записывать видео в зависимости от решения пользователя.</span><br />
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">ScreenRecorderHelper.kt </span><br />
<pre style="background-color: white; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow: auto hidden; padding: 0px; word-break: break-all;"><code class="kotlin hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="color: #a626a4;">import</span> android.app.Activity
<span class="hljs-keyword" style="color: #a626a4;">import</span> android.content.Context
<span class="hljs-keyword" style="color: #a626a4;">import</span> android.content.Intent
<span class="hljs-keyword" style="color: #a626a4;">import</span> android.media.projection.MediaProjection
<span class="hljs-keyword" style="color: #a626a4;">import</span> android.media.projection.MediaProjectionManager
<span class="hljs-keyword" style="color: #a626a4;">import</span> android.util.DisplayMetrics
<span class="hljs-keyword" style="color: #a626a4;">import</span> android.view.WindowManager
<span class="hljs-keyword" style="color: #a626a4;">import</span> dajver.com.recordscreenexample.recorder.service.listeners.RecordListener
<span class="hljs-keyword" style="color: #a626a4;">import</span> java.io.File
<span class="hljs-keyword" style="color: #a626a4;">import</span> java.io.IOException
<span class="hljs-class"><span class="hljs-keyword" style="color: #a626a4;">class</span> <span class="hljs-title" style="color: #c18401;">ScreenRecorderHelper</span></span>(<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-keyword" style="color: #a626a4;">val</span> mContext: Context) {
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-keyword" style="color: #a626a4;">var</span> isStartCalled = <span class="hljs-literal" style="color: #0184bb;">false</span>
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-keyword" style="color: #a626a4;">var</span> mMediaProjectionManager: MediaProjectionManager? = <span class="hljs-literal" style="color: #0184bb;">null</span>
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-keyword" style="color: #a626a4;">var</span> mMediaProjection: MediaProjection? = <span class="hljs-literal" style="color: #0184bb;">null</span>
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-keyword" style="color: #a626a4;">var</span> mMediaProjectionCallback: MediaProjectionCallback? = <span class="hljs-literal" style="color: #0184bb;">null</span>
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-keyword" style="color: #a626a4;">var</span> mScreenRecorder: ScreenRecorder? = <span class="hljs-literal" style="color: #0184bb;">null</span>
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-keyword" style="color: #a626a4;">var</span> mRecordListener: RecordListener? = <span class="hljs-literal" style="color: #0184bb;">null</span>
<span class="hljs-keyword" style="color: #a626a4;">val</span> isRecording: <span class="hljs-built_in" style="color: #c18401;">Boolean</span> <span class="hljs-keyword" style="color: #a626a4;">get</span>() = screenRecorder.isRecording
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-keyword" style="color: #a626a4;">val</span> screenRecorder: ScreenRecorder
<span class="hljs-keyword" style="color: #a626a4;">get</span>() {
<span class="hljs-keyword" style="color: #a626a4;">if</span> (mScreenRecorder == <span class="hljs-literal" style="color: #0184bb;">null</span>) {
<span class="hljs-keyword" style="color: #a626a4;">val</span> windowManager = mContext.getSystemService(Context.WINDOW_SERVICE) <span class="hljs-keyword" style="color: #a626a4;">as</span> WindowManager
<span class="hljs-keyword" style="color: #a626a4;">val</span> metrics = DisplayMetrics()
windowManager.defaultDisplay.getMetrics(metrics)
mScreenRecorder = ScreenRecorder(windowManager, metrics.densityDpi)
}
<span class="hljs-keyword" style="color: #a626a4;">return</span> mScreenRecorder!!
}
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-keyword" style="color: #a626a4;">val</span> mediaProjectionManager: MediaProjectionManager
<span class="hljs-keyword" style="color: #a626a4;">get</span>() {
<span class="hljs-keyword" style="color: #a626a4;">if</span> (mMediaProjectionManager == <span class="hljs-literal" style="color: #0184bb;">null</span>) {
mMediaProjectionManager = mContext.getSystemService(Context.MEDIA_PROJECTION_SERVICE) <span class="hljs-keyword" style="color: #a626a4;">as</span> MediaProjectionManager
}
<span class="hljs-keyword" style="color: #a626a4;">return</span> mMediaProjectionManager!!
}
<span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">setRecordListener</span><span class="hljs-params">(listener: <span class="hljs-type" style="color: #986801;">RecordListener</span>?)</span></span> {
mRecordListener = listener
}
<span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">release</span><span class="hljs-params">()</span></span> {
<span class="hljs-keyword" style="color: #a626a4;">if</span> (screenRecorder.isRecording) {
stopRecording()
}
tearDownMediaProjection()
}
<span class="hljs-meta" style="color: #4078f2;">@Throws(IOException::class)</span>
<span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">startRecording</span><span class="hljs-params">(outputFile: <span class="hljs-type" style="color: #986801;">File</span>)</span></span> {
<span class="hljs-keyword" style="color: #a626a4;">if</span> (!isStartCalled)
isStartCalled = <span class="hljs-literal" style="color: #0184bb;">true</span>
<span class="hljs-keyword" style="color: #a626a4;">else</span>
<span class="hljs-keyword" style="color: #a626a4;">return</span>
screenRecorder.startRecord(mMediaProjection!!, outputFile)
mRecordListener!!.onStartRecording()
}
<span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">stopRecording</span><span class="hljs-params">()</span></span> {
screenRecorder.stopRecord()
onStopRecording()
}
<span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">hasScreenRecordPermission</span><span class="hljs-params">()</span></span>: <span class="hljs-built_in" style="color: #c18401;">Boolean</span> {
<span class="hljs-keyword" style="color: #a626a4;">return</span> mMediaProjection != <span class="hljs-literal" style="color: #0184bb;">null</span>
}
<span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">onScreenRecordPermissionResult</span><span class="hljs-params">(resultCode: <span class="hljs-type" style="color: #986801;">Int</span>, resultData: <span class="hljs-type" style="color: #986801;">Intent</span>)</span></span>: <span class="hljs-built_in" style="color: #c18401;">Boolean</span> {
<span class="hljs-keyword" style="color: #a626a4;">return</span> <span class="hljs-keyword" style="color: #a626a4;">if</span> (resultCode == Activity.RESULT_OK) {
<span class="hljs-comment" style="color: #a0a1a7; font-style: italic;">// Set up media projection</span>
mMediaProjection = mediaProjectionManager.getMediaProjection(resultCode, resultData)
mMediaProjectionCallback = MediaProjectionCallback()
mMediaProjection!!.registerCallback(mMediaProjectionCallback, <span class="hljs-literal" style="color: #0184bb;">null</span>)
<span class="hljs-literal" style="color: #0184bb;">true</span>
} <span class="hljs-keyword" style="color: #a626a4;">else</span> {
<span class="hljs-literal" style="color: #0184bb;">false</span>
}
}
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">onStopRecording</span><span class="hljs-params">()</span></span> {
isStartCalled = <span class="hljs-literal" style="color: #0184bb;">false</span>
<span class="hljs-keyword" style="color: #a626a4;">if</span> (mRecordListener != <span class="hljs-literal" style="color: #0184bb;">null</span>) {
mRecordListener!!.onStopRecording()
}
}
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">tearDownMediaProjection</span><span class="hljs-params">()</span></span> {
<span class="hljs-keyword" style="color: #a626a4;">if</span> (mMediaProjection != <span class="hljs-literal" style="color: #0184bb;">null</span>) {
mMediaProjection!!.unregisterCallback(mMediaProjectionCallback)
mMediaProjection!!.stop()
mMediaProjection = <span class="hljs-literal" style="color: #0184bb;">null</span>
}
}
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-keyword" style="color: #a626a4;">inner</span> <span class="hljs-class"><span class="hljs-keyword" style="color: #a626a4;">class</span> <span class="hljs-title" style="color: #c18401;">MediaProjectionCallback</span> : <span class="hljs-type" style="color: #986801;">MediaProjection.Callback</span></span>() {
<span class="hljs-keyword" style="color: #a626a4;">override</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">onStop</span><span class="hljs-params">()</span></span> {
<span class="hljs-keyword" style="color: #a626a4;">if</span> (screenRecorder.isRecording) {
<span class="hljs-keyword" style="color: #a626a4;">try</span> {
stopRecording()
} <span class="hljs-keyword" style="color: #a626a4;">catch</span> (ignore: RuntimeException) {
<span class="hljs-comment" style="color: #a0a1a7; font-style: italic;">// Handle cleanup here, see:</span>
<span class="hljs-comment" style="color: #a0a1a7; font-style: italic;">// https://stackoverflow.com/questions/16221866/mediarecorder-failed-when-i-stop-the-recording</span>
}
}
tearDownMediaProjection()
}
}
}</code></pre>
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Собственно данный класс повторяет функционал ScreenRecorder, но только в этом классе мы добавили запрос с помощью MediaProjectionManager который спрашивает у пользователя «хотиш писать видос или не хотиш?» и пользователь уже решает хотит он или нет. </span><br />
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Прям все методы я не буду описывать, опишу только пару, в основном данный класс нужен для индикации о том что происходит на экране. Это будут startRecording и stopRecording, два метода которые нам возвращает лисенер из ScreenRecorder, по приходу колбека в эти методы мы отправляем запрос в сервис что бы он проверил все ли ок, хотит пользователь писать или нет, и если хотит — тогда мы пишем в файл, и отправляем колбек в onStartRecording в сервисе который отправляет колбек onPermissionGranted в MainActivity, в которой уже мы будем показывать какой-то индикатор что запись началась. Если же пользователь отказал — то мы отправляем другой колбек onPermissionDenied в MainActivity. И если запись была остановленная то так же отправляется колбек в MainActivity для индикации пользователю.</span><br />
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Все очень сложно и запутанно, я если честно сам офигел, но после пары часов разбора кода я думаю все встанет на свои места у человека которому это нужно :) </span><br />
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Но это еще не все, у нас еще будет класс менеджер который будет в себе обсорбировать все вызовы сервиса, старт записи, стоп записи и паузы / резюма. Он нам нужен для разделения логики работы что бы вот совсем было просто работать с нашим рекордером, что бы было достаточно создать инстанс RecorderManager и вызвать нужный метод и получить результат, какой-то колбек и еще видео ко всему.</span><br />
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">RecorderManager.kt</span><br />
<pre style="background-color: white; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow: auto hidden; padding: 0px; word-break: break-all;"><code class="kotlin hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="color: #a626a4;">import</span> android.content.ComponentName
<span class="hljs-keyword" style="color: #a626a4;">import</span> android.content.Context
<span class="hljs-keyword" style="color: #a626a4;">import</span> android.content.Intent
<span class="hljs-keyword" style="color: #a626a4;">import</span> android.content.ServiceConnection
<span class="hljs-keyword" style="color: #a626a4;">import</span> android.os.IBinder
<span class="hljs-keyword" style="color: #a626a4;">import</span> dajver.com.recordscreenexample.recorder.service.RecordService
<span class="hljs-keyword" style="color: #a626a4;">import</span> dajver.com.recordscreenexample.recorder.service.listeners.RecordingPermissionListener
<span class="hljs-keyword" style="color: #a626a4;">import</span> dajver.com.recordscreenexample.recorder.service.listeners.StopRecordingListener
<span class="hljs-keyword" style="color: #a626a4;">import</span> java.io.File
<span class="hljs-class"><span class="hljs-keyword" style="color: #a626a4;">class</span> <span class="hljs-title" style="color: #c18401;">RecorderManager</span></span>(<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-keyword" style="color: #a626a4;">val</span> mContext: Context, <span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-keyword" style="color: #a626a4;">val</span> mRecordingPermissionListener: RecordingPermissionListener, <span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-keyword" style="color: #a626a4;">val</span> mSystemStopRecordingListener: StopRecordingListener) {
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-keyword" style="color: #a626a4;">var</span> mRecordServiceBinder: RecordService.RecordServiceBinder? = <span class="hljs-literal" style="color: #0184bb;">null</span>
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-keyword" style="color: #a626a4;">var</span> mIsBound = <span class="hljs-literal" style="color: #0184bb;">false</span>
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-keyword" style="color: #a626a4;">var</span> mStartRecordingCalled = <span class="hljs-literal" style="color: #0184bb;">false</span>
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-keyword" style="color: #a626a4;">var</span> mFileToUpload: File? = <span class="hljs-literal" style="color: #0184bb;">null</span>
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-keyword" style="color: #a626a4;">val</span> mRecordServiceConnection = <span class="hljs-keyword" style="color: #a626a4;">object</span> : ServiceConnection {
<span class="hljs-keyword" style="color: #a626a4;">override</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">onServiceConnected</span><span class="hljs-params">(componentName: <span class="hljs-type" style="color: #986801;">ComponentName</span>, iBinder: <span class="hljs-type" style="color: #986801;">IBinder</span>)</span></span> {
mRecordServiceBinder = iBinder <span class="hljs-keyword" style="color: #a626a4;">as</span> RecordService.RecordServiceBinder
<span class="hljs-keyword" style="color: #a626a4;">if</span> (mStartRecordingCalled) {
mStartRecordingCalled = <span class="hljs-literal" style="color: #0184bb;">false</span>
mRecordServiceBinder!!.startRecording(mFileToUpload!!.absolutePath, mRecordingPermissionListener, <span class="hljs-literal" style="color: #0184bb;">true</span>, mSystemStopRecordingListener)
}
}
<span class="hljs-keyword" style="color: #a626a4;">override</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">onServiceDisconnected</span><span class="hljs-params">(componentName: <span class="hljs-type" style="color: #986801;">ComponentName</span>)</span></span> {
mRecordServiceBinder = <span class="hljs-literal" style="color: #0184bb;">null</span>
mIsBound = <span class="hljs-literal" style="color: #0184bb;">false</span>
}
}
<span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">startRecording</span><span class="hljs-params">(fileToRecord: <span class="hljs-type" style="color: #986801;">File</span>)</span></span> {
<span class="hljs-keyword" style="color: #a626a4;">this</span>.mFileToUpload = fileToRecord
<span class="hljs-keyword" style="color: #a626a4;">if</span> (mRecordServiceBinder == <span class="hljs-literal" style="color: #0184bb;">null</span>) {
mStartRecordingCalled = <span class="hljs-literal" style="color: #0184bb;">true</span>
bindRecordService()
} <span class="hljs-keyword" style="color: #a626a4;">else</span> {
mRecordServiceBinder!!.startRecording(fileToRecord.absolutePath, mRecordingPermissionListener, <span class="hljs-literal" style="color: #0184bb;">true</span>, mSystemStopRecordingListener)
}
}
<span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">pauseRecording</span><span class="hljs-params">(listener: <span class="hljs-type" style="color: #986801;">StopRecordingListener</span>)</span></span> {
<span class="hljs-keyword" style="color: #a626a4;">if</span> (!mStartRecordingCalled) {
mRecordServiceBinder!!.stopRecording(listener)
}
}
<span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">resumeRecording</span><span class="hljs-params">(fileToRecord: <span class="hljs-type" style="color: #986801;">File</span>)</span></span> {
<span class="hljs-keyword" style="color: #a626a4;">this</span>.mFileToUpload = fileToRecord
<span class="hljs-keyword" style="color: #a626a4;">if</span> (mRecordServiceBinder != <span class="hljs-literal" style="color: #0184bb;">null</span>) {
mRecordServiceBinder!!.startRecording(fileToRecord.absolutePath, mRecordingPermissionListener, <span class="hljs-literal" style="color: #0184bb;">true</span>, mSystemStopRecordingListener)
}
}
<span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">stopRecording</span><span class="hljs-params">(listener: <span class="hljs-type" style="color: #986801;">StopRecordingListener</span>)</span></span> {
mStartRecordingCalled = <span class="hljs-literal" style="color: #0184bb;">false</span>
<span class="hljs-keyword" style="color: #a626a4;">if</span>(mRecordServiceBinder != <span class="hljs-literal" style="color: #0184bb;">null</span>) {
mRecordServiceBinder!!.stopRecording(listener)
}
unbindRecordService()
}
<span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">cancelRecording</span><span class="hljs-params">()</span></span> {
mStartRecordingCalled = <span class="hljs-literal" style="color: #0184bb;">false</span>
unbindRecordService()
}
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">bindRecordService</span><span class="hljs-params">()</span></span> {
<span class="hljs-keyword" style="color: #a626a4;">val</span> serviceIntent = Intent(mContext, RecordService::<span class="hljs-class"><span class="hljs-keyword" style="color: #a626a4;">class</span>.<span class="hljs-title" style="color: #c18401;">java</span>)</span>
mContext.bindService(serviceIntent, mRecordServiceConnection, Context.BIND_AUTO_CREATE)
mIsBound = <span class="hljs-literal" style="color: #0184bb;">true</span>
}
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">unbindRecordService</span><span class="hljs-params">()</span></span> {
<span class="hljs-keyword" style="color: #a626a4;">if</span> (mIsBound && mRecordServiceBinder != <span class="hljs-literal" style="color: #0184bb;">null</span>) {
mContext.unbindService(mRecordServiceConnection)
mIsBound = <span class="hljs-literal" style="color: #0184bb;">false</span>
}
mRecordServiceBinder = <span class="hljs-literal" style="color: #0184bb;">null</span>
}
}</code></pre>
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Здесь мы создали инстанс RecordServiceBinder который нам нужен для проверки есть ли у нас на данный момент запись или нет, если RecordServiceBinder = null тогда мы создаем новый, а если не null — то мы запускаем / останавливаем запись.</span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">— onServiceConnected — биндер который запускается сервис запущен и готов записывать, то есть когда мы даем добро на запись экрана.</span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">— bindRecordService — нужен для старта сервиса, мы по сути инициализируем сервис и запускаем запрос на запись видео. Дальше как мы получили какой-то результат, пользователь дал доступ на запись или нет, мы вызываем onServiceConnected который запускает запись.</span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">— unbindRecordService — вызывается в основном когда нам нужно закончить запись и остановить сервис. Его мы будем вызывать в стоп рекординге, когда нам сервис уже не нужен.</span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">— startRecording и stopRecording — проверяют есть ли у нас запись и если нету то создает сервис и начинает ее, и соответственно если запись идет то оно останавливает ее, и все это сопровождается лисенерами которые отправляют колбеки в активити.</span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">— pauseRecording и resumeRecording — останавливает или резюмит запись, по сути тоже самое что и старт стоп, но в случае с паузой и резюмом, нам придется писать в новый файл каждый раз когда мы останавливаем или стартуем запись, дозаписывать в тот же не выйдет.</span><br />
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Далее нам нужен класс в котором у нас будет создаваться Notification по клику на который мы будем открывать видео.</span><br />
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">NotificationWrapper.kt</span><br />
<pre style="background-color: white; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow: auto hidden; padding: 0px; word-break: break-all;"><code class="kotlin hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="color: #a626a4;">import</span> android.app.NotificationChannel
<span class="hljs-keyword" style="color: #a626a4;">import</span> android.app.NotificationManager
<span class="hljs-keyword" style="color: #a626a4;">import</span> android.app.PendingIntent
<span class="hljs-keyword" style="color: #a626a4;">import</span> android.content.Context
<span class="hljs-keyword" style="color: #a626a4;">import</span> android.content.Intent
<span class="hljs-keyword" style="color: #a626a4;">import</span> android.graphics.Color
<span class="hljs-keyword" style="color: #a626a4;">import</span> android.net.Uri
<span class="hljs-keyword" style="color: #a626a4;">import</span> android.os.Build
<span class="hljs-keyword" style="color: #a626a4;">import</span> androidx.core.app.NotificationCompat
<span class="hljs-keyword" style="color: #a626a4;">import</span> dajver.com.recordscreenexample.R
<span class="hljs-keyword" style="color: #a626a4;">import</span> java.io.File
<span class="hljs-keyword" style="color: #a626a4;">object</span> NotificationWrapper {
<span class="hljs-keyword" style="color: #a626a4;">internal</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">createNotification</span><span class="hljs-params">(context: <span class="hljs-type" style="color: #986801;">Context</span>, videoPath: <span class="hljs-type" style="color: #986801;">File</span>)</span></span> {
<span class="hljs-keyword" style="color: #a626a4;">val</span> channelId = <span class="hljs-string" style="color: #50a14f;">"app_channel"</span>
<span class="hljs-keyword" style="color: #a626a4;">val</span> intent = Intent(Intent.ACTION_VIEW, Uri.parse(videoPath!!.path))
intent.setDataAndType(Uri.parse(videoPath.path), <span class="hljs-string" style="color: #50a14f;">"video/mp4"</span>)
<span class="hljs-keyword" style="color: #a626a4;">val</span> resultPendingIntent = PendingIntent.getActivity(context, <span class="hljs-number" style="color: #986801;">0</span>, intent, PendingIntent.FLAG_UPDATE_CURRENT)
<span class="hljs-keyword" style="color: #a626a4;">val</span> notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) <span class="hljs-keyword" style="color: #a626a4;">as</span> NotificationManager
<span class="hljs-keyword" style="color: #a626a4;">if</span> (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
<span class="hljs-keyword" style="color: #a626a4;">val</span> channel = NotificationChannel(channelId, <span class="hljs-string" style="color: #50a14f;">"AppExampleChannel"</span>, NotificationManager.IMPORTANCE_DEFAULT)
channel.description = context.getString(R.string.app_name)
channel.setSound(<span class="hljs-literal" style="color: #0184bb;">null</span>, <span class="hljs-literal" style="color: #0184bb;">null</span>)
channel.enableLights(<span class="hljs-literal" style="color: #0184bb;">false</span>)
channel.lightColor = Color.BLUE
channel.enableVibration(<span class="hljs-literal" style="color: #0184bb;">false</span>)
notificationManager.createNotificationChannel(channel)
}
<span class="hljs-keyword" style="color: #a626a4;">val</span> notification = NotificationCompat.Builder(context, channelId)
.setContentTitle(<span class="hljs-string" style="color: #50a14f;">"Screen was recorded"</span>)
.setContentText(<span class="hljs-string" style="color: #50a14f;">"You can open recorded video by clicking on this notification"</span>)
.setContentIntent(resultPendingIntent)
.setSmallIcon(R.drawable.ic_launcher_foreground)
.setVibrate(<span class="hljs-literal" style="color: #0184bb;">null</span>)
.setDefaults(<span class="hljs-number" style="color: #986801;">0</span>)
.setWhen(<span class="hljs-number" style="color: #986801;">0</span>)
.setOnlyAlertOnce(<span class="hljs-literal" style="color: #0184bb;">true</span>)
.build()
notificationManager.notify(<span class="hljs-number" style="color: #986801;">777</span>, notification)
}
}</code></pre>
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Просто создаем нотификейшн, в который передаем адрес файла для воспроизведения, и передаем его в интент который будет открывать видео. Так же мы задали канал для андроид 6 и выше что бы нотиф мог отображаться на них. Ну и далее уже типичное создаем NotificationCompat и задаем параметры отображения.</span><br />
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">activity_main.xml</span><br />
<pre style="background-color: white; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow: auto hidden; padding: 0px; word-break: break-all;"><code class="xml hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-meta" style="color: #4078f2;"><?xml version="1.0" encoding="utf-8"?></span>
<span class="hljs-tag"><<span class="hljs-name" style="color: #e45649;">LinearLayout</span>
<span class="hljs-attr" style="color: #986801;">xmlns:android</span>=<span class="hljs-string" style="color: #50a14f;">"http://schemas.android.com/apk/res/android"</span>
<span class="hljs-attr" style="color: #986801;">android:layout_width</span>=<span class="hljs-string" style="color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="color: #986801;">android:layout_height</span>=<span class="hljs-string" style="color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="color: #986801;">android:gravity</span>=<span class="hljs-string" style="color: #50a14f;">"center"</span>
<span class="hljs-attr" style="color: #986801;">android:orientation</span>=<span class="hljs-string" style="color: #50a14f;">"vertical"</span>></span>
<span class="hljs-tag"><<span class="hljs-name" style="color: #e45649;">Button</span>
<span class="hljs-attr" style="color: #986801;">android:layout_width</span>=<span class="hljs-string" style="color: #50a14f;">"wrap_content"</span>
<span class="hljs-attr" style="color: #986801;">android:layout_height</span>=<span class="hljs-string" style="color: #50a14f;">"wrap_content"</span>
<span class="hljs-attr" style="color: #986801;">android:id</span>=<span class="hljs-string" style="color: #50a14f;">"@+id/startStopButton"</span>
<span class="hljs-attr" style="color: #986801;">android:text</span>=<span class="hljs-string" style="color: #50a14f;">"Start recording"</span>/></span>
<span class="hljs-tag"></<span class="hljs-name" style="color: #e45649;">LinearLayout</span>></span></code></pre>
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Просто кнопка, мы без излишеств. Скромные маленькие человечки.</span><br />
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">MainActivity.kt</span><br />
<pre style="background-color: white; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow: auto hidden; padding: 0px; word-break: break-all;"><code class="kotlin hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="color: #a626a4;">import</span> android.Manifest.permission
<span class="hljs-keyword" style="color: #a626a4;">import</span> android.os.Bundle
<span class="hljs-keyword" style="color: #a626a4;">import</span> android.os.Environment
<span class="hljs-keyword" style="color: #a626a4;">import</span> androidx.appcompat.app.AppCompatActivity
<span class="hljs-keyword" style="color: #a626a4;">import</span> com.karumi.dexter.Dexter
<span class="hljs-keyword" style="color: #a626a4;">import</span> com.karumi.dexter.MultiplePermissionsReport
<span class="hljs-keyword" style="color: #a626a4;">import</span> com.karumi.dexter.PermissionToken
<span class="hljs-keyword" style="color: #a626a4;">import</span> com.karumi.dexter.listener.PermissionRequest
<span class="hljs-keyword" style="color: #a626a4;">import</span> com.karumi.dexter.listener.multi.MultiplePermissionsListener
<span class="hljs-keyword" style="color: #a626a4;">import</span> dajver.com.recordscreenexample.recorder.RecorderManager
<span class="hljs-keyword" style="color: #a626a4;">import</span> dajver.com.recordscreenexample.recorder.service.listeners.RecordingPermissionListener
<span class="hljs-keyword" style="color: #a626a4;">import</span> dajver.com.recordscreenexample.recorder.service.listeners.StopRecordingListener
<span class="hljs-keyword" style="color: #a626a4;">import</span> dajver.com.recordscreenexample.wrappers.NotificationWrapper
<span class="hljs-keyword" style="color: #a626a4;">import</span> kotlinx.android.synthetic.main.activity_main.*
<span class="hljs-keyword" style="color: #a626a4;">import</span> java.io.File
<span class="hljs-keyword" style="color: #a626a4;">import</span> java.util.*
<span class="hljs-class"><span class="hljs-keyword" style="color: #a626a4;">class</span> <span class="hljs-title" style="color: #c18401;">MainActivity</span> : <span class="hljs-type" style="color: #986801;">AppCompatActivity</span></span>(), RecordingPermissionListener, StopRecordingListener,
MultiplePermissionsListener {
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-keyword" style="color: #a626a4;">var</span> mRecorderManager: RecorderManager? = <span class="hljs-literal" style="color: #0184bb;">null</span>
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-keyword" style="color: #a626a4;">var</span> isRecording: <span class="hljs-built_in" style="color: #c18401;">Boolean</span> = <span class="hljs-literal" style="color: #0184bb;">false</span>
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-keyword" style="color: #a626a4;">var</span> videoPath: File? = <span class="hljs-literal" style="color: #0184bb;">null</span>
<span class="hljs-keyword" style="color: #a626a4;">override</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">onCreate</span><span class="hljs-params">(savedInstanceState: <span class="hljs-type" style="color: #986801;">Bundle</span>?)</span></span> {
<span class="hljs-keyword" style="color: #a626a4;">super</span>.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
Dexter.withActivity(<span class="hljs-keyword" style="color: #a626a4;">this</span>).withPermissions(
permission.WRITE_EXTERNAL_STORAGE,
permission.READ_EXTERNAL_STORAGE,
permission.RECORD_AUDIO
).withListener(<span class="hljs-keyword" style="color: #a626a4;">this</span>).check()
mRecorderManager = RecorderManager(<span class="hljs-keyword" style="color: #a626a4;">this</span>, <span class="hljs-keyword" style="color: #a626a4;">this</span>, <span class="hljs-keyword" style="color: #a626a4;">this</span>)
startStopButton.setOnClickListener {
<span class="hljs-keyword" style="color: #a626a4;">if</span>(isRecording) {
startStopButton.text = <span class="hljs-string" style="color: #50a14f;">"Start recording"</span>
mRecorderManager!!.stopRecording(<span class="hljs-keyword" style="color: #a626a4;">this</span>)
isRecording = <span class="hljs-literal" style="color: #0184bb;">false</span>
} <span class="hljs-keyword" style="color: #a626a4;">else</span> {
startStopButton.text = <span class="hljs-string" style="color: #50a14f;">"Stop recording"</span>
videoPath = getVideoFilePath()
mRecorderManager!!.startRecording(videoPath!!)
isRecording = <span class="hljs-literal" style="color: #0184bb;">true</span>
}
}
}
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">getVideoFilePath</span><span class="hljs-params">()</span></span>: File {
<span class="hljs-keyword" style="color: #a626a4;">val</span> videoId = UUID.randomUUID().toString()
<span class="hljs-keyword" style="color: #a626a4;">val</span> rootSessionsDir = File(getExternalFilesDir(Environment.DIRECTORY_DCIM), ROOT_SESSIONS_NAME)
<span class="hljs-keyword" style="color: #a626a4;">if</span> (!rootSessionsDir.exists() || !rootSessionsDir.isDirectory) {
rootSessionsDir.mkdir()
}
<span class="hljs-keyword" style="color: #a626a4;">val</span> videoDir = File(rootSessionsDir, videoId)
<span class="hljs-keyword" style="color: #a626a4;">if</span> (!videoDir.exists() || !videoDir.isDirectory) {
videoDir.mkdir()
}
<span class="hljs-keyword" style="color: #a626a4;">val</span> gameName = String.format(Locale.US, GAME_FILE_NAME_FORMAT, (<span class="hljs-number" style="color: #986801;">1</span>..<span class="hljs-number" style="color: #986801;">9999</span>).random())
<span class="hljs-keyword" style="color: #a626a4;">val</span> videoFileName = <span class="hljs-string" style="color: #50a14f;">"<span class="hljs-variable" style="color: #986801;">$gameName</span>.mp4"</span>
<span class="hljs-keyword" style="color: #a626a4;">val</span> videoFile = File(videoDir, videoFileName)
<span class="hljs-keyword" style="color: #a626a4;">if</span> (!videoFile.exists() || !videoFile.isFile) {
videoFile.createNewFile()
}
<span class="hljs-keyword" style="color: #a626a4;">return</span> videoFile
}
<span class="hljs-keyword" style="color: #a626a4;">override</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">onPermissionGranted</span><span class="hljs-params">()</span></span> {
<span class="hljs-comment" style="color: #a0a1a7; font-style: italic;">// show some indicator that recording has started</span>
}
<span class="hljs-keyword" style="color: #a626a4;">override</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">onPermissionDenied</span><span class="hljs-params">()</span></span> {
mRecorderManager!!.cancelRecording()
}
<span class="hljs-keyword" style="color: #a626a4;">override</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">onStopRecording</span><span class="hljs-params">()</span></span> {
<span class="hljs-comment" style="color: #a0a1a7; font-style: italic;">// show some indicator that recording ended, for example show the notification about recorded video</span>
NotificationWrapper.createNotification(<span class="hljs-keyword" style="color: #a626a4;">this</span>, videoPath!!)
}
<span class="hljs-keyword" style="color: #a626a4;">override</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">onSystemStopRecording</span><span class="hljs-params">()</span></span> {
mRecorderManager!!.cancelRecording()
<span class="hljs-comment" style="color: #a0a1a7; font-style: italic;">// and remove all other objectives which you need</span>
}
<span class="hljs-keyword" style="color: #a626a4;">override</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">onPermissionsChecked</span><span class="hljs-params">(report: <span class="hljs-type" style="color: #986801;">MultiplePermissionsReport</span>?)</span></span> { }
<span class="hljs-keyword" style="color: #a626a4;">override</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">onPermissionRationaleShouldBeShown</span><span class="hljs-params">(permissions: <span class="hljs-type" style="color: #986801;">MutableList</span><<span class="hljs-type" style="color: #986801;">PermissionRequest</span>>?, token: <span class="hljs-type" style="color: #986801;">PermissionToken</span>?)</span></span> { }
<span class="hljs-keyword" style="color: #a626a4;">companion</span> <span class="hljs-keyword" style="color: #a626a4;">object</span> {
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-keyword" style="color: #a626a4;">const</span> <span class="hljs-keyword" style="color: #a626a4;">val</span> GAME_FILE_NAME_FORMAT = <span class="hljs-string" style="color: #50a14f;">"video_%1\$d"</span>
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-keyword" style="color: #a626a4;">const</span> <span class="hljs-keyword" style="color: #a626a4;">val</span> ROOT_SESSIONS_NAME = <span class="hljs-string" style="color: #50a14f;">"videos"</span>
}
}</code></pre>
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">В onCreate мы спрашиваем у пользователя разрешения на запись экрана и на запись в внутренее хранилище. Так же вешаем лисенера на кнопку по нажатию на которую мы стартуем или стопаем запись экрана. Создаем инстанс RecorderManager и подписываемся на всех лисенеров на которые нас просит этот класс пописаться.</span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">— getVideoFilePath — создает путь к файлу и сам файл в который мы будем писать.</span><br />
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Ну и дальше уже просто создаем кучу методов которые просит нас создать студия, это методы из наших лисеноров.</span><br />
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">В onStopRecording мы показываем нотиф с помощью нашего класса NotificationWrapper по окончанию записи…</span><br />
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">AndroidManifest.xml</span><br />
<pre style="background-color: white; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow: auto hidden; padding: 0px; word-break: break-all;"><code class="xml hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-meta" style="color: #4078f2;"><?xml version="1.0" encoding="utf-8"?></span>
<span class="hljs-tag"><<span class="hljs-name" style="color: #e45649;">manifest</span> <span class="hljs-attr" style="color: #986801;">xmlns:android</span>=<span class="hljs-string" style="color: #50a14f;">"http://schemas.android.com/apk/res/android"</span>
<span class="hljs-attr" style="color: #986801;">xmlns:tools</span>=<span class="hljs-string" style="color: #50a14f;">"http://schemas.android.com/tools"</span> <span class="hljs-attr" style="color: #986801;">package</span>=<span class="hljs-string" style="color: #50a14f;">"dajver.com.recordscreenexample"</span>></span>
<span class="hljs-tag"><<span class="hljs-name" style="color: #e45649;">uses-permission</span> <span class="hljs-attr" style="color: #986801;">android:name</span>=<span class="hljs-string" style="color: #50a14f;">"android.permission.WRITE_EXTERNAL_STORAGE"</span> /></span>
<span class="hljs-tag"><<span class="hljs-name" style="color: #e45649;">uses-permission</span> <span class="hljs-attr" style="color: #986801;">android:name</span>=<span class="hljs-string" style="color: #50a14f;">"android.permission.READ_EXTERNAL_STORAGE"</span> /></span>
<span class="hljs-tag"><<span class="hljs-name" style="color: #e45649;">uses-permission</span> <span class="hljs-attr" style="color: #986801;">android:name</span>=<span class="hljs-string" style="color: #50a14f;">"android.permission.RECORD_AUDIO"</span> /></span>
<span class="hljs-tag"><<span class="hljs-name" style="color: #e45649;">application</span>
<span class="hljs-attr" style="color: #986801;">android:allowBackup</span>=<span class="hljs-string" style="color: #50a14f;">"true"</span>
<span class="hljs-attr" style="color: #986801;">android:icon</span>=<span class="hljs-string" style="color: #50a14f;">"@mipmap/ic_launcher"</span>
<span class="hljs-attr" style="color: #986801;">android:label</span>=<span class="hljs-string" style="color: #50a14f;">"@string/app_name"</span>
<span class="hljs-attr" style="color: #986801;">android:roundIcon</span>=<span class="hljs-string" style="color: #50a14f;">"@mipmap/ic_launcher_round"</span>
<span class="hljs-attr" style="color: #986801;">android:supportsRtl</span>=<span class="hljs-string" style="color: #50a14f;">"true"</span>
<span class="hljs-attr" style="color: #986801;">android:theme</span>=<span class="hljs-string" style="color: #50a14f;">"@style/AppTheme"</span>
<span class="hljs-attr" style="color: #986801;">tools:ignore</span>=<span class="hljs-string" style="color: #50a14f;">"GoogleAppIndexingWarning"</span>></span>
<span class="hljs-tag"><<span class="hljs-name" style="color: #e45649;">activity</span> <span class="hljs-attr" style="color: #986801;">android:name</span>=<span class="hljs-string" style="color: #50a14f;">".MainActivity"</span>></span>
<span class="hljs-tag"><<span class="hljs-name" style="color: #e45649;">intent-filter</span>></span>
<span class="hljs-tag"><<span class="hljs-name" style="color: #e45649;">action</span> <span class="hljs-attr" style="color: #986801;">android:name</span>=<span class="hljs-string" style="color: #50a14f;">"android.intent.action.MAIN"</span>/></span>
<span class="hljs-tag"><<span class="hljs-name" style="color: #e45649;">category</span> <span class="hljs-attr" style="color: #986801;">android:name</span>=<span class="hljs-string" style="color: #50a14f;">"android.intent.category.LAUNCHER"</span>/></span>
<span class="hljs-tag"></<span class="hljs-name" style="color: #e45649;">intent-filter</span>></span>
<span class="hljs-tag"></<span class="hljs-name" style="color: #e45649;">activity</span>></span>
<span class="hljs-tag"><<span class="hljs-name" style="color: #e45649;">activity</span> <span class="hljs-attr" style="color: #986801;">android:name</span>=<span class="hljs-string" style="color: #50a14f;">".recorder.activity.RequestMediaProjectionActivity"</span> /></span>
<span class="hljs-tag"><<span class="hljs-name" style="color: #e45649;">service</span> <span class="hljs-attr" style="color: #986801;">android:name</span>=<span class="hljs-string" style="color: #50a14f;">".recorder.service.RecordService"</span> /></span>
<span class="hljs-tag"></<span class="hljs-name" style="color: #e45649;">application</span>></span>
<span class="hljs-tag"></<span class="hljs-name" style="color: #e45649;">manifest</span>></span></code></pre>
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Так же еще осталось прописать все пермишенны в AndroidManifest, сервис и дополнительную активити которая будет вызываться для запроса на запись при клике на кнопку старта. Прописываем те же самые пермишены которые запрашивали в MainActivity.</span><br />
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Вот собственно и вся магия, надеюсь что хоть немного понятно объяснил весь этот треш который тут происходит. И это кому-то пригодится.</span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;"><br /></span>
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif;"><span style="font-size: large;"><b>Исходники:</b></span></span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif;"><span style="font-size: large;"><b><a href="https://github.com/dajver/RecordScreenExample">GitHub</a></b></span></span></div>
dajverhttp://www.blogger.com/profile/09427222798699404442noreply@blogger.com0tag:blogger.com,1999:blog-5677605911484164185.post-43765566259216920902019-07-06T14:21:00.001+03:002019-07-06T14:27:27.265+03:00PopupWindow который указывает на view вызывающий его<div dir="ltr" style="text-align: left;" trbidi="on">
<div class="separator" style="clear: both; text-align: center;">
</div>
<div style="text-align: justify;">
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; text-align: left;">Случается так что приходится делать выпадающее меню которое указывает на вью которое его вызвало и в нем выводить какие-то данные красиво, собственно я недавно столкнулся с такой штукой и теперь хочу поделиться с тем как я это сделал. </span></div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: justify;">
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; text-align: left;">У нас будет вообще элементарный пример, будет кнопка которая будет бегать по экране по клику на другую кнопку, а кнопка которая перемещается по экрану, по клику, будет вызывать диалог прицепленых к данной кнопке.</span></div>
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; text-align: left;">
</span>
<br />
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://github.com/dajver/PointerPopupViewExample/raw/master/images/example.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="800" data-original-width="450" height="400" src="https://github.com/dajver/PointerPopupViewExample/raw/master/images/example.gif" width="223" /></a></div>
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Никакие библиотеки нам в этот раз не понадобятся, никакие расширения дополнительные тоже. Использовать мы будем стандартный ListView для создания списка и обычный ArrayAdapter для написания адаптера для списка. Единственное что нам понадобится так это минимальная версия проекта </span><span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">minSdkVersion 19</span><span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">, так как для использования showAsDropDown() нужно иметь минимальный SDK 19.</span><br />
<a name='more'></a><br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Для начала нам нужно прописать ресурсы. Нам нужен будет фон для нашего PopupWindow. Его мы создадим в drawable, так как мы будем создавать эту вью программно, нам придется его присваивать не как цвет фона, а как Drawable.</span><br />
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">colors.xml</span><br />
<pre style="background-color: white; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow: auto hidden; padding: 0px; word-break: break-all;"><code class="xml hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-tag"><<span class="hljs-name" style="color: #e45649;">color</span> <span class="hljs-attr" style="color: #986801;">name</span>=<span class="hljs-string" style="color: #50a14f;">"brown_dark"</span>></span>#2C2935<span class="hljs-tag"></<span class="hljs-name" style="color: #e45649;">color</span>></span>
<span class="hljs-tag"><<span class="hljs-name" style="color: #e45649;">color</span> <span class="hljs-attr" style="color: #986801;">name</span>=<span class="hljs-string" style="color: #50a14f;">"gray_dark"</span>></span>#4b4b4b<span class="hljs-tag"></<span class="hljs-name" style="color: #e45649;">color</span>></span>
</code></pre>
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Будет два основных цвета, серый для разделителя и фоновый коричневый.</span><br />
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">background_popup_style.xml</span><br />
<pre style="background-color: white; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow: auto hidden; padding: 0px; word-break: break-all;"><code class="xml hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-meta" style="color: #4078f2;"><?xml version="1.0" encoding="utf-8"?></span>
<span class="hljs-tag"><<span class="hljs-name" style="color: #e45649;">layer-list</span> <span class="hljs-attr" style="color: #986801;">xmlns:android</span>=<span class="hljs-string" style="color: #50a14f;">"http://schemas.android.com/apk/res/android"</span> ></span>
<span class="hljs-tag"><<span class="hljs-name" style="color: #e45649;">item</span>></span>
<span class="hljs-tag"><<span class="hljs-name" style="color: #e45649;">shape</span> <span class="hljs-attr" style="color: #986801;">android:shape</span>=<span class="hljs-string" style="color: #50a14f;">"rectangle"</span> <span class="hljs-attr" style="color: #986801;">android:bottom</span>=<span class="hljs-string" style="color: #50a14f;">"0dp"</span> <span class="hljs-attr" style="color: #986801;">android:left</span>=<span class="hljs-string" style="color: #50a14f;">"20dp"</span> <span class="hljs-attr" style="color: #986801;">android:right</span>=<span class="hljs-string" style="color: #50a14f;">"20dp"</span> <span class="hljs-attr" style="color: #986801;">android:top</span>=<span class="hljs-string" style="color: #50a14f;">"0dp"</span> ></span>
<span class="hljs-tag"><<span class="hljs-name" style="color: #e45649;">solid</span> <span class="hljs-attr" style="color: #986801;">android:color</span>=<span class="hljs-string" style="color: #50a14f;">"@android:color/transparent"</span>/></span>
<span class="hljs-tag"><<span class="hljs-name" style="color: #e45649;">padding</span> <span class="hljs-attr" style="color: #986801;">android:bottom</span>=<span class="hljs-string" style="color: #50a14f;">"0dp"</span> <span class="hljs-attr" style="color: #986801;">android:left</span>=<span class="hljs-string" style="color: #50a14f;">"20dp"</span> <span class="hljs-attr" style="color: #986801;">android:right</span>=<span class="hljs-string" style="color: #50a14f;">"20dp"</span> <span class="hljs-attr" style="color: #986801;">android:top</span>=<span class="hljs-string" style="color: #50a14f;">"0dp"</span> /></span>
<span class="hljs-tag"></<span class="hljs-name" style="color: #e45649;">shape</span>></span>
<span class="hljs-tag"></<span class="hljs-name" style="color: #e45649;">item</span>></span>
<span class="hljs-tag"><<span class="hljs-name" style="color: #e45649;">item</span>></span>
<span class="hljs-tag"><<span class="hljs-name" style="color: #e45649;">shape</span> <span class="hljs-attr" style="color: #986801;">android:shape</span>=<span class="hljs-string" style="color: #50a14f;">"rectangle"</span>></span>
<span class="hljs-tag"><<span class="hljs-name" style="color: #e45649;">corners</span> <span class="hljs-attr" style="color: #986801;">android:radius</span>=<span class="hljs-string" style="color: #50a14f;">"10dp"</span> /></span>
<span class="hljs-tag"><<span class="hljs-name" style="color: #e45649;">solid</span> <span class="hljs-attr" style="color: #986801;">android:color</span>=<span class="hljs-string" style="color: #50a14f;">"@color/brown_dark"</span>/></span>
<span class="hljs-tag"></<span class="hljs-name" style="color: #e45649;">shape</span>></span>
<span class="hljs-tag"></<span class="hljs-name" style="color: #e45649;">item</span>></span>
<span class="hljs-tag"></<span class="hljs-name" style="color: #e45649;">layer-list</span>></span>
</code></pre>
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Тут мы просто рисуем бекграунд и заполняем его цветом с паддингами, и закругляем углы для визуальной красивости.</span><br />
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">PointerPopupWindow.kt</span><br />
<pre style="background-color: white; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow: auto hidden; padding: 0px; word-break: break-all;"><code class="kotlin hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="color: #a626a4;">import</span> android.content.Context
<span class="hljs-keyword" style="color: #a626a4;">import</span> android.graphics.Rect
<span class="hljs-keyword" style="color: #a626a4;">import</span> android.graphics.drawable.ColorDrawable
<span class="hljs-keyword" style="color: #a626a4;">import</span> android.graphics.drawable.Drawable
<span class="hljs-keyword" style="color: #a626a4;">import</span> android.view.Gravity
<span class="hljs-keyword" style="color: #a626a4;">import</span> android.view.View
<span class="hljs-keyword" style="color: #a626a4;">import</span> android.view.ViewGroup
<span class="hljs-keyword" style="color: #a626a4;">import</span> android.widget.FrameLayout
<span class="hljs-keyword" style="color: #a626a4;">import</span> android.widget.ImageView
<span class="hljs-keyword" style="color: #a626a4;">import</span> android.widget.LinearLayout
<span class="hljs-keyword" style="color: #a626a4;">import</span> android.widget.PopupWindow
<span class="hljs-keyword" style="color: #a626a4;">import</span> dajver.com.pointerpopupwindowexample.R
<span class="hljs-class"><span class="hljs-keyword" style="color: #a626a4;">class</span> <span class="hljs-title" style="color: #c18401;">PointerPopupWindow</span> <span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-keyword" style="color: #a626a4;">constructor</span></span>(context: Context, width: <span class="hljs-built_in" style="color: #c18401;">Int</span>, height: <span class="hljs-built_in" style="color: #c18401;">Int</span>) : PopupWindow(width, height) {
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-keyword" style="color: #a626a4;">val</span> mContainer: LinearLayout
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-keyword" style="color: #a626a4;">val</span> mAnchorImage: ImageView
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-keyword" style="color: #a626a4;">val</span> mContent: FrameLayout
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-keyword" style="color: #a626a4;">var</span> mAlignMode = AlignMode.DEFAULT
<span class="hljs-keyword" style="color: #a626a4;">constructor</span>(context: Context, width: <span class="hljs-built_in" style="color: #c18401;">Int</span>) : <span class="hljs-keyword" style="color: #a626a4;">this</span>(context, width, ViewGroup.LayoutParams.WRAP_CONTENT) {}
<span class="hljs-keyword" style="color: #a626a4;">init</span> {
<span class="hljs-keyword" style="color: #a626a4;">if</span> (width < <span class="hljs-number" style="color: #986801;">0</span>) {
<span class="hljs-keyword" style="color: #a626a4;">throw</span> RuntimeException(<span class="hljs-string" style="color: #50a14f;">"You must specify the window width explicitly(do not use WRAP_CONTENT or MATCH_PARENT)!!!"</span>)
}
mContainer = LinearLayout(context)
mContainer.orientation = LinearLayout.VERTICAL
mAnchorImage = ImageView(context)
mContent = FrameLayout(context)
setBackgroundDrawable(context.resources.getDrawable(R.drawable.background_popup_style))
isOutsideTouchable = <span class="hljs-literal" style="color: #0184bb;">true</span>
isFocusable = <span class="hljs-literal" style="color: #0184bb;">true</span>
}
<span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">setAlignMode</span><span class="hljs-params">(mAlignMode: <span class="hljs-type" style="color: #986801;">AlignMode</span>)</span></span> {
<span class="hljs-keyword" style="color: #a626a4;">this</span>.mAlignMode = mAlignMode
}
<span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">setPointerImageRes</span><span class="hljs-params">(res: <span class="hljs-type" style="color: #986801;">Int</span>)</span></span> {
mAnchorImage.setImageResource(res)
}
<span class="hljs-keyword" style="color: #a626a4;">override</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">setContentView</span><span class="hljs-params">(contentView: <span class="hljs-type" style="color: #986801;">View</span>?)</span></span> {
<span class="hljs-keyword" style="color: #a626a4;">if</span> (contentView != <span class="hljs-literal" style="color: #0184bb;">null</span>) {
mContainer.removeAllViews()
mContainer.addView(mAnchorImage, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT)
mContainer.addView(mContent, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)
mContent.addView(contentView, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)
<span class="hljs-keyword" style="color: #a626a4;">super</span>.setContentView(mContainer)
}
}
<span class="hljs-keyword" style="color: #a626a4;">override</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">setBackgroundDrawable</span><span class="hljs-params">(background: <span class="hljs-type" style="color: #986801;">Drawable</span>)</span></span> {
mContent.setBackgroundDrawable(background)
<span class="hljs-keyword" style="color: #a626a4;">super</span>.setBackgroundDrawable(ColorDrawable())
}
<span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">showAsPointer</span><span class="hljs-params">(anchor: <span class="hljs-type" style="color: #986801;">View</span>)</span></span> {
showAsPointer(anchor, <span class="hljs-number" style="color: #986801;">0</span>,
Y_OFFSET_FROM_THE_ANCHOR
)
}
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">showAsPointer</span><span class="hljs-params">(anchor: <span class="hljs-type" style="color: #986801;">View</span>, xOffset: <span class="hljs-type" style="color: #986801;">Int</span>, yOffset: <span class="hljs-type" style="color: #986801;">Int</span>)</span></span> {
<span class="hljs-keyword" style="color: #a626a4;">var</span> xOffset = xOffset
<span class="hljs-keyword" style="color: #a626a4;">val</span> displayFrame = Rect()
anchor.getWindowVisibleDisplayFrame(displayFrame)
<span class="hljs-keyword" style="color: #a626a4;">val</span> displayFrameWidth = displayFrame.right - displayFrame.left
<span class="hljs-keyword" style="color: #a626a4;">val</span> loc = IntArray(<span class="hljs-number" style="color: #986801;">2</span>)
anchor.getLocationInWindow(loc)
<span class="hljs-keyword" style="color: #a626a4;">if</span> (mAlignMode == AlignMode.AUTO_OFFSET) {
<span class="hljs-keyword" style="color: #a626a4;">val</span> offCenterRate = (displayFrame.centerX() - loc[<span class="hljs-number" style="color: #986801;">0</span>]) / displayFrameWidth.toFloat()
xOffset = ((anchor.width - width) / <span class="hljs-number" style="color: #986801;">2</span> + offCenterRate * width / <span class="hljs-number" style="color: #986801;">2</span>).toInt()
} <span class="hljs-keyword" style="color: #a626a4;">else</span> <span class="hljs-keyword" style="color: #a626a4;">if</span> (mAlignMode == AlignMode.CENTER_FIX) {
xOffset = (anchor.width - width) / <span class="hljs-number" style="color: #986801;">2</span>
}
<span class="hljs-keyword" style="color: #a626a4;">val</span> left = loc[<span class="hljs-number" style="color: #986801;">0</span>] + xOffset
<span class="hljs-keyword" style="color: #a626a4;">val</span> right = left + width
<span class="hljs-keyword" style="color: #a626a4;">if</span> (right > displayFrameWidth) {
xOffset = displayFrameWidth - width - loc[<span class="hljs-number" style="color: #986801;">0</span>]
}
<span class="hljs-keyword" style="color: #a626a4;">if</span> (left < displayFrame.left) {
xOffset = displayFrame.left - loc[<span class="hljs-number" style="color: #986801;">0</span>]
}
computePointerLocation(anchor, xOffset)
<span class="hljs-keyword" style="color: #a626a4;">super</span>.showAsDropDown(anchor, xOffset, yOffset, Gravity.CENTER)
}
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">computePointerLocation</span><span class="hljs-params">(anchor: <span class="hljs-type" style="color: #986801;">View</span>, xOffset: <span class="hljs-type" style="color: #986801;">Int</span>)</span></span> {
<span class="hljs-keyword" style="color: #a626a4;">val</span> aw = anchor.width
<span class="hljs-keyword" style="color: #a626a4;">val</span> dw = mAnchorImage.drawable.intrinsicWidth
mAnchorImage.setPadding((aw - dw) / <span class="hljs-number" style="color: #986801;">2</span> - xOffset, <span class="hljs-number" style="color: #986801;">0</span>, <span class="hljs-number" style="color: #986801;">0</span>, <span class="hljs-number" style="color: #986801;">0</span>)
}
<span class="hljs-keyword" style="color: #a626a4;">enum</span> <span class="hljs-class"><span class="hljs-keyword" style="color: #a626a4;">class</span> <span class="hljs-title" style="color: #c18401;">AlignMode</span> </span>{
DEFAULT,
CENTER_FIX,
AUTO_OFFSET
}
<span class="hljs-keyword" style="color: #a626a4;">companion</span> <span class="hljs-keyword" style="color: #a626a4;">object</span> {
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-keyword" style="color: #a626a4;">const</span> <span class="hljs-keyword" style="color: #a626a4;">val</span> Y_OFFSET_FROM_THE_ANCHOR = -<span class="hljs-number" style="color: #986801;">20</span>
}
}
</code></pre>
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">— init — инициализируем все нужные нам параметры, создаем контейнер в который помещаем все нужные параметры и задаем фоновый цвет.</span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">— setAlignMode() — указывает какой вид направления будет у вьюхи, DEFAULT, CENTER_FIX или AUTO_OFFSET. В зависимости от которых мы ниже будем расчитывать положение выпадашки на экране.</span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">— setPointerImageRes() — указывает картинку которая будет использоваться как поинтер на вью к которой привязана выпадашка.</span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">— setContentView() — добавляет все вьюхи на экран.</span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">— showAsPointer(anchor: View) — устанавливает вью на которую будет указывать поинтер. </span><img alt="image" src="https://github.com/dajver/PointerPopupViewExample/blob/master/app/src/main/res/mipmap-xhdpi/ic_popup_pointer.png?raw=true" style="background-color: white; border-style: none; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px; height: auto; margin: 0px; max-width: 100%; vertical-align: middle;" /><span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">. Эта картинка кстати нам понадобится дальше, так что сохраните ее себе как </span><span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">ic_popup_pointer.png</span><span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">.</span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">— showAsPointer(anchor: View, xOffset: Int, yOffset: Int) — же расширеная версия метода showAsPointer(anchor: View), так как этот метод вызывает текущий метод. В данном методе мы делаем некоторые расчеты для отображения выпадашки на экране, и проверяем что бы она не проваливалась за пределы экрана и выпадалшка находилась под вьюхой которая создает эту выпадашку. Так же в этом методе мы проверяем AlignMode, в зависимости от которого мы отображаем наш выпадающий вью.</span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">— computePointerLocation() — задает паддинг что бы наша вьюха не прилипала к краю экрана когда отображается на экране.</span><br />
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">UsersModel.kt</span><br />
<pre style="background-color: white; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow: auto hidden; padding: 0px; word-break: break-all;"><code class="kotlin hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-class"><span class="hljs-keyword" style="color: #a626a4;">class</span> <span class="hljs-title" style="color: #c18401;">UsersModel</span></span>(<span class="hljs-keyword" style="color: #a626a4;">internal</span> <span class="hljs-keyword" style="color: #a626a4;">var</span> title: String, <span class="hljs-keyword" style="color: #a626a4;">internal</span> <span class="hljs-keyword" style="color: #a626a4;">var</span> description: String)</code></pre>
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">У нас будет моделька Users которая будет в себе хранить имя пользователя и контент «типа» который этот пользователь написал. Ничего нового не смог придумать, старею…</span><br />
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">item_users.xml</span><br />
<pre style="background-color: white; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow: auto hidden; padding: 0px; word-break: break-all;"><code class="xml hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-meta" style="color: #4078f2;"><?xml version="1.0" encoding="utf-8"?></span>
<span class="hljs-tag"><<span class="hljs-name" style="color: #e45649;">LinearLayout</span> <span class="hljs-attr" style="color: #986801;">xmlns:android</span>=<span class="hljs-string" style="color: #50a14f;">"http://schemas.android.com/apk/res/android"</span>
<span class="hljs-attr" style="color: #986801;">android:orientation</span>=<span class="hljs-string" style="color: #50a14f;">"vertical"</span>
<span class="hljs-attr" style="color: #986801;">android:layout_width</span>=<span class="hljs-string" style="color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="color: #986801;">android:layout_height</span>=<span class="hljs-string" style="color: #50a14f;">"wrap_content"</span>
<span class="hljs-attr" style="color: #986801;">android:padding</span>=<span class="hljs-string" style="color: #50a14f;">"20dp"</span>></span>
<span class="hljs-tag"><<span class="hljs-name" style="color: #e45649;">TextView</span> <span class="hljs-attr" style="color: #986801;">android:text</span>=<span class="hljs-string" style="color: #50a14f;">"TextView"</span>
<span class="hljs-attr" style="color: #986801;">android:layout_width</span>=<span class="hljs-string" style="color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="color: #986801;">android:layout_height</span>=<span class="hljs-string" style="color: #50a14f;">"wrap_content"</span>
<span class="hljs-attr" style="color: #986801;">android:id</span>=<span class="hljs-string" style="color: #50a14f;">"@+id/name"</span>
<span class="hljs-attr" style="color: #986801;">android:textStyle</span>=<span class="hljs-string" style="color: #50a14f;">"bold"</span>
<span class="hljs-attr" style="color: #986801;">android:textColor</span>=<span class="hljs-string" style="color: #50a14f;">"@android:color/white"</span>/></span>
<span class="hljs-tag"><<span class="hljs-name" style="color: #e45649;">TextView</span> <span class="hljs-attr" style="color: #986801;">android:text</span>=<span class="hljs-string" style="color: #50a14f;">"TextView"</span>
<span class="hljs-attr" style="color: #986801;">android:layout_width</span>=<span class="hljs-string" style="color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="color: #986801;">android:layout_height</span>=<span class="hljs-string" style="color: #50a14f;">"wrap_content"</span>
<span class="hljs-attr" style="color: #986801;">android:id</span>=<span class="hljs-string" style="color: #50a14f;">"@+id/content"</span>
<span class="hljs-attr" style="color: #986801;">android:layout_marginTop</span>=<span class="hljs-string" style="color: #50a14f;">"10dp"</span>
<span class="hljs-attr" style="color: #986801;">android:textSize</span>=<span class="hljs-string" style="color: #50a14f;">"18sp"</span>
<span class="hljs-attr" style="color: #986801;">android:textColor</span>=<span class="hljs-string" style="color: #50a14f;">"@android:color/white"</span>/></span>
<span class="hljs-tag"></<span class="hljs-name" style="color: #e45649;">LinearLayout</span>></span>
</code></pre>
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Нарисуем два текстовых поля, в которых мы покажем юзера и его сообщение.</span><br />
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">PointerPopupAdapter.kt</span><br />
<pre style="background-color: white; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow: auto hidden; padding: 0px; word-break: break-all;"><code class="kotlin hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="color: #a626a4;">import</span> android.content.Context
<span class="hljs-keyword" style="color: #a626a4;">import</span> android.view.LayoutInflater
<span class="hljs-keyword" style="color: #a626a4;">import</span> android.view.View
<span class="hljs-keyword" style="color: #a626a4;">import</span> android.view.ViewGroup
<span class="hljs-keyword" style="color: #a626a4;">import</span> android.widget.ArrayAdapter
<span class="hljs-keyword" style="color: #a626a4;">import</span> dajver.com.pointerpopupwindowexample.R
<span class="hljs-keyword" style="color: #a626a4;">import</span> dajver.com.pointerpopupwindowexample.adapter.model.UsersModel
<span class="hljs-keyword" style="color: #a626a4;">import</span> kotlinx.android.synthetic.main.item_users.view.*
<span class="hljs-keyword" style="color: #a626a4;">import</span> java.util.*
<span class="hljs-class"><span class="hljs-keyword" style="color: #a626a4;">class</span> <span class="hljs-title" style="color: #c18401;">PointerPopupAdapter</span></span>(context: Context, <span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-keyword" style="color: #a626a4;">val</span> usersModels: ArrayList<UsersModel>) : ArrayAdapter<UsersModel>(context, <span class="hljs-number" style="color: #986801;">0</span>, usersModels) {
<span class="hljs-keyword" style="color: #a626a4;">override</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">getCount</span><span class="hljs-params">()</span></span>: <span class="hljs-built_in" style="color: #c18401;">Int</span> {
<span class="hljs-keyword" style="color: #a626a4;">return</span> usersModels.size
}
<span class="hljs-keyword" style="color: #a626a4;">override</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">getView</span><span class="hljs-params">(position: <span class="hljs-type" style="color: #986801;">Int</span>, convertView: <span class="hljs-type" style="color: #986801;">View</span>?, parent: <span class="hljs-type" style="color: #986801;">ViewGroup</span>)</span></span>: View {
<span class="hljs-keyword" style="color: #a626a4;">val</span> view = LayoutInflater.from(context).inflate(R.layout.item_users, <span class="hljs-literal" style="color: #0184bb;">null</span>)
<span class="hljs-keyword" style="color: #a626a4;">val</span> holder = PopupTitleViewHolder(view)
holder.bind(usersModels[position])
<span class="hljs-keyword" style="color: #a626a4;">return</span> view
}
<span class="hljs-keyword" style="color: #a626a4;">inner</span> <span class="hljs-class"><span class="hljs-keyword" style="color: #a626a4;">class</span> <span class="hljs-title" style="color: #c18401;">PopupTitleViewHolder</span></span>(<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-keyword" style="color: #a626a4;">var</span> view: View) {
<span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">bind</span><span class="hljs-params">(usersModel: <span class="hljs-type" style="color: #986801;">UsersModel</span>)</span></span> {
view.name.text = usersModel.title
view.content.text = usersModel.description
}
}
}
</code></pre>
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Тут самый обычный адаптер, в который мы передаем список UsersModel, и отображаем через PopupTitleViewHolder. </span><br />
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">activity_main.xml</span><br />
<pre style="background-color: white; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow: auto hidden; padding: 0px; word-break: break-all;"><code class="xml hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-meta" style="color: #4078f2;"><?xml version="1.0" encoding="utf-8"?></span>
<span class="hljs-tag"><<span class="hljs-name" style="color: #e45649;">RelativeLayout</span>
<span class="hljs-attr" style="color: #986801;">xmlns:android</span>=<span class="hljs-string" style="color: #50a14f;">"http://schemas.android.com/apk/res/android"</span>
<span class="hljs-attr" style="color: #986801;">android:layout_width</span>=<span class="hljs-string" style="color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="color: #986801;">android:layout_height</span>=<span class="hljs-string" style="color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="color: #986801;">android:orientation</span>=<span class="hljs-string" style="color: #50a14f;">"vertical"</span>></span>
<span class="hljs-tag"><<span class="hljs-name" style="color: #e45649;">Button</span>
<span class="hljs-attr" style="color: #986801;">android:text</span>=<span class="hljs-string" style="color: #50a14f;">"Call popup"</span>
<span class="hljs-attr" style="color: #986801;">android:layout_width</span>=<span class="hljs-string" style="color: #50a14f;">"wrap_content"</span>
<span class="hljs-attr" style="color: #986801;">android:layout_height</span>=<span class="hljs-string" style="color: #50a14f;">"wrap_content"</span>
<span class="hljs-attr" style="color: #986801;">android:id</span>=<span class="hljs-string" style="color: #50a14f;">"@+id/openPopup"</span>
<span class="hljs-attr" style="color: #986801;">android:layout_marginLeft</span>=<span class="hljs-string" style="color: #50a14f;">"45dp"</span>
<span class="hljs-attr" style="color: #986801;">android:layout_marginTop</span>=<span class="hljs-string" style="color: #50a14f;">"250dp"</span>/></span>
<span class="hljs-tag"><<span class="hljs-name" style="color: #e45649;">Button</span>
<span class="hljs-attr" style="color: #986801;">android:text</span>=<span class="hljs-string" style="color: #50a14f;">"Change button position"</span>
<span class="hljs-attr" style="color: #986801;">android:layout_width</span>=<span class="hljs-string" style="color: #50a14f;">"wrap_content"</span>
<span class="hljs-attr" style="color: #986801;">android:layout_height</span>=<span class="hljs-string" style="color: #50a14f;">"wrap_content"</span>
<span class="hljs-attr" style="color: #986801;">android:id</span>=<span class="hljs-string" style="color: #50a14f;">"@+id/changeButtonPosition"</span>/></span>
<span class="hljs-tag"></<span class="hljs-name" style="color: #e45649;">RelativeLayout</span>></span>
</code></pre>
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Будет знач у нас две кнопки, одна будет вызывать выпадашку, а вторая будет по нажатию перемещать нашу кнопку call popup рандомно по экрану.</span><br />
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">MainActivity.kt</span><br />
<pre style="background-color: white; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow: auto hidden; padding: 0px; word-break: break-all;"><code class="kotlin hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="color: #a626a4;">import</span> android.content.Context
<span class="hljs-keyword" style="color: #a626a4;">import</span> android.graphics.drawable.ColorDrawable
<span class="hljs-keyword" style="color: #a626a4;">import</span> android.os.Bundle
<span class="hljs-keyword" style="color: #a626a4;">import</span> android.view.WindowManager
<span class="hljs-keyword" style="color: #a626a4;">import</span> android.widget.ListView
<span class="hljs-keyword" style="color: #a626a4;">import</span> android.widget.RelativeLayout
<span class="hljs-keyword" style="color: #a626a4;">import</span> androidx.appcompat.app.AppCompatActivity
<span class="hljs-keyword" style="color: #a626a4;">import</span> dajver.com.pointerpopupwindowexample.adapter.PointerPopupAdapter
<span class="hljs-keyword" style="color: #a626a4;">import</span> dajver.com.pointerpopupwindowexample.adapter.model.UsersModel
<span class="hljs-keyword" style="color: #a626a4;">import</span> dajver.com.pointerpopupwindowexample.popup.PointerPopupWindow
<span class="hljs-keyword" style="color: #a626a4;">import</span> kotlinx.android.synthetic.main.activity_main.*
<span class="hljs-keyword" style="color: #a626a4;">import</span> java.util.*
<span class="hljs-class"><span class="hljs-keyword" style="color: #a626a4;">class</span> <span class="hljs-title" style="color: #c18401;">MainActivity</span> : <span class="hljs-type" style="color: #986801;">AppCompatActivity</span></span>() {
<span class="hljs-keyword" style="color: #a626a4;">override</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">onCreate</span><span class="hljs-params">(savedInstanceState: <span class="hljs-type" style="color: #986801;">Bundle</span>?)</span></span> {
<span class="hljs-keyword" style="color: #a626a4;">super</span>.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
openPopup.setOnClickListener {
<span class="hljs-keyword" style="color: #a626a4;">val</span> wm = getSystemService(Context.WINDOW_SERVICE) <span class="hljs-keyword" style="color: #a626a4;">as</span> WindowManager
<span class="hljs-keyword" style="color: #a626a4;">val</span> width = wm.defaultDisplay.width
<span class="hljs-keyword" style="color: #a626a4;">val</span> popupWindow = PointerPopupWindow(<span class="hljs-keyword" style="color: #a626a4;">this</span>, width)
popupWindow.setPointerImageRes(R.mipmap.ic_popup_pointer)
popupWindow.setAlignMode(PointerPopupWindow.AlignMode.CENTER_FIX)
<span class="hljs-keyword" style="color: #a626a4;">val</span> usersModels = ArrayList<UsersModel>()
usersModels.add(UsersModel(<span class="hljs-string" style="color: #50a14f;">"John Wick"</span>, <span class="hljs-string" style="color: #50a14f;">"Lorem Ipsum is simply."</span>))
usersModels.add(UsersModel(<span class="hljs-string" style="color: #50a14f;">"David Hasselhoff"</span>, <span class="hljs-string" style="color: #50a14f;">"It is a long established fact."</span>))
usersModels.add(UsersModel(<span class="hljs-string" style="color: #50a14f;">"Elizabeth Shaw"</span>, <span class="hljs-string" style="color: #50a14f;">"Contrary to popular belief."</span>))
<span class="hljs-keyword" style="color: #a626a4;">val</span> adapter = PointerPopupAdapter(<span class="hljs-keyword" style="color: #a626a4;">this</span>, usersModels)
<span class="hljs-keyword" style="color: #a626a4;">val</span> listView = ListView(<span class="hljs-keyword" style="color: #a626a4;">this</span>)
listView.divider = ColorDrawable(resources.getColor(R.color.gray_dark))
listView.dividerHeight = <span class="hljs-number" style="color: #986801;">1</span>
listView.adapter = adapter
popupWindow.contentView = listView
popupWindow.showAsPointer(openPopup)
}
changeButtonPosition.setOnClickListener {
<span class="hljs-keyword" style="color: #a626a4;">val</span> params = openPopup.layoutParams <span class="hljs-keyword" style="color: #a626a4;">as</span> RelativeLayout.LayoutParams
params.setMargins((<span class="hljs-number" style="color: #986801;">1</span>..<span class="hljs-number" style="color: #986801;">1099</span>).random(), (<span class="hljs-number" style="color: #986801;">1</span>..<span class="hljs-number" style="color: #986801;">499</span>).random(), <span class="hljs-number" style="color: #986801;">10</span>, <span class="hljs-number" style="color: #986801;">0</span>)
openPopup.layoutParams = params
}
}
}
</code></pre>
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">В onCreate() мы по клику на openPopup показываем наш попап. Получаем ширину экрана, отправляем его в конструктор PointerPopupWindow, для того что бы тот при создании растягивал выпадашку во всю ширину экрана. Задаем картинку поинтера и устанавливаем что бы попап показывался под вьюхой но по середине экрана. Дальше мы создаем список с пользователям, отправляем этот список в адаптер, а дальше адаптер передаем в listView, а listView передаем в popupWindow что бы тот отображался внутри выпадашки. Ну и в showAsPointer задаем кнопку под которой будем показывать выпадашку.</span><br />
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Ну а по нажатию на changeButtonPosition — мы просто задаем margin рандомно от 1 до 1099 от верхней точки экрана и от 1 до 499 с левого края экрана.</span><br />
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Собственно и все. Последний абзац не сильно важный, но его нужно было объяснить :) </span><br />
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Всем спасибо, все свободны.</span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;"><br /></span>
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif;"><b><span style="font-size: large;">Исходники:</span></b></span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif;"><b><span style="font-size: large;"><a href="https://github.com/dajver/PointerPopupViewExample">GitHub</a></span></b></span></div>
dajverhttp://www.blogger.com/profile/09427222798699404442noreply@blogger.com2tag:blogger.com,1999:blog-5677605911484164185.post-36773039090551979242019-07-05T00:21:00.000+03:002019-07-05T00:23:02.037+03:00Проектируем приложение с MVVM<div dir="ltr" style="text-align: left;" trbidi="on">
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div style="margin-left: 1em; margin-right: 1em;">
<div style="text-align: center;">
<img alt="image" height="192" src="https://upload.wikimedia.org/wikipedia/commons/8/87/MVVMPattern.png?1562272378766" style="background-color: white; border-style: none; color: #222222; font-size: 16px; height: auto; margin: 0px; max-width: 100%; vertical-align: middle;" width="640" /></div>
</div>
<br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Я уже писал про ViewModel у себя в блоге, но я писал немного про другое использование данного класса, там мы рассматривали сохранение состояния данных при вращениии экрана что бы мы не теряли данные. Сейчас же мы поговорим про паттерн MVVM который используется для визуального упрощения кода и устанавливает правила для каждого класса выполнять свою работу.</span><br />
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Что же такое MVVM? Вот выдержка из википедии:</span><br />
<blockquote style="background: rgb(255, 247, 215); color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px; margin: 12px 0px; padding: 18px 20px;">
Model-View-ViewModel (т.е. MVVM) — это шаблон архитектуры клиентских приложений, который был предложен Джоном Госсманом (John Gossman) как альтернатива шаблонам MVC и MVP при использовании технологии связывания данных (Data Binding). Его концепция заключается в отделении логики представления данных от бизнес-логики путем вынесения её в отдельный класс для более четкого разграничения.</blockquote>
<a name='more'></a><br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Что такое MVVM разобрались, теперт давайте разберемся как же это реализуется. В моем примере это будет реализовано через запрос на сервер который будет возвращать нам какие-то данные, а мы в свою очередь будем эти данные получать в модель, и отправлять в адаптер. Выглядит довольно просто, давайте посмотрим как же оно выглядит в реальности.</span><br />
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">app/build.gradle</span><br />
<pre style="background-color: white; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow: auto hidden; padding: 0px; word-break: break-all;"><code class="java hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;">dependencies {
implementation <span class="hljs-string" style="color: #50a14f;">'androidx.appcompat:appcompat:1.0.2'</span>
implementation <span class="hljs-string" style="color: #50a14f;">'androidx.recyclerview:recyclerview:1.0.0'</span>
implementation <span class="hljs-string" style="color: #50a14f;">'com.squareup.retrofit2:retrofit:2.6.0'</span>
implementation <span class="hljs-string" style="color: #50a14f;">'com.squareup.retrofit2:converter-gson:2.4.0'</span>
implementation <span class="hljs-string" style="color: #50a14f;">'com.squareup.retrofit2:converter-scalars:2.0.1'</span>
implementation <span class="hljs-string" style="color: #50a14f;">"android.arch.lifecycle:extensions:1.1.1"</span>
implementation <span class="hljs-string" style="color: #50a14f;">"android.arch.lifecycle:viewmodel:1.1.1"</span>
}
</code></pre>
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Начнем с того что подключим нужные библиотеки, их у нас будет две, это Retrofit — который мы будем использовать для запросов на сервер и LifecycleExtentions который нужен для ипользования ViewModelProviders и других классов.</span><br />
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">С библиотеками разобрались, теперь нам нужно создать модель в которую мы будем парсить данные с сервера. Данные мы будем получать с фейкового сервера который я взял отсюда — </span><a href="https://jsonplaceholder.typicode.com/" style="background-color: white; color: #992298; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px; text-decoration-line: none;">jsonplaceholder.typicode.com</a><span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">. Там можно найти много разных запросов которые будут возвращать разные данные, очень удобно для написания примеров. На основе респонса запроса к </span><a href="https://jsonplaceholder.typicode.com/posts" style="background-color: white; color: #992298; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px; text-decoration-line: none;">jsonplaceholder.typicode.com/posts</a><span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;"> создаем модель на сайте </span><a href="http://www.jsonschema2pojo.org/" style="background-color: white; color: #992298; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px; text-decoration-line: none;">www.jsonschema2pojo.org</a><span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;"> и добавляем эту модель к себе в проект.</span><br />
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">PostModel.kt</span><br />
<pre style="background-color: white; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow: auto hidden; padding: 0px; word-break: break-all;"><code class="kotlin hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="color: #a626a4;">import</span> com.google.gson.annotations.Expose
<span class="hljs-keyword" style="color: #a626a4;">import</span> com.google.gson.annotations.SerializedName
<span class="hljs-class"><span class="hljs-keyword" style="color: #a626a4;">class</span> <span class="hljs-title" style="color: #c18401;">PostModel</span> </span>{
<span class="hljs-meta" style="color: #4078f2;">@SerializedName(<span class="hljs-meta-string" style="color: #50a14f;">"userId"</span>)</span>
<span class="hljs-meta" style="color: #4078f2;">@Expose</span>
<span class="hljs-keyword" style="color: #a626a4;">var</span> userId: <span class="hljs-built_in" style="color: #c18401;">Int</span>? = <span class="hljs-literal" style="color: #0184bb;">null</span>
<span class="hljs-meta" style="color: #4078f2;">@SerializedName(<span class="hljs-meta-string" style="color: #50a14f;">"id"</span>)</span>
<span class="hljs-meta" style="color: #4078f2;">@Expose</span>
<span class="hljs-keyword" style="color: #a626a4;">var</span> id: <span class="hljs-built_in" style="color: #c18401;">Int</span>? = <span class="hljs-literal" style="color: #0184bb;">null</span>
<span class="hljs-meta" style="color: #4078f2;">@SerializedName(<span class="hljs-meta-string" style="color: #50a14f;">"title"</span>)</span>
<span class="hljs-meta" style="color: #4078f2;">@Expose</span>
<span class="hljs-keyword" style="color: #a626a4;">var</span> title: String? = <span class="hljs-literal" style="color: #0184bb;">null</span>
<span class="hljs-meta" style="color: #4078f2;">@SerializedName(<span class="hljs-meta-string" style="color: #50a14f;">"body"</span>)</span>
<span class="hljs-meta" style="color: #4078f2;">@Expose</span>
<span class="hljs-keyword" style="color: #a626a4;">var</span> body: String? = <span class="hljs-literal" style="color: #0184bb;">null</span>
}
</code></pre>
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Определяем все нужные параметры которые мы будем использовать, я решил оставить так как оно выглядит в респонсе, что бы не путать, использовать мы будем только title и body.</span><br />
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">API.kt</span><br />
<pre style="background-color: white; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow: auto hidden; padding: 0px; word-break: break-all;"><code class="kotlin hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="color: #a626a4;">import</span> dajver.com.mvvm.api.model.PostModel
<span class="hljs-keyword" style="color: #a626a4;">import</span> retrofit2.Call
<span class="hljs-keyword" style="color: #a626a4;">import</span> retrofit2.http.GET
<span class="hljs-class"><span class="hljs-keyword" style="color: #a626a4;">interface</span> <span class="hljs-title" style="color: #c18401;">API</span> </span>{
<span class="hljs-meta" style="color: #4078f2;">@get:GET</span>(<span class="hljs-string" style="color: #50a14f;">"posts"</span>)
<span class="hljs-keyword" style="color: #a626a4;">val</span> posts: Call<List<PostModel>>
}
</code></pre>
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Тут мы описали в какой запрос мы будем стучаться и каким способом, это стандартный способ работы с Retrofit. Если кто не работал с ним советую, у меня даже </span><a href="http://dajver.blogspot.com/2017/05/retrofit.html" style="background-color: white; color: #992298; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px; text-decoration-line: none;">была статья </a><span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">с примером и описанием работы с этой библиотекой, советую ознакомиться.</span><br />
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">RestClient.kt</span><br />
<pre style="background-color: white; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow: auto hidden; padding: 0px; word-break: break-all;"><code class="kotlin hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="color: #a626a4;">import</span> retrofit2.Retrofit
<span class="hljs-keyword" style="color: #a626a4;">import</span> retrofit2.converter.gson.GsonConverterFactory
<span class="hljs-keyword" style="color: #a626a4;">import</span> retrofit2.converter.scalars.ScalarsConverterFactory
<span class="hljs-class"><span class="hljs-keyword" style="color: #a626a4;">class</span> <span class="hljs-title" style="color: #c18401;">RestClient</span> </span>{
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-keyword" style="color: #a626a4;">val</span> service: API
<span class="hljs-keyword" style="color: #a626a4;">init</span> {
<span class="hljs-keyword" style="color: #a626a4;">val</span> retrofit = Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(ScalarsConverterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.build()
service = retrofit.create(API::<span class="hljs-class"><span class="hljs-keyword" style="color: #a626a4;">class</span>.<span class="hljs-title" style="color: #c18401;">java</span>)</span>
}
<span class="hljs-keyword" style="color: #a626a4;">companion</span> <span class="hljs-keyword" style="color: #a626a4;">object</span> {
<span class="hljs-keyword" style="color: #a626a4;">const</span> <span class="hljs-keyword" style="color: #a626a4;">val</span> BASE_URL = <span class="hljs-string" style="color: #50a14f;">"https://jsonplaceholder.typicode.com/"</span>
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-keyword" style="color: #a626a4;">val</span> instance = RestClient()
<span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">instance</span><span class="hljs-params">()</span></span>: API {
<span class="hljs-keyword" style="color: #a626a4;">return</span> instance.service
}
}
}
</code></pre>
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Здесь мы описываем все настройки для ретрофита, создаем инстанс данного класса для удобного его использования, задаем хост на который мы будем стучатьдля получения респонса и прописываем конвертеры для парсинга респонсом.</span><br />
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Теперь давайте создадим наш класс ViewModel который будет стучаться в RestClient и получать данные, а после получения отправлять их в ViewModel.</span><br />
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">PostViewModel.kt</span><br />
<pre style="background-color: white; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow: auto hidden; padding: 0px; word-break: break-all;"><code class="kotlin hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="color: #a626a4;">import</span> androidx.lifecycle.MutableLiveData
<span class="hljs-keyword" style="color: #a626a4;">import</span> androidx.lifecycle.ViewModel
<span class="hljs-keyword" style="color: #a626a4;">import</span> dajver.com.mvvm.api.RestClient
<span class="hljs-keyword" style="color: #a626a4;">import</span> dajver.com.mvvm.api.model.PostModel
<span class="hljs-keyword" style="color: #a626a4;">import</span> retrofit2.Call
<span class="hljs-keyword" style="color: #a626a4;">import</span> retrofit2.Callback
<span class="hljs-keyword" style="color: #a626a4;">import</span> retrofit2.Response
<span class="hljs-class"><span class="hljs-keyword" style="color: #a626a4;">class</span> <span class="hljs-title" style="color: #c18401;">PostViewModel</span> : <span class="hljs-type" style="color: #986801;">ViewModel</span></span>() {
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-keyword" style="color: #a626a4;">var</span> mutableLiveData: MutableLiveData<List<PostModel>>? = <span class="hljs-literal" style="color: #0184bb;">null</span>
<span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">getPosts</span><span class="hljs-params">()</span></span> : MutableLiveData<List<PostModel>>? {
<span class="hljs-keyword" style="color: #a626a4;">if</span>(mutableLiveData == <span class="hljs-literal" style="color: #0184bb;">null</span>) {
mutableLiveData = MutableLiveData()
loadPosts()
}
<span class="hljs-keyword" style="color: #a626a4;">return</span> mutableLiveData
}
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">loadPosts</span><span class="hljs-params">()</span></span> {
RestClient.instance().posts.enqueue(<span class="hljs-keyword" style="color: #a626a4;">object</span> : Callback<List<PostModel>> {
<span class="hljs-keyword" style="color: #a626a4;">override</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">onResponse</span><span class="hljs-params">(call: <span class="hljs-type" style="color: #986801;">Call</span><<span class="hljs-type" style="color: #986801;">List</span><<span class="hljs-type" style="color: #986801;">PostModel</span>>>, response: <span class="hljs-type" style="color: #986801;">Response</span><<span class="hljs-type" style="color: #986801;">List</span><<span class="hljs-type" style="color: #986801;">PostModel</span>>>)</span></span> {
<span class="hljs-keyword" style="color: #a626a4;">if</span>(response.code() < <span class="hljs-number" style="color: #986801;">400</span>) {
mutableLiveData!!.value = response.body()
}
}
<span class="hljs-keyword" style="color: #a626a4;">override</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">onFailure</span><span class="hljs-params">(call: <span class="hljs-type" style="color: #986801;">Call</span><<span class="hljs-type" style="color: #986801;">List</span><<span class="hljs-type" style="color: #986801;">PostModel</span>>>, t: <span class="hljs-type" style="color: #986801;">Throwable</span>)</span></span> {
t.printStackTrace()
}
})
}
}
</code></pre>
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Мы создали метод loadPosts() который стучится на сервер и получает какой то респонс оттуда, этот респонс он получает в модель List, собственно эту модель мы берем и пихаем в MutableLiveData который хранится в этом классе. А дальше у нас есть метод getPosts() который возвращает нам эту MutableLiveData<List> если он у нас не пустой, а если пустой то он делает запрос на сервер и получает его. В этом случае у вас не будут делаться лишние запросы на сервер когда вы будете гулять между фрагментами или активити, ну и это улучшит перфоманс нашего приложения.</span><br />
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">item_posts.xml</span><br />
<pre style="background-color: white; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow: auto hidden; padding: 0px; word-break: break-all;"><code class="xml hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-meta" style="color: #4078f2;"><?xml version="1.0" encoding="utf-8"?></span>
<span class="hljs-tag"><<span class="hljs-name" style="color: #e45649;">LinearLayout</span> <span class="hljs-attr" style="color: #986801;">xmlns:android</span>=<span class="hljs-string" style="color: #50a14f;">"http://schemas.android.com/apk/res/android"</span>
<span class="hljs-attr" style="color: #986801;">android:orientation</span>=<span class="hljs-string" style="color: #50a14f;">"vertical"</span>
<span class="hljs-attr" style="color: #986801;">android:layout_width</span>=<span class="hljs-string" style="color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="color: #986801;">android:layout_height</span>=<span class="hljs-string" style="color: #50a14f;">"wrap_content"</span> <span class="hljs-attr" style="color: #986801;">android:padding</span>=<span class="hljs-string" style="color: #50a14f;">"10dp"</span>></span>
<span class="hljs-tag"><<span class="hljs-name" style="color: #e45649;">TextView</span>
<span class="hljs-attr" style="color: #986801;">android:text</span>=<span class="hljs-string" style="color: #50a14f;">"TextView"</span>
<span class="hljs-attr" style="color: #986801;">android:layout_width</span>=<span class="hljs-string" style="color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="color: #986801;">android:layout_height</span>=<span class="hljs-string" style="color: #50a14f;">"wrap_content"</span> <span class="hljs-attr" style="color: #986801;">android:id</span>=<span class="hljs-string" style="color: #50a14f;">"@+id/name"</span> <span class="hljs-attr" style="color: #986801;">android:textColor</span>=<span class="hljs-string" style="color: #50a14f;">"@android:color/black"</span>
<span class="hljs-attr" style="color: #986801;">android:textStyle</span>=<span class="hljs-string" style="color: #50a14f;">"bold"</span> <span class="hljs-attr" style="color: #986801;">android:padding</span>=<span class="hljs-string" style="color: #50a14f;">"10dp"</span>/></span>
<span class="hljs-tag"><<span class="hljs-name" style="color: #e45649;">TextView</span>
<span class="hljs-attr" style="color: #986801;">android:text</span>=<span class="hljs-string" style="color: #50a14f;">"TextView"</span>
<span class="hljs-attr" style="color: #986801;">android:layout_width</span>=<span class="hljs-string" style="color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="color: #986801;">android:layout_height</span>=<span class="hljs-string" style="color: #50a14f;">"wrap_content"</span> <span class="hljs-attr" style="color: #986801;">android:id</span>=<span class="hljs-string" style="color: #50a14f;">"@+id/content"</span> <span class="hljs-attr" style="color: #986801;">android:padding</span>=<span class="hljs-string" style="color: #50a14f;">"10dp"</span>
<span class="hljs-attr" style="color: #986801;">android:textSize</span>=<span class="hljs-string" style="color: #50a14f;">"18sp"</span>/></span>
<span class="hljs-tag"></<span class="hljs-name" style="color: #e45649;">LinearLayout</span>></span>
</code></pre>
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Вот так будет выглядеть наш айтем в списке. Просто два текстовых поля.</span><br />
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">PostViewHolder.kt</span><br />
<pre style="background-color: white; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow: auto hidden; padding: 0px; word-break: break-all;"><code class="kotlin hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="color: #a626a4;">import</span> android.view.View
<span class="hljs-keyword" style="color: #a626a4;">import</span> androidx.recyclerview.widget.RecyclerView
<span class="hljs-keyword" style="color: #a626a4;">import</span> dajver.com.mvvm.api.model.PostModel
<span class="hljs-keyword" style="color: #a626a4;">import</span> kotlinx.android.synthetic.main.view_posts.view.*
<span class="hljs-class"><span class="hljs-keyword" style="color: #a626a4;">class</span> <span class="hljs-title" style="color: #c18401;">PostViewHolder</span></span>(itemView: View) : RecyclerView.ViewHolder(itemView) {
<span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">bind</span><span class="hljs-params">(postModel: <span class="hljs-type" style="color: #986801;">PostModel</span>)</span></span> {
itemView.name.text = postModel.title
itemView.content.text = postModel.body
}
}
</code></pre>
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Теперь создадим ViewHolder для отображения данных в адаптере. У нас будет отображатсья title и body из модели.</span><br />
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">PostRecyclerAdapter.kt</span><br />
<pre style="background-color: white; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow: auto hidden; padding: 0px; word-break: break-all;"><code class="kotlin hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="color: #a626a4;">import</span> android.view.LayoutInflater
<span class="hljs-keyword" style="color: #a626a4;">import</span> android.view.ViewGroup
<span class="hljs-keyword" style="color: #a626a4;">import</span> androidx.recyclerview.widget.RecyclerView
<span class="hljs-keyword" style="color: #a626a4;">import</span> dajver.com.mvvm.R
<span class="hljs-keyword" style="color: #a626a4;">import</span> dajver.com.mvvm.adapter.holder.PostViewHolder
<span class="hljs-keyword" style="color: #a626a4;">import</span> dajver.com.mvvm.api.model.PostModel
<span class="hljs-class"><span class="hljs-keyword" style="color: #a626a4;">class</span> <span class="hljs-title" style="color: #c18401;">PostRecyclerAdapter</span></span>(<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-keyword" style="color: #a626a4;">val</span> postList: List<PostModel>) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
<span class="hljs-keyword" style="color: #a626a4;">override</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">onCreateViewHolder</span><span class="hljs-params">(parent: <span class="hljs-type" style="color: #986801;">ViewGroup</span>, viewType: <span class="hljs-type" style="color: #986801;">Int</span>)</span></span>: RecyclerView.ViewHolder {
<span class="hljs-keyword" style="color: #a626a4;">return</span> PostViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.view_posts, parent, <span class="hljs-literal" style="color: #0184bb;">false</span>))
}
<span class="hljs-keyword" style="color: #a626a4;">override</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">onBindViewHolder</span><span class="hljs-params">(holder: <span class="hljs-type" style="color: #986801;">RecyclerView</span>.<span class="hljs-type" style="color: #986801;">ViewHolder</span>, position: <span class="hljs-type" style="color: #986801;">Int</span>)</span></span> {
<span class="hljs-keyword" style="color: #a626a4;">val</span> viewHolder = holder <span class="hljs-keyword" style="color: #a626a4;">as</span> PostViewHolder
viewHolder.bind(postList[position])
}
<span class="hljs-keyword" style="color: #a626a4;">override</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">getItemCount</span><span class="hljs-params">()</span></span>: <span class="hljs-built_in" style="color: #c18401;">Int</span> {
<span class="hljs-keyword" style="color: #a626a4;">return</span> postList.size
}
}
</code></pre>
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Ну и здесь уже создаем адаптер для отображения наших данных из респонса.</span><br />
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">activity_main.xml</span><br />
<pre style="background-color: white; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow: auto hidden; padding: 0px; word-break: break-all;"><code class="xml hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-meta" style="color: #4078f2;"><?xml version="1.0" encoding="utf-8"?></span>
<span class="hljs-tag"><<span class="hljs-name" style="color: #e45649;">LinearLayout</span> <span class="hljs-attr" style="color: #986801;">xmlns:android</span>=<span class="hljs-string" style="color: #50a14f;">"http://schemas.android.com/apk/res/android"</span>
<span class="hljs-attr" style="color: #986801;">xmlns:app</span>=<span class="hljs-string" style="color: #50a14f;">"http://schemas.android.com/apk/res-auto"</span>
<span class="hljs-attr" style="color: #986801;">android:layout_width</span>=<span class="hljs-string" style="color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="color: #986801;">android:layout_height</span>=<span class="hljs-string" style="color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="color: #986801;">android:layout_gravity</span>=<span class="hljs-string" style="color: #50a14f;">"center"</span>
<span class="hljs-attr" style="color: #986801;">android:orientation</span>=<span class="hljs-string" style="color: #50a14f;">"vertical"</span>></span>
<span class="hljs-tag"><<span class="hljs-name" style="color: #e45649;">androidx.recyclerview.widget.RecyclerView</span>
<span class="hljs-attr" style="color: #986801;">android:layout_width</span>=<span class="hljs-string" style="color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="color: #986801;">android:layout_height</span>=<span class="hljs-string" style="color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="color: #986801;">android:id</span>=<span class="hljs-string" style="color: #50a14f;">"@+id/recyclerView"</span>
<span class="hljs-attr" style="color: #986801;">app:layoutManager</span>=<span class="hljs-string" style="color: #50a14f;">"androidx.recyclerview.widget.LinearLayoutManager"</span>
<span class="hljs-attr" style="color: #986801;">android:layout_weight</span>=<span class="hljs-string" style="color: #50a14f;">"0.1"</span>></span>
<span class="hljs-tag"></<span class="hljs-name" style="color: #e45649;">androidx.recyclerview.widget.RecyclerView</span>></span>
<span class="hljs-tag"></<span class="hljs-name" style="color: #e45649;">LinearLayout</span>></span>
</code></pre>
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Активити у нас будет просто с RecyclerView. В XML мы сразу указали что будем использовать LinearLayoutManager для отображения списка.</span><br />
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">MainActivity.kt</span><br />
<pre style="background-color: white; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow: auto hidden; padding: 0px; word-break: break-all;"><code class="kotlin hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="color: #a626a4;">import</span> android.os.Bundle
<span class="hljs-keyword" style="color: #a626a4;">import</span> androidx.appcompat.app.AppCompatActivity
<span class="hljs-keyword" style="color: #a626a4;">import</span> androidx.lifecycle.Observer
<span class="hljs-keyword" style="color: #a626a4;">import</span> androidx.lifecycle.ViewModelProviders
<span class="hljs-keyword" style="color: #a626a4;">import</span> dajver.com.mvvm.adapter.PostRecyclerAdapter
<span class="hljs-keyword" style="color: #a626a4;">import</span> dajver.com.mvvm.api.model.PostModel
<span class="hljs-keyword" style="color: #a626a4;">import</span> dajver.com.mvvm.viewmodel.PostViewModel
<span class="hljs-keyword" style="color: #a626a4;">import</span> kotlinx.android.synthetic.main.activity_main.*
<span class="hljs-class"><span class="hljs-keyword" style="color: #a626a4;">class</span> <span class="hljs-title" style="color: #c18401;">MainActivity</span> : <span class="hljs-type" style="color: #986801;">AppCompatActivity</span></span>() {
<span class="hljs-keyword" style="color: #a626a4;">override</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">onCreate</span><span class="hljs-params">(savedInstanceState: <span class="hljs-type" style="color: #986801;">Bundle</span>?)</span></span> {
<span class="hljs-keyword" style="color: #a626a4;">super</span>.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
<span class="hljs-keyword" style="color: #a626a4;">val</span> model = ViewModelProviders.of(<span class="hljs-keyword" style="color: #a626a4;">this</span>).<span class="hljs-keyword" style="color: #a626a4;">get</span>(PostViewModel::<span class="hljs-class"><span class="hljs-keyword" style="color: #a626a4;">class</span>.<span class="hljs-title" style="color: #c18401;">java</span>!!)</span>
model.getPosts()!!.observe(<span class="hljs-keyword" style="color: #a626a4;">this</span>,
Observer<List<PostModel>> {
<span class="hljs-keyword" style="color: #a626a4;">val</span> adapter = PostRecyclerAdapter(it)
recyclerView.adapter = adapter
})
}
}
</code></pre>
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">В onCreate() у нас помимо инициализации леяута появилось пара новых строк. Нам они нужны для того что бы мы могли отобразить наш список с актуальными данными которые мы получили из ViewModel, которые были получены с сервера.</span><br />
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Еще надо дать пермишены на доступ в интернет в AndroidManifest.xml и собственно все.</span><br />
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">AndroidManifest.xml</span><br />
<pre style="background-color: white; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow: auto hidden; padding: 0px; word-break: break-all;"><code class="xml hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-tag"><<span class="hljs-name" style="color: #e45649;">uses-permission</span> <span class="hljs-attr" style="color: #986801;">android:name</span>=<span class="hljs-string" style="color: #50a14f;">"android.permission.INTERNET"</span> /></span></code></pre>
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Вот такая магия получается у нас, код максимально упрощенный, максимально чистый, любой новые человек в команде посмотрев на него сразу поймет что происходит, как по мне это лучше решение для такого рода задач.</span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;"><br /></span>
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif;"><span style="font-size: large;"><b>Исходники:</b></span></span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif;"><span style="font-size: large;"><b><a href="https://github.com/dajver/MVVMExample">GitHub</a></b></span></span></div>
dajverhttp://www.blogger.com/profile/09427222798699404442noreply@blogger.com0tag:blogger.com,1999:blog-5677605911484164185.post-12693841057807854032019-07-03T15:25:00.001+03:002019-07-03T15:32:59.254+03:00Affter Effect анимация с помощью Lottie<div dir="ltr" style="text-align: left;" trbidi="on">
<div class="separator" style="clear: both; text-align: center;">
</div>
<div style="text-align: left;">
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; text-align: left;">Недавно пришлось столкнуться с такой штукой как работа с анимацией которая была экспортирована из Affter Effect. Она была красивая, все переливалось, но реализовать такое стандартными методами было просто нереально, но потом мне расказали про Lottie которая была создана AirBnb для своих нужд, но в дальнейшем выпущена в публичный доступ для всех желающих. Эта библиотека позволяет проигрывать анимации экспортированные как json файлы из Affter </span><span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; text-align: left;">Effect буквально в пару строчек кода.</span></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://github.com/dajver/LottieAnimationExample/blob/master/images/example.gif?raw=true" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img alt="image" border="0" height="400" src="https://github.com/dajver/LottieAnimationExample/blob/master/images/example.gif?raw=true" style="background-color: white; border-style: none; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px; height: auto; margin-top: 0px; max-width: 100%; vertical-align: middle;" width="225" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Это очень крутая штука и очень мощная, анимаций уже готовых в свободном доступе просто куча. Найти их можно на сайте </span><a href="https://lottiefiles.com/" style="background-color: white; color: #992298; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px; text-decoration-line: none;">lottiefiles.com</a><span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">. Для примера я взял один пример и решил его запустить в этом приложении. </span><a href="https://www.blogger.com/null" name="habracut" style="background-color: white; color: #548eaa; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;"></a><span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Анимация добавляется в проект в папку assets, и прописывается в дальнейшем в вашем layout файле, а в коде можно запускать уже настройки, такие на пример как проигрывание анимации сразу при старте приложения, или цикличное проигрывание без остановки, или на пример запуск по кнопке. Для примера мы сделаем элементарное приложение в котором будем по клику на вью запускать анимацию. Для начала нам нужно создать пустой проект, в котором добавим библиотеку Lottie.</span><br />
<a name='more'></a><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">app/build.gradle</span><br />
<pre style="background-color: white; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow: auto hidden; padding: 0px; word-break: break-all;"><code class="java hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"> implementation <span class="hljs-string" style="color: #50a14f;">'com.airbnb.android:lottie:3.0.7'</span>
</code></pre>
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;"><br /></span>
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Она нам нужна собсвенно для запуска анимации на нашем экране. Так же нам понадобится сама анимация, вы можете ее скачать или с самого сайта </span><a href="https://lottiefiles.com/" style="background-color: white; color: #992298; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px; text-decoration-line: none;">lottiefiles.com</a><span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;"> или же из моего </span><a href="https://github.com/dajver/LottieAnimationExample/blob/master/app/src/main/assets/clapclap.json" style="background-color: white; color: #992298; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px; text-decoration-line: none;">Github</a> <span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">проекта. Далее нам нужно положить ее в папку app/src/main/assets/ и прописать пару строк в main.xml файле.</span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;"><br /></span>
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">activity_main.xml</span><br />
<pre style="background-color: white; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow: auto hidden; padding: 0px; word-break: break-all;"><code class="xml hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-meta" style="color: #4078f2;"><?xml version="1.0" encoding="utf-8"?></span>
<span class="hljs-tag"><<span class="hljs-name" style="color: #e45649;">LinearLayout</span>
<span class="hljs-attr" style="color: #986801;">xmlns:android</span>=<span class="hljs-string" style="color: #50a14f;">"http://schemas.android.com/apk/res/android"</span>
<span class="hljs-attr" style="color: #986801;">xmlns:app</span>=<span class="hljs-string" style="color: #50a14f;">"http://schemas.android.com/apk/res-auto"</span>
<span class="hljs-attr" style="color: #986801;">android:layout_width</span>=<span class="hljs-string" style="color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="color: #986801;">android:layout_height</span>=<span class="hljs-string" style="color: #50a14f;">"match_parent"</span> <span class="hljs-attr" style="color: #986801;">android:gravity</span>=<span class="hljs-string" style="color: #50a14f;">"center"</span>></span>
<span class="hljs-tag"><<span class="hljs-name" style="color: #e45649;">com.airbnb.lottie.LottieAnimationView</span>
<span class="hljs-attr" style="color: #986801;">android:id</span>=<span class="hljs-string" style="color: #50a14f;">"@+id/animationView"</span>
<span class="hljs-attr" style="color: #986801;">android:layout_width</span>=<span class="hljs-string" style="color: #50a14f;">"200dp"</span>
<span class="hljs-attr" style="color: #986801;">android:layout_height</span>=<span class="hljs-string" style="color: #50a14f;">"200dp"</span>
<span class="hljs-attr" style="color: #986801;">app:lottie_fileName</span>=<span class="hljs-string" style="color: #50a14f;">"clapclap.json"</span>/></span>
<span class="hljs-tag"></<span class="hljs-name" style="color: #e45649;">LinearLayout</span>></span>
</code></pre>
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Тут мы прописали LottieAnimationView и указали файл который мы будем проигрывать. Это можно сделать так же из кода, все настройки которые можно установить из xml так же доступны и из кода, по этому каждому как удобно будет.</span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;"><br /></span>
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">MainActivity.kt</span><br />
<pre style="background-color: white; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow: auto hidden; padding: 0px; word-break: break-all;"><code class="kotlin hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="color: #a626a4;">import</span> android.os.Bundle
<span class="hljs-keyword" style="color: #a626a4;">import</span> androidx.appcompat.app.AppCompatActivity
<span class="hljs-keyword" style="color: #a626a4;">import</span> kotlinx.android.synthetic.main.activity_main.*
<span class="hljs-class"><span class="hljs-keyword" style="color: #a626a4;">class</span> <span class="hljs-title" style="color: #c18401;">MainActivity</span> : <span class="hljs-type" style="color: #986801;">AppCompatActivity</span></span>() {
<span class="hljs-keyword" style="color: #a626a4;">override</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">onCreate</span><span class="hljs-params">(savedInstanceState: <span class="hljs-type" style="color: #986801;">Bundle</span>?)</span></span> {
<span class="hljs-keyword" style="color: #a626a4;">super</span>.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
animationView.setOnClickListener {
animationView.playAnimation()
}
}
}
</code></pre>
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">В onCreate мы задали onClickListener вьюхе и проигрываем по клику на нее анимацию, собственно что еще нужно. Так же можно установить листенер на проигрывание анимации что бы знать когда она начала играть и когда закончилась, установить бесконечное проигрывание анимации, отменить проигрыш и собственно все. А что еще надо для счастья?</span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;"><br /></span><span style="color: #222222; font-size: large;"><span style="background-color: white;"><b>Исходники:</b></span></span><br />
<span style="color: #222222; font-size: large;"><span style="background-color: white;"><b><a href="https://github.com/dajver/LottieAnimationExample">GitHub</a></b></span></span></div>
dajverhttp://www.blogger.com/profile/09427222798699404442noreply@blogger.com0tag:blogger.com,1999:blog-5677605911484164185.post-68588010518668688262019-07-02T23:40:00.003+03:002019-07-02T23:49:33.371+03:00AutoPlayRecyclerView для проигрывания видео в списке автоматически<div dir="ltr" style="text-align: left;" trbidi="on">
<span style="background-color: white; color: #222222; font-size: 16px;">Очень давно я ничего не писал себе в блог, но настоло время вспомнить старые добрые времена и снова заняться этим грязным делом. Наверняка многие сталкивались с такой штукой как автоплей в разного рода приложениях, когда ты доходишь до видео в фиде, и оно начинает автоматически играть. Такую штуку можно сделать разными способами, есть готовые библиотеки которые уже реализовали эти решения, есть либы которые имеют баги, ну или в моем случае мне нужно было реализовать не обычный плеер, из-за этого решения которые я находил не подходили просто мне. </span><br />
<div style="text-align: left;">
<span style="color: #222222; font-family: , , "arial" , sans-serif;"><br /></span></div>
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;"></span><br />
<div style="text-align: left;">
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">В случае с этой статьей, я просто приведу пример своего кастомного RecyclerView который я использовал для проигрывания видео в списке. Но так же хочу привести примеры уже готовых решений, таких на пример как <a href="https://github.com/eneim/toro" style="color: #992298; text-decoration-line: none;">Toro Player</a>, который реализован на основе ExoPlayer'a и который выполняет свою работу просто отлично, но к сожалению я не смог найти ему применения у себя в проекте. Но сразу скажу что я советую его всем кто хочет сделать у себя автоплей, стандартный с одним плеером в айтеме — это то что вам нужно. </span></div>
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">
</span>
<br />
<div style="text-align: left;">
<div class="separator" style="clear: both; text-align: center;">
<a href="https://github.com/dajver/AutoPlayRecyclerViewExample/raw/master/image/example.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img alt="image" border="0" height="400" src="https://github.com/dajver/AutoPlayRecyclerViewExample/raw/master/image/example.gif" style="background-color: white; border-style: none; color: #222222; font-size: 16px; height: auto; margin-top: 0px; max-width: 100%; vertical-align: middle;" width="224" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Мой же пример ориентирован больше на людей которые любят собственные решения и которые хотят понимать что происходит у них в приложении и как это все работает. Опять же, сразу скажу что вариант который я использую в этой статье не мое личное решение, я его нашел на просторах Github'a, и при чем не у одного человека, по этому я не могу утверждать кому оно пренадлежит, но к сожалению оно было изобретено до меня и я могу только им пользоваться. :) </span></div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div style="margin-left: 1em; margin-right: 1em;">
</div>
<a name='more'></a><br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Теперь после такого долгого вступления можно и начать кодить. Для начала нужно создать пустой проект в который мы подключим наши библиотеки. Писать я нынче буду на котлине, он более так сказать модный щас, да и в принципе с ним получается на порядок меньше кода, по этому будем ориентироваться на него.</span><br />
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">app/build.gradle</span><br />
<pre style="background-color: white; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow: auto hidden; padding: 0px; word-break: break-all;"><code class="java hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;">android {
...
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
dependencies {
implementation <span class="hljs-string" style="color: #50a14f;">'androidx.appcompat:appcompat:1.0.2'</span>
implementation <span class="hljs-string" style="color: #50a14f;">'io.reactivex.rxjava2:rxjava:2.1.13'</span>
implementation <span class="hljs-string" style="color: #50a14f;">'io.reactivex.rxjava2:rxandroid:2.0.2'</span>
implementation <span class="hljs-string" style="color: #50a14f;">'androidx.recyclerview:recyclerview:1.0.0'</span>
implementation <span class="hljs-string" style="color: #50a14f;">"com.google.android.exoplayer:exoplayer-core:2.9.0"</span>
implementation <span class="hljs-string" style="color: #50a14f;">"com.google.android.exoplayer:exoplayer-hls:2.9.0"</span>
implementation <span class="hljs-string" style="color: #50a14f;">"com.google.android.exoplayer:exoplayer-ui:2.9.0"</span>
}
</code></pre>
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Зачем нам нужна поддержка java 8? Для того что бы мы могли использовать лямбды в нашем коде, так и красивее и выглядит более понятно без простыней реализаций интерфейсов.</span><br />
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">По порядку нафига нам столько библиотек:</span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">— androidx — подключается автоматически и нужен для подключения всех сдк которые нужны для работы с андроид.</span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">— rxjava2 и rxandroid — нужны для того что бы мы могли использовать наш AutoPlayRecyclerView который написан с помощью RxJava</span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">— exoplayer — нужен для работы с видео, с его помощью мы будем проигрывать HLS видео в нашем приложении.</span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">— recyclerview — нужен нам для того что бы мы могли наследоваться от него и создать наш собственный RecyclerView с помощью которого будем проигрывать видео.</span><br />
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Далее нам нужно создать вспомогательные классы для нашего AutoPlayRecyclerView, у нас их будет 2, это ViewHolder и LinearLayoutManager.</span><br />
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">AutoPlayLinearLayoutManager.kt</span><br />
<pre style="background-color: white; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow: auto hidden; padding: 0px; word-break: break-all;"><code class="kotlin hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="color: #a626a4;">import</span> android.content.Context
<span class="hljs-keyword" style="color: #a626a4;">import</span> android.util.Log
<span class="hljs-keyword" style="color: #a626a4;">import</span> androidx.recyclerview.widget.LinearLayoutManager
<span class="hljs-keyword" style="color: #a626a4;">import</span> androidx.recyclerview.widget.RecyclerView
<span class="hljs-class"><span class="hljs-keyword" style="color: #a626a4;">class</span> <span class="hljs-title" style="color: #c18401;">AutoPlayLinearLayoutManager</span></span>(context: Context, orientation: <span class="hljs-built_in" style="color: #c18401;">Int</span>, reverseLayout: <span class="hljs-built_in" style="color: #c18401;">Boolean</span>) :
LinearLayoutManager(context, orientation, reverseLayout) {
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-keyword" style="color: #a626a4;">val</span> isScrollEnabled = <span class="hljs-literal" style="color: #0184bb;">true</span>
<span class="hljs-keyword" style="color: #a626a4;">init</span> {
initialPrefetchItemCount = <span class="hljs-number" style="color: #986801;">10</span>
}
<span class="hljs-keyword" style="color: #a626a4;">override</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">onLayoutChildren</span><span class="hljs-params">(recycler: <span class="hljs-type" style="color: #986801;">RecyclerView</span>.<span class="hljs-type" style="color: #986801;">Recycler</span>?, state: <span class="hljs-type" style="color: #986801;">RecyclerView</span>.<span class="hljs-type" style="color: #986801;">State</span>)</span></span> {
<span class="hljs-keyword" style="color: #a626a4;">try</span> {
<span class="hljs-keyword" style="color: #a626a4;">super</span>.onLayoutChildren(recycler, state)
} <span class="hljs-keyword" style="color: #a626a4;">catch</span> (e: IndexOutOfBoundsException) {
Log.e(<span class="hljs-string" style="color: #50a14f;">"Error"</span>, <span class="hljs-string" style="color: #50a14f;">"IndexOutOfBoundsException in RecyclerView happens"</span>)
}
}
<span class="hljs-keyword" style="color: #a626a4;">override</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">canScrollVertically</span><span class="hljs-params">()</span></span>: <span class="hljs-built_in" style="color: #c18401;">Boolean</span> {
<span class="hljs-keyword" style="color: #a626a4;">return</span> isScrollEnabled
}
}
</code></pre>
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Этот класс нам нужен для нашего кастомного RecyclerView для того что бы ограничить количество активных айтемов на экране что бы не засрать память телефона и тот ушел бы в OutOfMemory, у нас наш RecyclerView будет recyclable. То есть айтемы за пределами экрана будут удаляться и реюзаться.</span><br />
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">VideoHolder.kt</span><br />
<pre style="background-color: white; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow: auto hidden; padding: 0px; word-break: break-all;"><code class="kotlin hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="color: #a626a4;">import</span> android.view.View
<span class="hljs-keyword" style="color: #a626a4;">import</span> androidx.recyclerview.widget.RecyclerView
<span class="hljs-keyword" style="color: #a626a4;">import</span> dajver.com.videorecyclerview.adapter.holder.ViewHolder
<span class="hljs-keyword" style="color: #a626a4;">abstract</span> <span class="hljs-class"><span class="hljs-keyword" style="color: #a626a4;">class</span> <span class="hljs-title" style="color: #c18401;">VideoHolder</span></span>(itemView: View, mOnPlayerVisibleListener: ViewHolder.OnPlayerVisibleListener) : RecyclerView.ViewHolder(itemView) {
<span class="hljs-keyword" style="color: #a626a4;">abstract</span> <span class="hljs-keyword" style="color: #a626a4;">val</span> videoLayout: View
<span class="hljs-keyword" style="color: #a626a4;">abstract</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">playVideo</span><span class="hljs-params">()</span></span>
<span class="hljs-keyword" style="color: #a626a4;">abstract</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">stopVideo</span><span class="hljs-params">()</span></span>
}
</code></pre>
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Тут мы создали отдельный холдер который у нас будет иметь три абстрактных метода через которые мы будем управлять нашим холдером в котором будут наши видео и который будет наследовать этот холдер.</span><br />
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">AutoPlayVideoRecyclerView.java</span><br />
<pre style="background-color: white; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow: auto hidden; padding: 0px; word-break: break-all;"><code class="java hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="color: #a626a4;">import</span> android.annotation.SuppressLint;
<span class="hljs-keyword" style="color: #a626a4;">import</span> android.app.Activity;
<span class="hljs-keyword" style="color: #a626a4;">import</span> android.content.Context;
<span class="hljs-keyword" style="color: #a626a4;">import</span> android.util.AttributeSet;
<span class="hljs-keyword" style="color: #a626a4;">import</span> android.util.DisplayMetrics;
<span class="hljs-keyword" style="color: #a626a4;">import</span> android.view.View;
<span class="hljs-keyword" style="color: #a626a4;">import</span> androidx.annotation.Nullable;
<span class="hljs-keyword" style="color: #a626a4;">import</span> androidx.recyclerview.widget.LinearLayoutManager;
<span class="hljs-keyword" style="color: #a626a4;">import</span> androidx.recyclerview.widget.RecyclerView;
<span class="hljs-keyword" style="color: #a626a4;">import</span> dajver.com.videorecyclerview.player.views.holder.VideoHolder;
<span class="hljs-keyword" style="color: #a626a4;">import</span> dajver.com.videorecyclerview.player.views.manager.AutoPlayLinearLayoutManager;
<span class="hljs-keyword" style="color: #a626a4;">import</span> io.reactivex.Observable;
<span class="hljs-keyword" style="color: #a626a4;">import</span> io.reactivex.ObservableSource;
<span class="hljs-keyword" style="color: #a626a4;">import</span> io.reactivex.Observer;
<span class="hljs-keyword" style="color: #a626a4;">import</span> io.reactivex.android.schedulers.AndroidSchedulers;
<span class="hljs-keyword" style="color: #a626a4;">import</span> io.reactivex.annotations.NonNull;
<span class="hljs-keyword" style="color: #a626a4;">import</span> io.reactivex.disposables.Disposable;
<span class="hljs-keyword" style="color: #a626a4;">import</span> io.reactivex.functions.Function;
<span class="hljs-keyword" style="color: #a626a4;">import</span> io.reactivex.schedulers.Schedulers;
<span class="hljs-keyword" style="color: #a626a4;">import</span> io.reactivex.subjects.PublishSubject;
<span class="hljs-keyword" style="color: #a626a4;">import</span> java.util.concurrent.TimeUnit;
<span class="hljs-keyword" style="color: #a626a4;">public</span> <span class="hljs-class"><span class="hljs-keyword" style="color: #a626a4;">class</span> <span class="hljs-title" style="color: #c18401;">AutoPlayVideoRecyclerView</span> <span class="hljs-keyword" style="color: #a626a4;">extends</span> <span class="hljs-title" style="color: #c18401;">RecyclerView</span> </span>{
<span class="hljs-keyword" style="color: #a626a4;">private</span> PublishSubject<Integer> subject;
<span class="hljs-keyword" style="color: #a626a4;">private</span> VideoHolder handingVideoHolder;
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-keyword" style="color: #a626a4;">int</span> handingPosition = <span class="hljs-number" style="color: #986801;">0</span>;
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-keyword" style="color: #a626a4;">int</span> newPosition = -<span class="hljs-number" style="color: #986801;">1</span>;
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-keyword" style="color: #a626a4;">int</span> heightScreen;
<span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">public</span> <span class="hljs-title" style="color: #4078f2;">AutoPlayVideoRecyclerView</span><span class="hljs-params">(Context context)</span> </span>{
<span class="hljs-keyword" style="color: #a626a4;">super</span>(context);
initView(context);
}
<span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">public</span> <span class="hljs-title" style="color: #4078f2;">AutoPlayVideoRecyclerView</span><span class="hljs-params">(Context context, @Nullable AttributeSet attrs)</span> </span>{
<span class="hljs-keyword" style="color: #a626a4;">super</span>(context, attrs);
initView(context);
}
<span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">public</span> <span class="hljs-title" style="color: #4078f2;">AutoPlayVideoRecyclerView</span><span class="hljs-params">(Context context, @Nullable AttributeSet attrs, <span class="hljs-keyword" style="color: #a626a4;">int</span> defStyle)</span> </span>{
<span class="hljs-keyword" style="color: #a626a4;">super</span>(context, attrs, defStyle);
initView(context);
}
<span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-keyword" style="color: #a626a4;">void</span> <span class="hljs-title" style="color: #4078f2;">initView</span><span class="hljs-params">(Context context)</span> </span>{
setLayoutManager(<span class="hljs-keyword" style="color: #a626a4;">new</span> AutoPlayLinearLayoutManager(getContext(), RecyclerView.VERTICAL, <span class="hljs-keyword" style="color: #a626a4;">false</span>));
getRecycledViewPool().setMaxRecycledViews(<span class="hljs-number" style="color: #986801;">0</span>, <span class="hljs-number" style="color: #986801;">5</span>);
heightScreen = getHeightScreen((Activity) context);
subject = createSubject();
addOnScrollListener(<span class="hljs-keyword" style="color: #a626a4;">new</span> OnScrollListener() {
<span class="hljs-meta" style="color: #4078f2;">@Override</span>
<span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">public</span> <span class="hljs-keyword" style="color: #a626a4;">void</span> <span class="hljs-title" style="color: #4078f2;">onScrolled</span><span class="hljs-params">(RecyclerView recyclerView, <span class="hljs-keyword" style="color: #a626a4;">int</span> dx, <span class="hljs-keyword" style="color: #a626a4;">int</span> dy)</span> </span>{
<span class="hljs-keyword" style="color: #a626a4;">super</span>.onScrolled(recyclerView, dx, dy);
checkPositionHandingViewHolder();
subject.onNext(dy);
}
});
}
<span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-keyword" style="color: #a626a4;">void</span> <span class="hljs-title" style="color: #4078f2;">checkPositionHandingViewHolder</span><span class="hljs-params">()</span> </span>{
<span class="hljs-keyword" style="color: #a626a4;">if</span> (handingVideoHolder == <span class="hljs-keyword" style="color: #a626a4;">null</span>) <span class="hljs-keyword" style="color: #a626a4;">return</span>;
Observable.just(handingVideoHolder)
.map(<span class="hljs-keyword" style="color: #a626a4;">this</span>::getPercentViewHolderInScreen)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(<span class="hljs-keyword" style="color: #a626a4;">new</span> Observer<Float>() {
<span class="hljs-meta" style="color: #4078f2;">@Override</span>
<span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">public</span> <span class="hljs-keyword" style="color: #a626a4;">void</span> <span class="hljs-title" style="color: #4078f2;">onSubscribe</span><span class="hljs-params">(@NonNull Disposable d)</span> </span>{
}
<span class="hljs-meta" style="color: #4078f2;">@Override</span>
<span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">public</span> <span class="hljs-keyword" style="color: #a626a4;">void</span> <span class="hljs-title" style="color: #4078f2;">onNext</span><span class="hljs-params">(@NonNull Float aFloat)</span> </span>{
<span class="hljs-keyword" style="color: #a626a4;">if</span> (aFloat < <span class="hljs-number" style="color: #986801;">50</span> && handingVideoHolder != <span class="hljs-keyword" style="color: #a626a4;">null</span>) {
handingVideoHolder.stopVideo();
handingVideoHolder = <span class="hljs-keyword" style="color: #a626a4;">null</span>;
handingPosition = -<span class="hljs-number" style="color: #986801;">1</span>;
}
}
<span class="hljs-meta" style="color: #4078f2;">@Override</span>
<span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">public</span> <span class="hljs-keyword" style="color: #a626a4;">void</span> <span class="hljs-title" style="color: #4078f2;">onError</span><span class="hljs-params">(@NonNull Throwable e)</span> </span>{
}
<span class="hljs-meta" style="color: #4078f2;">@Override</span>
<span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">public</span> <span class="hljs-keyword" style="color: #a626a4;">void</span> <span class="hljs-title" style="color: #4078f2;">onComplete</span><span class="hljs-params">()</span> </span>{
}
});
}
<span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-keyword" style="color: #a626a4;">int</span> <span class="hljs-title" style="color: #4078f2;">getHeightScreen</span><span class="hljs-params">(Activity context)</span> </span>{
DisplayMetrics displayMetrics = <span class="hljs-keyword" style="color: #a626a4;">new</span> DisplayMetrics();
context.getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
<span class="hljs-keyword" style="color: #a626a4;">return</span> displayMetrics.heightPixels;
}
<span class="hljs-meta" style="color: #4078f2;">@SuppressLint</span>(<span class="hljs-string" style="color: #50a14f;">"CheckResult"</span>)
<span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">private</span> PublishSubject<Integer> <span class="hljs-title" style="color: #4078f2;">createSubject</span><span class="hljs-params">()</span> </span>{
subject = PublishSubject.create();
subject.debounce(<span class="hljs-number" style="color: #986801;">300</span>, TimeUnit.MILLISECONDS)
.filter(value -> <span class="hljs-keyword" style="color: #a626a4;">true</span>)
.switchMap((Function<Integer, ObservableSource<Integer>>) Observable::just)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.doOnNext(integer -> {
playVideo(integer);
})
.subscribe();
<span class="hljs-keyword" style="color: #a626a4;">return</span> subject;
}
<span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-keyword" style="color: #a626a4;">void</span> <span class="hljs-title" style="color: #4078f2;">playVideo</span><span class="hljs-params">(<span class="hljs-keyword" style="color: #a626a4;">float</span> value)</span> </span>{
Observable.just(value)
.map(aFloat -> {
VideoHolder videoHolder = getViewHolderCenterScreen();
<span class="hljs-keyword" style="color: #a626a4;">if</span> (videoHolder == <span class="hljs-keyword" style="color: #a626a4;">null</span>) <span class="hljs-keyword" style="color: #a626a4;">return</span> <span class="hljs-keyword" style="color: #a626a4;">null</span>;
<span class="hljs-keyword" style="color: #a626a4;">if</span> (videoHolder.equals(handingVideoHolder) && handingPosition == newPosition)
<span class="hljs-keyword" style="color: #a626a4;">return</span> <span class="hljs-keyword" style="color: #a626a4;">null</span>;
handingPosition = newPosition;
<span class="hljs-keyword" style="color: #a626a4;">return</span> videoHolder;
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(<span class="hljs-keyword" style="color: #a626a4;">new</span> Observer<VideoHolder>() {
<span class="hljs-meta" style="color: #4078f2;">@Override</span>
<span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">public</span> <span class="hljs-keyword" style="color: #a626a4;">void</span> <span class="hljs-title" style="color: #4078f2;">onSubscribe</span><span class="hljs-params">(@NonNull Disposable d)</span> </span>{
}
<span class="hljs-meta" style="color: #4078f2;">@Override</span>
<span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">public</span> <span class="hljs-keyword" style="color: #a626a4;">void</span> <span class="hljs-title" style="color: #4078f2;">onNext</span><span class="hljs-params">(@NonNull VideoHolder videoHolder)</span> </span>{
<span class="hljs-keyword" style="color: #a626a4;">if</span> (handingVideoHolder != <span class="hljs-keyword" style="color: #a626a4;">null</span>)
handingVideoHolder.stopVideo();
videoHolder.playVideo();
handingVideoHolder = videoHolder;
}
<span class="hljs-meta" style="color: #4078f2;">@Override</span>
<span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">public</span> <span class="hljs-keyword" style="color: #a626a4;">void</span> <span class="hljs-title" style="color: #4078f2;">onError</span><span class="hljs-params">(@NonNull Throwable e)</span> </span>{
}
<span class="hljs-meta" style="color: #4078f2;">@Override</span>
<span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">public</span> <span class="hljs-keyword" style="color: #a626a4;">void</span> <span class="hljs-title" style="color: #4078f2;">onComplete</span><span class="hljs-params">()</span> </span>{
}
});
}
<span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">private</span> VideoHolder <span class="hljs-title" style="color: #4078f2;">getViewHolderCenterScreen</span><span class="hljs-params">()</span> </span>{
<span class="hljs-keyword" style="color: #a626a4;">int</span>[] limitPosition = getLimitPositionInScreen();
<span class="hljs-keyword" style="color: #a626a4;">int</span> min = limitPosition[<span class="hljs-number" style="color: #986801;">0</span>];
<span class="hljs-keyword" style="color: #a626a4;">int</span> max = limitPosition[<span class="hljs-number" style="color: #986801;">1</span>];
VideoHolder viewHolderMax = <span class="hljs-keyword" style="color: #a626a4;">null</span>;
<span class="hljs-keyword" style="color: #a626a4;">float</span> percentMax = <span class="hljs-number" style="color: #986801;">0</span>;
<span class="hljs-keyword" style="color: #a626a4;">for</span> (<span class="hljs-keyword" style="color: #a626a4;">int</span> i = min; i <= max; i++) {
ViewHolder viewHolder = findViewHolderForAdapterPosition(i);
<span class="hljs-keyword" style="color: #a626a4;">if</span> (!(viewHolder <span class="hljs-keyword" style="color: #a626a4;">instanceof</span> VideoHolder)) <span class="hljs-keyword" style="color: #a626a4;">continue</span>;
<span class="hljs-keyword" style="color: #a626a4;">float</span> percentViewHolder = getPercentViewHolderInScreen((VideoHolder) viewHolder);
<span class="hljs-keyword" style="color: #a626a4;">if</span> (percentViewHolder > percentMax && percentViewHolder >= <span class="hljs-number" style="color: #986801;">50</span>) {
percentMax = percentViewHolder;
viewHolderMax = (VideoHolder) viewHolder;
newPosition = i;
}
}
<span class="hljs-keyword" style="color: #a626a4;">return</span> viewHolderMax;
}
<span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-keyword" style="color: #a626a4;">float</span> <span class="hljs-title" style="color: #4078f2;">getPercentViewHolderInScreen</span><span class="hljs-params">(VideoHolder viewHolder)</span> </span>{
<span class="hljs-keyword" style="color: #a626a4;">if</span> (viewHolder == <span class="hljs-keyword" style="color: #a626a4;">null</span>) <span class="hljs-keyword" style="color: #a626a4;">return</span> <span class="hljs-number" style="color: #986801;">0</span>;
View view = viewHolder.getVideoLayout();
<span class="hljs-keyword" style="color: #a626a4;">int</span>[] location = <span class="hljs-keyword" style="color: #a626a4;">new</span> <span class="hljs-keyword" style="color: #a626a4;">int</span>[<span class="hljs-number" style="color: #986801;">2</span>];
view.getLocationOnScreen(location);
<span class="hljs-keyword" style="color: #a626a4;">int</span> viewHeight = view.getHeight();
<span class="hljs-keyword" style="color: #a626a4;">int</span> viewFromY = location[<span class="hljs-number" style="color: #986801;">1</span>];
<span class="hljs-keyword" style="color: #a626a4;">int</span> viewToY = location[<span class="hljs-number" style="color: #986801;">1</span>] + viewHeight;
<span class="hljs-keyword" style="color: #a626a4;">if</span> (viewFromY >= <span class="hljs-number" style="color: #986801;">0</span> && viewToY <= heightScreen) <span class="hljs-keyword" style="color: #a626a4;">return</span> <span class="hljs-number" style="color: #986801;">100</span>;
<span class="hljs-keyword" style="color: #a626a4;">if</span> (viewFromY < <span class="hljs-number" style="color: #986801;">0</span> && viewToY > heightScreen) <span class="hljs-keyword" style="color: #a626a4;">return</span> <span class="hljs-number" style="color: #986801;">100</span>;
<span class="hljs-keyword" style="color: #a626a4;">if</span> (viewFromY < <span class="hljs-number" style="color: #986801;">0</span> && viewToY <= heightScreen)
<span class="hljs-keyword" style="color: #a626a4;">return</span> ((<span class="hljs-keyword" style="color: #a626a4;">float</span>) (viewToY - (-viewFromY)) / viewHeight) * <span class="hljs-number" style="color: #986801;">100</span>;
<span class="hljs-keyword" style="color: #a626a4;">if</span> (viewFromY >= <span class="hljs-number" style="color: #986801;">0</span> && viewToY > heightScreen)
<span class="hljs-keyword" style="color: #a626a4;">return</span> ((<span class="hljs-keyword" style="color: #a626a4;">float</span>) (heightScreen - viewFromY) / viewHeight) * <span class="hljs-number" style="color: #986801;">100</span>;
<span class="hljs-keyword" style="color: #a626a4;">return</span> <span class="hljs-number" style="color: #986801;">0</span>;
}
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-keyword" style="color: #a626a4;">int</span>[] getLimitPositionInScreen() {
<span class="hljs-keyword" style="color: #a626a4;">int</span> findFirstVisibleItemPosition = ((LinearLayoutManager) getLayoutManager()).findFirstVisibleItemPosition();
<span class="hljs-keyword" style="color: #a626a4;">int</span> findFirstCompletelyVisibleItemPosition = ((LinearLayoutManager) getLayoutManager()).findFirstCompletelyVisibleItemPosition();
<span class="hljs-keyword" style="color: #a626a4;">int</span> findLastVisibleItemPosition = ((LinearLayoutManager) getLayoutManager()).findLastVisibleItemPosition();
<span class="hljs-keyword" style="color: #a626a4;">int</span> findLastCompletelyVisibleItemPosition = ((LinearLayoutManager) getLayoutManager()).findLastCompletelyVisibleItemPosition();
<span class="hljs-keyword" style="color: #a626a4;">int</span> min = Math.min(Math.max(findFirstVisibleItemPosition, findFirstCompletelyVisibleItemPosition),
Math.min(findLastVisibleItemPosition, findLastCompletelyVisibleItemPosition));
<span class="hljs-keyword" style="color: #a626a4;">int</span> max = Math.max(Math.min(findFirstVisibleItemPosition, findFirstCompletelyVisibleItemPosition),
Math.max(findLastVisibleItemPosition, findLastCompletelyVisibleItemPosition));
<span class="hljs-keyword" style="color: #a626a4;">return</span> <span class="hljs-keyword" style="color: #a626a4;">new</span> <span class="hljs-keyword" style="color: #a626a4;">int</span>[]{min, max};
}
}
</code></pre>
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Оооо, с чего бы начать, даже не знаю, у насв этом классе надо выделить пару важных методов:</span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">— initView — логично что в этом методе мы инициализируем наш RecyclerView, задаем LayoutManager, говорим что нам нужно хранить максимум 5 айтемов в нашем списке, получаем высоту экрана для расчета какое видео нам нужно включать, и инициализируем ScrollListener что бы далее получать позицию на экране и включать или выключать видео.</span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">— checkPositionHandingViewHolder — расчитывает эту позицию и по текущему VideoHolder'у он стопает видео если он за пределами зоны видимости.</span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">— getHeightScreen — получает высоту экрана.</span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">— createSubject — с задержкой в 300 милисекунд определяет местоположение центра экрана и включает видео которое находится в этом положении. Задержка сделанна для того что бы не нужно было играть каждое видео которое попадает в фокус, а только то на котором пользователь остановился и желает посмотреть.</span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">— playVideo — проигрывает текущее видео, которое оказалось в фокусе у нашего createSubject().</span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">getViewHolderCenterScreen — очевидно что расчитывает центр экрана и находит на нем VideoHolder который нужно проиграть.</span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">— getPercentViewHolderInScreen — расчитывает насколько точно этот VideoHolder нужно играть, вохможно он не настолько в центре экрана как допустим VideoHolder перед ним или после…</span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">— getLimitPositionInScreen — расчитывает лимиты с верху и снизу экрана, собственно он нам говорит что VideoHolder внизу экрана присутствует или нет, и так же про верхнюю часть экрана. Это offset который нужен что бы у нас играли видео не только в центре экрана но и снизу и сверху, на пример когда по центру у нас не 100% от getPercentViewHolderInScreen().</span><br />
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Вот такая сложная фигня этот класс, его единственного я не смог переписать на котлин, в нем просто творится адская магия, но сам факт, эта магия работает и прям очень даже не плохо, главное не тупить :) В целом этот класс у нас готов, дальше нам нужно создать плеер который мы будем использовать для отображения видео.</span><br />
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Для начала нам нужно создать bootstrap который будет хранить в себе все нужные параметры и настройки. Потом создадим все нужные листенеры, енамы и фабрики. А в конце уже будем создавать собственно сам плеер.</span><br />
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">VideoPlayerQuality.kt</span><br />
<pre style="background-color: white; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow: auto hidden; padding: 0px; word-break: break-all;"><code class="kotlin hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="color: #a626a4;">enum</span> <span class="hljs-class"><span class="hljs-keyword" style="color: #a626a4;">class</span> <span class="hljs-title" style="color: #c18401;">VideoPlayerQuality</span> </span>{
LOWEST, ADAPTIVE
}
</code></pre>
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Нам нужен этот енам для того что бы разделить качество видосов на низкое и высокое, потому что HLS это видео поток в котором можно регулировать качество видосов, высокое качество нужно для широкоформатного стриминга, на пример в фулл скрине, или там стрим с телефона на телевизор по chromecast'у, а в списке мы будем использовать LOWEST формат для экономии памяти и батареи.</span><br />
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">StartupTrackSelectionFactory.kt</span><br />
<pre style="background-color: white; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow: auto hidden; padding: 0px; word-break: break-all;"><code class="kotlin hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="color: #a626a4;">import</span> com.google.android.exoplayer2.C
<span class="hljs-keyword" style="color: #a626a4;">import</span> com.google.android.exoplayer2.source.TrackGroup
<span class="hljs-keyword" style="color: #a626a4;">import</span> com.google.android.exoplayer2.trackselection.AdaptiveTrackSelection
<span class="hljs-keyword" style="color: #a626a4;">import</span> com.google.android.exoplayer2.trackselection.TrackSelection
<span class="hljs-keyword" style="color: #a626a4;">import</span> com.google.android.exoplayer2.upstream.BandwidthMeter
<span class="hljs-keyword" style="color: #a626a4;">import</span> com.google.android.exoplayer2.util.Clock
<span class="hljs-class"><span class="hljs-keyword" style="color: #a626a4;">class</span> <span class="hljs-title" style="color: #c18401;">StartupTrackSelectionFactory</span></span>(<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-keyword" style="color: #a626a4;">val</span> bandwidthMeter: BandwidthMeter) : TrackSelection.Factory {
<span class="hljs-keyword" style="color: #a626a4;">override</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">createTrackSelection</span><span class="hljs-params">(
group: <span class="hljs-type" style="color: #986801;">TrackGroup</span>,
bandwidthMeter: <span class="hljs-type" style="color: #986801;">BandwidthMeter</span>,
<span class="hljs-keyword" style="color: #a626a4;">vararg</span> tracks: <span class="hljs-type" style="color: #986801;">Int</span>
)</span></span>: TrackSelection {
<span class="hljs-keyword" style="color: #a626a4;">val</span> adaptiveTrackSelection = AdaptiveTrackSelection(
group,
tracks,
bandwidthMeter,
AdaptiveTrackSelection.DEFAULT_MIN_DURATION_FOR_QUALITY_INCREASE_MS.toLong(),
AdaptiveTrackSelection.DEFAULT_MAX_DURATION_FOR_QUALITY_DECREASE_MS.toLong(),
AdaptiveTrackSelection.DEFAULT_MIN_DURATION_TO_RETAIN_AFTER_DISCARD_MS.toLong(),
AdaptiveTrackSelection.DEFAULT_BANDWIDTH_FRACTION,
AdaptiveTrackSelection.DEFAULT_BUFFERED_FRACTION_TO_LIVE_EDGE_FOR_QUALITY_INCREASE,
AdaptiveTrackSelection.DEFAULT_MIN_TIME_BETWEEN_BUFFER_REEVALUTATION_MS,
Clock.DEFAULT
)
<span class="hljs-keyword" style="color: #a626a4;">var</span> lowestBitrate = Integer.MAX_VALUE
<span class="hljs-keyword" style="color: #a626a4;">var</span> lowestBitrateTrackIndex = C.INDEX_UNSET
<span class="hljs-keyword" style="color: #a626a4;">for</span> (i <span class="hljs-keyword" style="color: #a626a4;">in</span> tracks.indices) {
<span class="hljs-keyword" style="color: #a626a4;">val</span> format = group.getFormat(tracks[i])
<span class="hljs-keyword" style="color: #a626a4;">if</span> (format.bitrate < lowestBitrate) {
lowestBitrateTrackIndex = i
lowestBitrate = format.bitrate
}
adaptiveTrackSelection.blacklist(tracks[i],
BLACKLIST_DURATION
)
}
<span class="hljs-keyword" style="color: #a626a4;">if</span> (lowestBitrateTrackIndex != C.INDEX_UNSET) {
adaptiveTrackSelection.blacklist(tracks[lowestBitrateTrackIndex], <span class="hljs-number" style="color: #986801;">0</span>)
}
<span class="hljs-keyword" style="color: #a626a4;">return</span> adaptiveTrackSelection
}
<span class="hljs-keyword" style="color: #a626a4;">companion</span> <span class="hljs-keyword" style="color: #a626a4;">object</span> {
<span class="hljs-comment" style="color: #a0a1a7; font-style: italic;">// end blacklisting after ten seconds earliest</span>
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-keyword" style="color: #a626a4;">val</span> BLACKLIST_DURATION = (<span class="hljs-number" style="color: #986801;">10</span> * <span class="hljs-number" style="color: #986801;">1000</span>).toLong()
}
}
</code></pre>
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Этот класс нам нужен для адаптивного стриминга, про который я говорил выше, в этом классе мы говорим стриму что стартовать нам нужно как можно быстрее, по этому в начале проигрыша видео, мы видео играем в низком качестве, в самом низком в котором можно, а по мере проигрывания если появляется возможность улучшить его, мы повышаем.</span><br />
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">ExoPlayerVideoPlayerBootstrap.kt</span><br />
<pre style="background-color: white; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow: auto hidden; padding: 0px; word-break: break-all;"><code class="kotlin hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="color: #a626a4;">import</span> android.content.Context
<span class="hljs-keyword" style="color: #a626a4;">import</span> android.net.Uri
<span class="hljs-keyword" style="color: #a626a4;">import</span> android.os.Handler
<span class="hljs-keyword" style="color: #a626a4;">import</span> com.google.android.exoplayer2.*
<span class="hljs-keyword" style="color: #a626a4;">import</span> com.google.android.exoplayer2.DefaultLoadControl.DEFAULT_BUFFER_FOR_PLAYBACK_MS
<span class="hljs-keyword" style="color: #a626a4;">import</span> com.google.android.exoplayer2.DefaultLoadControl.DEFAULT_TARGET_BUFFER_BYTES
<span class="hljs-keyword" style="color: #a626a4;">import</span> com.google.android.exoplayer2.Player.REPEAT_MODE_ALL
<span class="hljs-keyword" style="color: #a626a4;">import</span> com.google.android.exoplayer2.source.hls.HlsMediaSource
<span class="hljs-keyword" style="color: #a626a4;">import</span> com.google.android.exoplayer2.trackselection.AdaptiveTrackSelection
<span class="hljs-keyword" style="color: #a626a4;">import</span> com.google.android.exoplayer2.trackselection.AdaptiveTrackSelection.*
<span class="hljs-keyword" style="color: #a626a4;">import</span> com.google.android.exoplayer2.trackselection.DefaultTrackSelector
<span class="hljs-keyword" style="color: #a626a4;">import</span> com.google.android.exoplayer2.upstream.DefaultAllocator
<span class="hljs-keyword" style="color: #a626a4;">import</span> com.google.android.exoplayer2.upstream.DefaultBandwidthMeter
<span class="hljs-keyword" style="color: #a626a4;">import</span> com.google.android.exoplayer2.upstream.DefaultDataSourceFactory
<span class="hljs-keyword" style="color: #a626a4;">import</span> com.google.android.exoplayer2.util.Util
<span class="hljs-keyword" style="color: #a626a4;">import</span> dajver.com.videorecyclerview.player.bootstrap.enums.VideoPlayerQuality
<span class="hljs-keyword" style="color: #a626a4;">import</span> dajver.com.videorecyclerview.player.bootstrap.factory.StartupTrackSelectionFactory
<span class="hljs-keyword" style="color: #a626a4;">open</span> <span class="hljs-class"><span class="hljs-keyword" style="color: #a626a4;">class</span> <span class="hljs-title" style="color: #c18401;">ExoPlayerVideoPlayerBootstrap</span></span>(context: Context, videoPlayerQuality: VideoPlayerQuality) {
<span class="hljs-keyword" style="color: #a626a4;">var</span> exoPlayer: SimpleExoPlayer
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-keyword" style="color: #a626a4;">var</span> mContext: Context
<span class="hljs-keyword" style="color: #a626a4;">var</span> isVideoPrepared = <span class="hljs-literal" style="color: #0184bb;">false</span>
<span class="hljs-keyword" style="color: #a626a4;">var</span> isVideoPaused = <span class="hljs-literal" style="color: #0184bb;">false</span>;
<span class="hljs-keyword" style="color: #a626a4;">var</span> isAppStopped = <span class="hljs-literal" style="color: #0184bb;">false</span>
<span class="hljs-keyword" style="color: #a626a4;">var</span> isBuffering = <span class="hljs-literal" style="color: #0184bb;">false</span>
<span class="hljs-keyword" style="color: #a626a4;">init</span> {
<span class="hljs-keyword" style="color: #a626a4;">val</span> trackSelector = DefaultTrackSelector()
<span class="hljs-keyword" style="color: #a626a4;">if</span> (videoPlayerQuality == VideoPlayerQuality.LOWEST) {
<span class="hljs-comment" style="color: #a0a1a7; font-style: italic;">// low quality</span>
trackSelector.setParameters(lowQualityTrackSelectorFactory())
} <span class="hljs-keyword" style="color: #a626a4;">else</span> {
<span class="hljs-comment" style="color: #a0a1a7; font-style: italic;">// high quality</span>
trackSelector.setParameters(highQualityTrackSelectorFactory())
}
<span class="hljs-keyword" style="color: #a626a4;">val</span> loadControl = DefaultLoadControl(
DefaultAllocator(<span class="hljs-literal" style="color: #0184bb;">true</span>, C.DEFAULT_BUFFER_SEGMENT_SIZE),
DEFAULT_MIN_BUFFER_SIZE_MS,
DEFAULT_MAX_BUFFER_SIZE_MS,
DEFAULT_BUFFER_FOR_PLAYBACK_MS,
DEFAULT_BUFFER_FOR_PLAYBACK_AFTER_REBUFFER_MS,
DEFAULT_TARGET_BUFFER_BYTES,
DEFAULT_PRIORITZE_TIME_OVER_THREADS
)
exoPlayer = ExoPlayerFactory.newSimpleInstance(context, DefaultRenderersFactory(context), trackSelector, loadControl)
exoPlayer.setRepeatMode(REPEAT_MODE_ALL)
mContext = context
}
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">lowQualityTrackSelectorFactory</span><span class="hljs-params">()</span></span>: DefaultTrackSelector.ParametersBuilder {
<span class="hljs-keyword" style="color: #a626a4;">val</span> bandwidthMeter = DefaultBandwidthMeter()
<span class="hljs-keyword" style="color: #a626a4;">val</span> adaptiveVideoTrackSelection =
StartupTrackSelectionFactory(bandwidthMeter)
<span class="hljs-keyword" style="color: #a626a4;">val</span> trackSelector = DefaultTrackSelector(adaptiveVideoTrackSelection)
<span class="hljs-keyword" style="color: #a626a4;">val</span> parameters: DefaultTrackSelector.ParametersBuilder
parameters = trackSelector.parameters.buildUpon()
parameters.setForceLowestBitrate(<span class="hljs-literal" style="color: #0184bb;">true</span>)
parameters.setAllowNonSeamlessAdaptiveness(<span class="hljs-literal" style="color: #0184bb;">true</span>)
<span class="hljs-keyword" style="color: #a626a4;">return</span> parameters
}
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">highQualityTrackSelectorFactory</span><span class="hljs-params">()</span></span>: DefaultTrackSelector.ParametersBuilder {
<span class="hljs-keyword" style="color: #a626a4;">val</span> parameters: DefaultTrackSelector.ParametersBuilder
<span class="hljs-keyword" style="color: #a626a4;">val</span> bandwidthMeter = DefaultBandwidthMeter()
<span class="hljs-keyword" style="color: #a626a4;">val</span> videoTrackSelectionFactory = AdaptiveTrackSelection.Factory(bandwidthMeter,
DEFAULT_MIN_DURATION_FOR_QUALITY_INCREASE_MS,
DEFAULT_MAX_DURATION_FOR_QUALITY_DECREASE_MS,
DEFAULT_MIN_DURATION_TO_RETAIN_AFTER_DISCARD_MS,
DEFAULT_BANDWIDTH_FRACTION)
<span class="hljs-keyword" style="color: #a626a4;">val</span> trackSelector = DefaultTrackSelector(videoTrackSelectionFactory)
parameters = trackSelector.parameters.buildUpon()
parameters.setForceHighestSupportedBitrate(<span class="hljs-literal" style="color: #0184bb;">true</span>)
parameters.setAllowNonSeamlessAdaptiveness(<span class="hljs-literal" style="color: #0184bb;">true</span>)
<span class="hljs-keyword" style="color: #a626a4;">return</span> parameters
}
<span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">buildMediaSource</span><span class="hljs-params">(uri: <span class="hljs-type" style="color: #986801;">Uri</span>)</span></span>: HlsMediaSource {
<span class="hljs-keyword" style="color: #a626a4;">val</span> defaultBandwidthMeter = DefaultBandwidthMeter()
<span class="hljs-keyword" style="color: #a626a4;">val</span> dataSourceFactory = DefaultDataSourceFactory(mContext, Util.getUserAgent(mContext, <span class="hljs-string" style="color: #50a14f;">"Exo2"</span>), defaultBandwidthMeter)
<span class="hljs-keyword" style="color: #a626a4;">return</span> HlsMediaSource.Factory(dataSourceFactory).setAllowChunklessPreparation(<span class="hljs-literal" style="color: #0184bb;">true</span>).createMediaSource(uri, Handler(), <span class="hljs-literal" style="color: #0184bb;">null</span>)
}
<span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">release</span><span class="hljs-params">()</span></span> {
exoPlayer.release()
}
<span class="hljs-keyword" style="color: #a626a4;">companion</span> <span class="hljs-keyword" style="color: #a626a4;">object</span> {
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-keyword" style="color: #a626a4;">const</span> <span class="hljs-keyword" style="color: #a626a4;">val</span> DEFAULT_MIN_BUFFER_SIZE_MS = <span class="hljs-number" style="color: #986801;">2600</span>
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-keyword" style="color: #a626a4;">const</span> <span class="hljs-keyword" style="color: #a626a4;">val</span> DEFAULT_MAX_BUFFER_SIZE_MS = <span class="hljs-number" style="color: #986801;">3000</span>
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-keyword" style="color: #a626a4;">const</span> <span class="hljs-keyword" style="color: #a626a4;">val</span> DEFAULT_BUFFER_FOR_PLAYBACK_AFTER_REBUFFER_MS = <span class="hljs-number" style="color: #986801;">2000</span>
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-keyword" style="color: #a626a4;">const</span> <span class="hljs-keyword" style="color: #a626a4;">val</span> DEFAULT_PRIORITZE_TIME_OVER_THREADS = <span class="hljs-literal" style="color: #0184bb;">true</span>
}
}
</code></pre>
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Что же у нас тут происходит, а происходит вот что, в теле init мы определяем в каком формате нам нужно настраивать поток, и устанавливаем track selector который выбирает в каком качестве играть, в низком или в высоком. Далее создаем SimpleExoPlayer и инициализируем его и указываем что видео у нас будут играть по кругу.</span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">— lowQualityTrackSelectorFactory и highQualityTrackSelectorFactory — нам нужны чисто для сокращения кода в init, в первом мы устанавливаем низкое качество потока, во втором высокое.</span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">— buildMediaSource — нужен для инициализации потока который мы будем проигрывать, собственно тут мы указываем ссылку на видео которое хотим проиграть.</span><br />
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Так же нам понадобится листенер который будет использовать ExoPlayer для понимания статуса видео, готово ли оно для проигрывания или может оно буферится, или запаузено…</span><br />
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">PlayerStateChangedListener.kt</span><br />
<pre style="background-color: white; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow: auto hidden; padding: 0px; word-break: break-all;"><code class="kotlin hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="color: #a626a4;">import</span> android.util.Log
<span class="hljs-keyword" style="color: #a626a4;">import</span> com.google.android.exoplayer2.ExoPlaybackException
<span class="hljs-keyword" style="color: #a626a4;">import</span> com.google.android.exoplayer2.PlaybackParameters
<span class="hljs-keyword" style="color: #a626a4;">import</span> com.google.android.exoplayer2.Player
<span class="hljs-keyword" style="color: #a626a4;">import</span> com.google.android.exoplayer2.Timeline
<span class="hljs-keyword" style="color: #a626a4;">import</span> com.google.android.exoplayer2.source.TrackGroupArray
<span class="hljs-keyword" style="color: #a626a4;">import</span> com.google.android.exoplayer2.trackselection.TrackSelectionArray
<span class="hljs-class"><span class="hljs-keyword" style="color: #a626a4;">class</span> <span class="hljs-title" style="color: #c18401;">PlayerStateChangedListener</span></span>(<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-keyword" style="color: #a626a4;">val</span> onPlayerStateChangedListener: OnPlayerStateChangedListener) :
Player.EventListener {
<span class="hljs-keyword" style="color: #a626a4;">override</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">onTimelineChanged</span><span class="hljs-params">(timeline: <span class="hljs-type" style="color: #986801;">Timeline</span>?, manifest: <span class="hljs-type" style="color: #986801;">Any</span>?, reason: <span class="hljs-type" style="color: #986801;">Int</span>)</span></span> {}
<span class="hljs-keyword" style="color: #a626a4;">override</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">onTracksChanged</span><span class="hljs-params">(trackGroups: <span class="hljs-type" style="color: #986801;">TrackGroupArray</span>?, trackSelections: <span class="hljs-type" style="color: #986801;">TrackSelectionArray</span>?)</span></span> {}
<span class="hljs-keyword" style="color: #a626a4;">override</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">onLoadingChanged</span><span class="hljs-params">(isLoading: <span class="hljs-type" style="color: #986801;">Boolean</span>)</span></span> {}
<span class="hljs-keyword" style="color: #a626a4;">override</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">onPlayerStateChanged</span><span class="hljs-params">(playWhenReady: <span class="hljs-type" style="color: #986801;">Boolean</span>, playbackState: <span class="hljs-type" style="color: #986801;">Int</span>)</span></span> {
onPlayerStateChangedListener.onPlayerStateChanged(playWhenReady, playbackState, <span class="hljs-literal" style="color: #0184bb;">false</span>)
}
<span class="hljs-keyword" style="color: #a626a4;">override</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">onRepeatModeChanged</span><span class="hljs-params">(repeatMode: <span class="hljs-type" style="color: #986801;">Int</span>)</span></span> {}
<span class="hljs-keyword" style="color: #a626a4;">override</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">onShuffleModeEnabledChanged</span><span class="hljs-params">(shuffleModeEnabled: <span class="hljs-type" style="color: #986801;">Boolean</span>)</span></span> {}
<span class="hljs-keyword" style="color: #a626a4;">override</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">onPlayerError</span><span class="hljs-params">(error: <span class="hljs-type" style="color: #986801;">ExoPlaybackException</span>?)</span></span> {
<span class="hljs-keyword" style="color: #a626a4;">when</span> (error!!.type) {
ExoPlaybackException.TYPE_SOURCE -> Log.e(TAG, <span class="hljs-string" style="color: #50a14f;">"TYPE_SOURCE: "</span> + error.sourceException.message)
ExoPlaybackException.TYPE_RENDERER -> Log.e(TAG, <span class="hljs-string" style="color: #50a14f;">"TYPE_RENDERER: "</span> + error.rendererException.message)
ExoPlaybackException.TYPE_UNEXPECTED -> Log.e(TAG, <span class="hljs-string" style="color: #50a14f;">"TYPE_UNEXPECTED: "</span> + error.unexpectedException.message)
}
}
<span class="hljs-keyword" style="color: #a626a4;">override</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">onPositionDiscontinuity</span><span class="hljs-params">(reason: <span class="hljs-type" style="color: #986801;">Int</span>)</span></span> {}
<span class="hljs-keyword" style="color: #a626a4;">override</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">onPlaybackParametersChanged</span><span class="hljs-params">(playbackParameters: <span class="hljs-type" style="color: #986801;">PlaybackParameters</span>?)</span></span> {}
<span class="hljs-keyword" style="color: #a626a4;">override</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">onSeekProcessed</span><span class="hljs-params">()</span></span> {}
<span class="hljs-class"><span class="hljs-keyword" style="color: #a626a4;">interface</span> <span class="hljs-title" style="color: #c18401;">OnPlayerStateChangedListener</span> </span>{
<span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">onPlayerStateChanged</span><span class="hljs-params">(playWhenReady: <span class="hljs-type" style="color: #986801;">Boolean</span>, playbackState: <span class="hljs-type" style="color: #986801;">Int</span>, status: <span class="hljs-type" style="color: #986801;">Boolean</span>)</span></span>
}
<span class="hljs-keyword" style="color: #a626a4;">companion</span> <span class="hljs-keyword" style="color: #a626a4;">object</span> {
<span class="hljs-keyword" style="color: #a626a4;">val</span> TAG = PlayerStateChangedListener::<span class="hljs-class"><span class="hljs-keyword" style="color: #a626a4;">class</span>.<span class="hljs-title" style="color: #c18401;">java</span>.<span class="hljs-title" style="color: #c18401;">simpleName</span></span>
}
}
</code></pre>
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Собственно метод onPlayerStateChanged и нужен, его мы и дублируем в наш плеер через интерфейс, остальные методы для нас бесполезны, ну кроме onPlayerError, но он и так выведет нам нужную инфу в случае ошибки в лог.</span><br />
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Теперь мы дошли наконец-то до нашего плеера, ура! Но для начала давайте посмотрим как выглядит xml у плеера.</span><br />
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">view_video_player.xml</span><br />
<pre style="background-color: white; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow: auto hidden; padding: 0px; word-break: break-all;"><code class="xml hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-meta" style="color: #4078f2;"><?xml version="1.0" encoding="utf-8"?></span>
<span class="hljs-tag"><<span class="hljs-name" style="color: #e45649;">LinearLayout</span> <span class="hljs-attr" style="color: #986801;">xmlns:android</span>=<span class="hljs-string" style="color: #50a14f;">"http://schemas.android.com/apk/res/android"</span>
<span class="hljs-attr" style="color: #986801;">xmlns:app</span>=<span class="hljs-string" style="color: #50a14f;">"http://schemas.android.com/apk/res-auto"</span>
<span class="hljs-attr" style="color: #986801;">android:layout_width</span>=<span class="hljs-string" style="color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="color: #986801;">android:layout_height</span>=<span class="hljs-string" style="color: #50a14f;">"wrap_content"</span>
<span class="hljs-attr" style="color: #986801;">android:orientation</span>=<span class="hljs-string" style="color: #50a14f;">"vertical"</span>></span>
<span class="hljs-tag"><<span class="hljs-name" style="color: #e45649;">RelativeLayout</span>
<span class="hljs-attr" style="color: #986801;">android:layout_width</span>=<span class="hljs-string" style="color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="color: #986801;">android:layout_height</span>=<span class="hljs-string" style="color: #50a14f;">"wrap_content"</span>
<span class="hljs-attr" style="color: #986801;">android:layout_weight</span>=<span class="hljs-string" style="color: #50a14f;">"0.1"</span>
<span class="hljs-attr" style="color: #986801;">android:orientation</span>=<span class="hljs-string" style="color: #50a14f;">"horizontal"</span>></span>
<span class="hljs-tag"><<span class="hljs-name" style="color: #e45649;">com.google.android.exoplayer2.ui.PlayerView</span>
<span class="hljs-attr" style="color: #986801;">android:id</span>=<span class="hljs-string" style="color: #50a14f;">"@+id/exoVideoPlayer"</span>
<span class="hljs-attr" style="color: #986801;">android:layout_width</span>=<span class="hljs-string" style="color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="color: #986801;">android:layout_height</span>=<span class="hljs-string" style="color: #50a14f;">"match_parent"</span> ></span>
<span class="hljs-tag"></<span class="hljs-name" style="color: #e45649;">com.google.android.exoplayer2.ui.PlayerView</span>></span>
<span class="hljs-tag"><<span class="hljs-name" style="color: #e45649;">ProgressBar</span>
<span class="hljs-attr" style="color: #986801;">android:id</span>=<span class="hljs-string" style="color: #50a14f;">"@+id/progressBar"</span>
<span class="hljs-attr" style="color: #986801;">style</span>=<span class="hljs-string" style="color: #50a14f;">"?android:attr/progressBarStyle"</span>
<span class="hljs-attr" style="color: #986801;">android:layout_width</span>=<span class="hljs-string" style="color: #50a14f;">"wrap_content"</span>
<span class="hljs-attr" style="color: #986801;">android:layout_height</span>=<span class="hljs-string" style="color: #50a14f;">"wrap_content"</span>
<span class="hljs-attr" style="color: #986801;">android:layout_centerInParent</span>=<span class="hljs-string" style="color: #50a14f;">"true"</span>
<span class="hljs-attr" style="color: #986801;">android:visibility</span>=<span class="hljs-string" style="color: #50a14f;">"gone"</span> /></span>
<span class="hljs-tag"></<span class="hljs-name" style="color: #e45649;">RelativeLayout</span>></span>
<span class="hljs-tag"></<span class="hljs-name" style="color: #e45649;">LinearLayout</span>></span>
</code></pre>
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Здесь у нас все придельно тривиально, у нас есть PlayerView и поверх него у нас лежит ProgressBar который будет показываться при загрузке видео и будет прятаться при включении потока.</span><br />
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">VideoPlayerView.kt</span><br />
<pre style="background-color: white; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow: auto hidden; padding: 0px; word-break: break-all;"><code class="kotlin hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="color: #a626a4;">import</span> android.app.Activity
<span class="hljs-keyword" style="color: #a626a4;">import</span> android.content.Context
<span class="hljs-keyword" style="color: #a626a4;">import</span> android.net.Uri
<span class="hljs-keyword" style="color: #a626a4;">import</span> android.util.AttributeSet
<span class="hljs-keyword" style="color: #a626a4;">import</span> android.view.LayoutInflater
<span class="hljs-keyword" style="color: #a626a4;">import</span> android.view.View
<span class="hljs-keyword" style="color: #a626a4;">import</span> android.widget.LinearLayout
<span class="hljs-keyword" style="color: #a626a4;">import</span> androidx.customview.widget.ViewDragHelper.STATE_IDLE
<span class="hljs-keyword" style="color: #a626a4;">import</span> com.google.android.exoplayer2.Player
<span class="hljs-keyword" style="color: #a626a4;">import</span> com.google.android.exoplayer2.Player.STATE_ENDED
<span class="hljs-keyword" style="color: #a626a4;">import</span> com.google.android.exoplayer2.Player.STATE_READY
<span class="hljs-keyword" style="color: #a626a4;">import</span> com.google.android.exoplayer2.SimpleExoPlayer
<span class="hljs-keyword" style="color: #a626a4;">import</span> com.google.android.exoplayer2.source.MediaSource
<span class="hljs-keyword" style="color: #a626a4;">import</span> com.google.android.exoplayer2.ui.AspectRatioFrameLayout
<span class="hljs-keyword" style="color: #a626a4;">import</span> dajver.com.videorecyclerview.adapter.holder.ViewHolder
<span class="hljs-keyword" style="color: #a626a4;">import</span> dajver.com.videorecyclerview.models.VideosModel
<span class="hljs-keyword" style="color: #a626a4;">import</span> dajver.com.videorecyclerview.player.bootstrap.ExoPlayerVideoPlayerBootstrap
<span class="hljs-keyword" style="color: #a626a4;">import</span> dajver.com.videorecyclerview.player.bootstrap.enums.VideoPlayerQuality
<span class="hljs-keyword" style="color: #a626a4;">import</span> dajver.com.videorecyclerview.player.listener.PlayerStateChangedListener
<span class="hljs-keyword" style="color: #a626a4;">import</span> kotlinx.android.synthetic.main.view_video_player.view.*
<span class="hljs-keyword" style="color: #a626a4;">open</span> <span class="hljs-class"><span class="hljs-keyword" style="color: #a626a4;">class</span> <span class="hljs-title" style="color: #c18401;">VideoPlayerView</span> : <span class="hljs-type" style="color: #986801;">LinearLayout</span>, <span class="hljs-type" style="color: #986801;">PlayerStateChangedListener.OnPlayerStateChangedListener {</span></span>
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-keyword" style="color: #a626a4;">lateinit</span> <span class="hljs-keyword" style="color: #a626a4;">var</span> model: VideosModel
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-keyword" style="color: #a626a4;">lateinit</span> <span class="hljs-keyword" style="color: #a626a4;">var</span> exoPlayerVideoPlayerBootstrap: ExoPlayerVideoPlayerBootstrap
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-keyword" style="color: #a626a4;">var</span> player: SimpleExoPlayer? = <span class="hljs-literal" style="color: #0184bb;">null</span>
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-keyword" style="color: #a626a4;">var</span> quality: VideoPlayerQuality? = <span class="hljs-literal" style="color: #0184bb;">null</span>
<span class="hljs-keyword" style="color: #a626a4;">val</span> videoHeight: <span class="hljs-built_in" style="color: #c18401;">Int</span> <span class="hljs-keyword" style="color: #a626a4;">get</span>() {
<span class="hljs-keyword" style="color: #a626a4;">val</span> metrics = context.resources.displayMetrics
(context <span class="hljs-keyword" style="color: #a626a4;">as</span> Activity).windowManager.defaultDisplay.getRealMetrics(metrics)
<span class="hljs-keyword" style="color: #a626a4;">val</span> ratio = metrics.widthPixels * metrics.density / (metrics.heightPixels * metrics.density)
<span class="hljs-keyword" style="color: #a626a4;">val</span> screenHeight = (metrics.widthPixels * ratio).toInt()
<span class="hljs-keyword" style="color: #a626a4;">return</span> screenHeight + PLAYER_RATIO_HEIGHT_OFFSET
}
<span class="hljs-keyword" style="color: #a626a4;">constructor</span>(context: Context) : <span class="hljs-keyword" style="color: #a626a4;">super</span>(context) {
<span class="hljs-keyword" style="color: #a626a4;">init</span>()
}
<span class="hljs-keyword" style="color: #a626a4;">constructor</span>(context: Context, attrs: AttributeSet?) : <span class="hljs-keyword" style="color: #a626a4;">super</span>(context, attrs) {
<span class="hljs-keyword" style="color: #a626a4;">init</span>()
}
<span class="hljs-keyword" style="color: #a626a4;">constructor</span>(context: Context, attrs: AttributeSet?, defStyleAttr: <span class="hljs-built_in" style="color: #c18401;">Int</span>) : <span class="hljs-keyword" style="color: #a626a4;">super</span>(context, attrs, defStyleAttr) {
<span class="hljs-keyword" style="color: #a626a4;">init</span>()
}
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">init</span><span class="hljs-params">()</span></span> {
<span class="hljs-keyword" style="color: #a626a4;">val</span> inflater = LayoutInflater.from(context)
inflater.inflate(dajver.com.videorecyclerview.R.layout.view_video_player, <span class="hljs-keyword" style="color: #a626a4;">this</span>)
setup(VideoPlayerQuality.LOWEST)
}
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">setup</span><span class="hljs-params">(quality: <span class="hljs-type" style="color: #986801;">VideoPlayerQuality</span>)</span></span> {
<span class="hljs-keyword" style="color: #a626a4;">this</span>.quality = quality
}
<span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">initPlayer</span><span class="hljs-params">(videosModel: <span class="hljs-type" style="color: #986801;">VideosModel</span>, onPlayerVisibleListener: <span class="hljs-type" style="color: #986801;">ViewHolder</span>.<span class="hljs-type" style="color: #986801;">OnPlayerVisibleListener</span>?)</span></span> {
<span class="hljs-keyword" style="color: #a626a4;">this</span>.model = videosModel
exoPlayerVideoPlayerBootstrap = ExoPlayerVideoPlayerBootstrap(context, quality!!)
exoPlayerVideoPlayerBootstrap.isVideoPrepared = <span class="hljs-literal" style="color: #0184bb;">false</span>
<span class="hljs-keyword" style="color: #a626a4;">if</span> (player == <span class="hljs-literal" style="color: #0184bb;">null</span>) {
player = exoPlayerVideoPlayerBootstrap.exoPlayer
<span class="hljs-keyword" style="color: #a626a4;">if</span> (exoVideoPlayer != <span class="hljs-literal" style="color: #0184bb;">null</span>) {
exoVideoPlayer!!.setPlayer(player)
exoVideoPlayer!!.keepScreenOn
exoVideoPlayer!!.setKeepContentOnPlayerReset(<span class="hljs-literal" style="color: #0184bb;">true</span>)
exoVideoPlayer!!.useController = <span class="hljs-literal" style="color: #0184bb;">false</span>
exoVideoPlayer!!.resizeMode = AspectRatioFrameLayout.RESIZE_MODE_FILL
}
<span class="hljs-keyword" style="color: #a626a4;">val</span> mediaSource: MediaSource
mediaSource = exoPlayerVideoPlayerBootstrap.buildMediaSource(Uri.parse(videosModel.videoUrl))
player!!.prepare(mediaSource, <span class="hljs-literal" style="color: #0184bb;">true</span>, <span class="hljs-literal" style="color: #0184bb;">true</span>)
player!!.addListener(PlayerStateChangedListener(<span class="hljs-keyword" style="color: #a626a4;">this</span>))
onPlayerVisibleListener?.onActivePlayerView(<span class="hljs-keyword" style="color: #a626a4;">this</span>)
}
}
<span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">playVideo</span><span class="hljs-params">()</span></span> {
progressBar!!.visibility = View.VISIBLE
exoPlayerVideoPlayerBootstrap.isAppStopped = <span class="hljs-literal" style="color: #0184bb;">false</span>
<span class="hljs-keyword" style="color: #a626a4;">if</span> (player != <span class="hljs-literal" style="color: #0184bb;">null</span>) {
player!!.playWhenReady = <span class="hljs-literal" style="color: #0184bb;">true</span>
player!!.playbackState
}
}
<span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">pauseVideo</span><span class="hljs-params">()</span></span> {
<span class="hljs-keyword" style="color: #a626a4;">if</span> (player != <span class="hljs-literal" style="color: #0184bb;">null</span>) {
player!!.playWhenReady = <span class="hljs-literal" style="color: #0184bb;">false</span>
player!!.playbackState
}
exoPlayerVideoPlayerBootstrap.isVideoPaused = <span class="hljs-literal" style="color: #0184bb;">true</span>
}
<span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">resumeVideo</span><span class="hljs-params">()</span></span> {
<span class="hljs-keyword" style="color: #a626a4;">if</span> (player != <span class="hljs-literal" style="color: #0184bb;">null</span>) {
player!!.playWhenReady = <span class="hljs-literal" style="color: #0184bb;">true</span>
player!!.playbackState
}
exoPlayerVideoPlayerBootstrap.isVideoPaused = <span class="hljs-literal" style="color: #0184bb;">false</span>
}
<span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">stopVideo</span><span class="hljs-params">()</span></span> {
progressBar!!.visibility = View.GONE
exoPlayerVideoPlayerBootstrap.isVideoPrepared = <span class="hljs-literal" style="color: #0184bb;">false</span>
exoPlayerVideoPlayerBootstrap.isAppStopped = <span class="hljs-literal" style="color: #0184bb;">true</span>
<span class="hljs-keyword" style="color: #a626a4;">if</span> (player != <span class="hljs-literal" style="color: #0184bb;">null</span>) {
releasePlayer()
}
}
<span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">releasePlayer</span><span class="hljs-params">()</span></span> {
<span class="hljs-keyword" style="color: #a626a4;">if</span> (player != <span class="hljs-literal" style="color: #0184bb;">null</span>) {
player!!.playWhenReady = <span class="hljs-literal" style="color: #0184bb;">false</span>
player!!.removeListener(<span class="hljs-literal" style="color: #0184bb;">null</span>)
player!!.stop()
player!!.release()
player = <span class="hljs-literal" style="color: #0184bb;">null</span>
exoPlayerVideoPlayerBootstrap.release()
}
}
<span class="hljs-keyword" style="color: #a626a4;">override</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">onPlayerStateChanged</span><span class="hljs-params">(playWhenReady: <span class="hljs-type" style="color: #986801;">Boolean</span>, playbackState: <span class="hljs-type" style="color: #986801;">Int</span>, status: <span class="hljs-type" style="color: #986801;">Boolean</span>)</span></span> {
<span class="hljs-keyword" style="color: #a626a4;">if</span> (!exoPlayerVideoPlayerBootstrap.isVideoPrepared && playbackState == STATE_READY) {
exoPlayerVideoPlayerBootstrap.isVideoPrepared = <span class="hljs-literal" style="color: #0184bb;">true</span>
}
<span class="hljs-keyword" style="color: #a626a4;">if</span> (playbackState == STATE_READY) {
progressBar!!.visibility = View.GONE
exoPlayerVideoPlayerBootstrap.isBuffering = <span class="hljs-literal" style="color: #0184bb;">false</span>
} <span class="hljs-keyword" style="color: #a626a4;">else</span> <span class="hljs-keyword" style="color: #a626a4;">if</span> (playbackState == Player.STATE_BUFFERING) {
progressBar!!.visibility = View.VISIBLE
exoPlayerVideoPlayerBootstrap.isBuffering = <span class="hljs-literal" style="color: #0184bb;">true</span>
}
<span class="hljs-keyword" style="color: #a626a4;">if</span> (playbackState == STATE_IDLE || playbackState == STATE_ENDED) {
progressBar!!.visibility = View.GONE
}
}
<span class="hljs-keyword" style="color: #a626a4;">companion</span> <span class="hljs-keyword" style="color: #a626a4;">object</span> {
<span class="hljs-keyword" style="color: #a626a4;">const</span> <span class="hljs-keyword" style="color: #a626a4;">val</span> PLAYER_RATIO_HEIGHT_OFFSET = <span class="hljs-number" style="color: #986801;">100</span>
}
}
</code></pre>
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">— videoHeight — метод который возвращает высоту видео, он нам нужен для установки высоты видео в айтеме в адаптере.</span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">— init — у нас инициализирует нашу вьюху и устанавливает качество стрима — LOWEST.</span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">— initPlayer нам нужен прежде всего для того что бы мы могли проинициализировать наш плеер когда фокус падает на айтем который пользователь захотел просмотреть. В этом методе мы инициализируем наш bootstrap класс, создаем плеер, задаем все нужные параметры — такие как:</span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">— задаем плеер в котором нужно играть видео.</span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">— устанавливаем что нам нужно что экран будет включен все время сколько видео будет проигрываться.</span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">— видео будет стартовать с начала каждый раз когда будет заканчиваться.</span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">— мы отключили контролы в плеере, по этому они не будут отображаться.</span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">— и установили ресайз для видео что бы оно растягивало его по ширине и высоте, в том резолюшене который мы задали расчитав его в методе videoHeight.</span><br />
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Так же мы задали mediaSource и вызвали prepeare что бы видео начало прогружаться. И так же, кинули коллбек для onPlayerVisibleListener в холдер что у нас появился активный плеер которым дальше из адаптера мы сможем управлять, паузить, резюмить или останавливать.</span><br />
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Дальше идут методы playVideo, pauseVideom resumeVideo и stopVideo — они все повторяют стандартный функционал в котором мы говорим что нам делать с потоком, ну и дергаем нужные переключатели для сохранения статуса потока, что бы не запутаться.</span><br />
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">— releasePlayer — останавливает плеер и уничтожает все его инстансы, это нам нужно для того что бы эти переменные не висели без толку если мы их уже не используем.</span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">— onPlayerStateChanged — это наш метод из PlayerStateChangedListener, который возвращает стейт потока, в этом методе мы регулируем, когда показывать прогресс бар, когда его прятать и опять же управляем переключателем isBuffering который нужен нам для разного рода проверок в будущем.</span><br />
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Дальше начинается самая легкая часть, мы создадим адаптер, холдер и подключим все эти штуки в MainActivity для отображения.</span><br />
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Но для начала нам нужно создать модель в которую мы будем загружать ссылки на поток и названия видео.</span><br />
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">VideosModel.kt</span><br />
<pre style="background-color: white; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow: auto hidden; padding: 0px; word-break: break-all;"><code class="kotlin hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-class"><span class="hljs-keyword" style="color: #a626a4;">class</span> <span class="hljs-title" style="color: #c18401;">VideosModel</span></span>(<span class="hljs-keyword" style="color: #a626a4;">var</span> title: String?, <span class="hljs-keyword" style="color: #a626a4;">var</span> videoUrl: String?)
</code></pre>
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Обожаю котлин за это :)</span><br />
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">ViewHolder.kt</span><br />
<pre style="background-color: white; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow: auto hidden; padding: 0px; word-break: break-all;"><code class="kotlin hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="color: #a626a4;">import</span> android.view.View
<span class="hljs-keyword" style="color: #a626a4;">import</span> android.widget.FrameLayout
<span class="hljs-keyword" style="color: #a626a4;">import</span> dajver.com.videorecyclerview.models.VideosModel
<span class="hljs-keyword" style="color: #a626a4;">import</span> dajver.com.videorecyclerview.player.VideoPlayerView
<span class="hljs-keyword" style="color: #a626a4;">import</span> dajver.com.videorecyclerview.player.views.holder.VideoHolder
<span class="hljs-keyword" style="color: #a626a4;">import</span> kotlinx.android.synthetic.main.item_video_view_holder.view.*
<span class="hljs-class"><span class="hljs-keyword" style="color: #a626a4;">class</span> <span class="hljs-title" style="color: #c18401;">ViewHolder</span></span>(itemView: View, mOnPlayerVisibleListener: OnPlayerVisibleListener) : VideoHolder(itemView, mOnPlayerVisibleListener) {
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-keyword" style="color: #a626a4;">var</span> mVideosModel: VideosModel? = <span class="hljs-literal" style="color: #0184bb;">null</span>
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-keyword" style="color: #a626a4;">var</span> onPlayerVisibleListener: OnPlayerVisibleListener? = <span class="hljs-literal" style="color: #0184bb;">null</span>
<span class="hljs-keyword" style="color: #a626a4;">init</span> {
<span class="hljs-keyword" style="color: #a626a4;">this</span>.onPlayerVisibleListener = mOnPlayerVisibleListener
}
<span class="hljs-keyword" style="color: #a626a4;">override</span> <span class="hljs-keyword" style="color: #a626a4;">val</span> videoLayout: View
<span class="hljs-keyword" style="color: #a626a4;">get</span>() = itemView.video
<span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">bind</span><span class="hljs-params">(videosModel: <span class="hljs-type" style="color: #986801;">VideosModel</span>)</span></span> {
mVideosModel = videosModel
itemView.video.layoutParams = FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, itemView.video.videoHeight)
itemView.title.text = videosModel.title
}
<span class="hljs-keyword" style="color: #a626a4;">override</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">playVideo</span><span class="hljs-params">()</span></span> {
itemView.video.initPlayer(mVideosModel!!, onPlayerVisibleListener!!)
itemView.video.playVideo()
}
<span class="hljs-keyword" style="color: #a626a4;">override</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">stopVideo</span><span class="hljs-params">()</span></span> {
itemView.video.stopVideo()
}
<span class="hljs-class"><span class="hljs-keyword" style="color: #a626a4;">interface</span> <span class="hljs-title" style="color: #c18401;">OnPlayerVisibleListener</span> </span>{
<span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">onActivePlayerView</span><span class="hljs-params">(videoPlayerView: <span class="hljs-type" style="color: #986801;">VideoPlayerView</span>)</span></span>
}
}
</code></pre>
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Мы унаследовали наш ViewHolder от VideoHolder который у нас используется в нашем AutoPlayRecyclerView, и оно нам предложило создать три метода которые собственно мы и прописывали там. В videoLayout мы передаем наш плеер что бы тот мог управлять им по надобности, а в play и stop прописываем включение и выключение потока.</span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">— init — в этом методе мы инициализируем наш колбек который будет возвращать текущий активный холдер на экране, который проигрывается.</span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">— в методе bind мы просто отображаем что у нас находится в модельке, а это тайтл видео. И задаем высоту видео в айтеме.</span><br />
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">item_video_view_holder.xml</span><br />
<pre style="background-color: white; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow: auto hidden; padding: 0px; word-break: break-all;"><code class="xml hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-meta" style="color: #4078f2;"><?xml version="1.0" encoding="utf-8"?></span>
<span class="hljs-tag"><<span class="hljs-name" style="color: #e45649;">LinearLayout</span> <span class="hljs-attr" style="color: #986801;">xmlns:android</span>=<span class="hljs-string" style="color: #50a14f;">"http://schemas.android.com/apk/res/android"</span>
<span class="hljs-attr" style="color: #986801;">android:layout_width</span>=<span class="hljs-string" style="color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="color: #986801;">android:layout_height</span>=<span class="hljs-string" style="color: #50a14f;">"wrap_content"</span>
<span class="hljs-attr" style="color: #986801;">android:layout_marginTop</span>=<span class="hljs-string" style="color: #50a14f;">"10dp"</span>
<span class="hljs-attr" style="color: #986801;">android:orientation</span>=<span class="hljs-string" style="color: #50a14f;">"vertical"</span>></span>
<span class="hljs-tag"><<span class="hljs-name" style="color: #e45649;">TextView</span>
<span class="hljs-attr" style="color: #986801;">android:text</span>=<span class="hljs-string" style="color: #50a14f;">"TextView"</span>
<span class="hljs-attr" style="color: #986801;">android:layout_width</span>=<span class="hljs-string" style="color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="color: #986801;">android:layout_height</span>=<span class="hljs-string" style="color: #50a14f;">"wrap_content"</span> <span class="hljs-attr" style="color: #986801;">android:id</span>=<span class="hljs-string" style="color: #50a14f;">"@+id/title"</span> <span class="hljs-attr" style="color: #986801;">android:padding</span>=<span class="hljs-string" style="color: #50a14f;">"15dp"</span>
<span class="hljs-attr" style="color: #986801;">android:textColor</span>=<span class="hljs-string" style="color: #50a14f;">"@android:color/black"</span> <span class="hljs-attr" style="color: #986801;">android:textSize</span>=<span class="hljs-string" style="color: #50a14f;">"18sp"</span>/></span>
<span class="hljs-tag"><<span class="hljs-name" style="color: #e45649;">FrameLayout</span>
<span class="hljs-attr" style="color: #986801;">android:layout_width</span>=<span class="hljs-string" style="color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="color: #986801;">android:layout_height</span>=<span class="hljs-string" style="color: #50a14f;">"wrap_content"</span>></span>
<span class="hljs-tag"><<span class="hljs-name" style="color: #e45649;">dajver.com.videorecyclerview.player.VideoPlayerView</span>
<span class="hljs-attr" style="color: #986801;">android:id</span>=<span class="hljs-string" style="color: #50a14f;">"@+id/video"</span>
<span class="hljs-attr" style="color: #986801;">android:layout_width</span>=<span class="hljs-string" style="color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="color: #986801;">android:layout_height</span>=<span class="hljs-string" style="color: #50a14f;">"wrap_content"</span> /></span>
<span class="hljs-tag"></<span class="hljs-name" style="color: #e45649;">FrameLayout</span>></span>
<span class="hljs-tag"></<span class="hljs-name" style="color: #e45649;">LinearLayout</span>></span>
</code></pre>
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Просто текст и наш плеер который мы создали, этого достаточно нам для примера как я считаю.</span><br />
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">VideoRecyclerAdapter.kt</span><br />
<pre style="background-color: white; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow: auto hidden; padding: 0px; word-break: break-all;"><code class="kotlin hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="color: #a626a4;">import</span> android.view.LayoutInflater
<span class="hljs-keyword" style="color: #a626a4;">import</span> android.view.ViewGroup
<span class="hljs-keyword" style="color: #a626a4;">import</span> androidx.recyclerview.widget.RecyclerView
<span class="hljs-keyword" style="color: #a626a4;">import</span> dajver.com.videorecyclerview.R
<span class="hljs-keyword" style="color: #a626a4;">import</span> dajver.com.videorecyclerview.adapter.holder.ViewHolder
<span class="hljs-keyword" style="color: #a626a4;">import</span> dajver.com.videorecyclerview.models.VideosModel
<span class="hljs-keyword" style="color: #a626a4;">import</span> dajver.com.videorecyclerview.player.VideoPlayerView
<span class="hljs-keyword" style="color: #a626a4;">import</span> dajver.com.videorecyclerview.player.views.AutoPlayVideoRecyclerView
<span class="hljs-keyword" style="color: #a626a4;">import</span> java.util.*
<span class="hljs-keyword" style="color: #a626a4;">open</span> <span class="hljs-class"><span class="hljs-keyword" style="color: #a626a4;">class</span> <span class="hljs-title" style="color: #c18401;">VideoRecyclerAdapter</span> : <span class="hljs-type" style="color: #986801;">RecyclerView.Adapter</span><<span class="hljs-type" style="color: #986801;">RecyclerView.ViewHolder</span>></span>(), ViewHolder.OnPlayerVisibleListener {
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-keyword" style="color: #a626a4;">var</span> videoPlayerView: VideoPlayerView? = <span class="hljs-literal" style="color: #0184bb;">null</span>
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-keyword" style="color: #a626a4;">var</span> videosModels: MutableList<VideosModel> = ArrayList()
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-keyword" style="color: #a626a4;">var</span> mRecyclerView: AutoPlayVideoRecyclerView? = <span class="hljs-literal" style="color: #0184bb;">null</span>
<span class="hljs-keyword" style="color: #a626a4;">private</span> <span class="hljs-keyword" style="color: #a626a4;">val</span> isInternetConnected = <span class="hljs-literal" style="color: #0184bb;">true</span>
<span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">addItems</span><span class="hljs-params">(blinkEdgeModels: <span class="hljs-type" style="color: #986801;">List</span><<span class="hljs-type" style="color: #986801;">VideosModel</span>>)</span></span> {
<span class="hljs-keyword" style="color: #a626a4;">this</span>.videosModels.addAll(blinkEdgeModels)
notifyDataSetChanged()
}
<span class="hljs-keyword" style="color: #a626a4;">override</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">onActivePlayerView</span><span class="hljs-params">(videoPlayerView: <span class="hljs-type" style="color: #986801;">VideoPlayerView</span>)</span></span> {
<span class="hljs-keyword" style="color: #a626a4;">this</span>.videoPlayerView = videoPlayerView
}
<span class="hljs-keyword" style="color: #a626a4;">override</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">onCreateViewHolder</span><span class="hljs-params">(parent: <span class="hljs-type" style="color: #986801;">ViewGroup</span>, viewType: <span class="hljs-type" style="color: #986801;">Int</span>)</span></span>: RecyclerView.ViewHolder {
<span class="hljs-keyword" style="color: #a626a4;">val</span> cardView = LayoutInflater.from(parent.context).inflate(R.layout.item_video_view_holder, parent, <span class="hljs-literal" style="color: #0184bb;">false</span>)
<span class="hljs-keyword" style="color: #a626a4;">return</span> ViewHolder(cardView, <span class="hljs-keyword" style="color: #a626a4;">this</span>)
}
<span class="hljs-keyword" style="color: #a626a4;">override</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">onBindViewHolder</span><span class="hljs-params">(holder: <span class="hljs-type" style="color: #986801;">RecyclerView</span>.<span class="hljs-type" style="color: #986801;">ViewHolder</span>, position: <span class="hljs-type" style="color: #986801;">Int</span>)</span></span> {
<span class="hljs-keyword" style="color: #a626a4;">val</span> viewHolder = holder <span class="hljs-keyword" style="color: #a626a4;">as</span> ViewHolder
viewHolder.bind(videosModels[position])
holder.setIsRecyclable(<span class="hljs-literal" style="color: #0184bb;">true</span>)
}
<span class="hljs-keyword" style="color: #a626a4;">override</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">getItemCount</span><span class="hljs-params">()</span></span>: <span class="hljs-built_in" style="color: #c18401;">Int</span> {
<span class="hljs-keyword" style="color: #a626a4;">return</span> videosModels.size
}
<span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">stop</span><span class="hljs-params">()</span></span> {
<span class="hljs-keyword" style="color: #a626a4;">if</span> (videoPlayerView != <span class="hljs-literal" style="color: #0184bb;">null</span>) {
videoPlayerView!!.stopVideo()
}
}
<span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">pause</span><span class="hljs-params">()</span></span> {
<span class="hljs-keyword" style="color: #a626a4;">if</span> (videoPlayerView != <span class="hljs-literal" style="color: #0184bb;">null</span>) {
videoPlayerView!!.pauseVideo()
}
}
<span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">resumeLastPlayer</span><span class="hljs-params">()</span></span> {
<span class="hljs-keyword" style="color: #a626a4;">if</span> (isInternetConnected && videoPlayerView != <span class="hljs-literal" style="color: #0184bb;">null</span> && mRecyclerView != <span class="hljs-literal" style="color: #0184bb;">null</span>) {
videoPlayerView!!.resumeVideo()
}
}
<span class="hljs-keyword" style="color: #a626a4;">override</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">onAttachedToRecyclerView</span><span class="hljs-params">(recyclerView: <span class="hljs-type" style="color: #986801;">RecyclerView</span>)</span></span> {
<span class="hljs-keyword" style="color: #a626a4;">super</span>.onAttachedToRecyclerView(recyclerView)
mRecyclerView = recyclerView <span class="hljs-keyword" style="color: #a626a4;">as</span> AutoPlayVideoRecyclerView
}
<span class="hljs-keyword" style="color: #a626a4;">override</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">onDetachedFromRecyclerView</span><span class="hljs-params">(recyclerView: <span class="hljs-type" style="color: #986801;">RecyclerView</span>)</span></span> {
<span class="hljs-keyword" style="color: #a626a4;">super</span>.onDetachedFromRecyclerView(recyclerView)
mRecyclerView = <span class="hljs-literal" style="color: #0184bb;">null</span>
}
}
</code></pre>
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Адаптер у нас в полне стандартный, в нем мы просто подписываемся на наш интерфейс который возвращает нам активный плеер, и дальше у нас появляется возможность паузить видео, резюмить или останавливать вообще, на пример когда нам нужно по сворачиванию или выключению приложения сделать так что бы видео не играло в фоне.</span><br />
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">activity_main.xml</span><br />
<pre style="background-color: white; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow: auto hidden; padding: 0px; word-break: break-all;"><code class="xml hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-meta" style="color: #4078f2;"><?xml version="1.0" encoding="utf-8"?></span>
<span class="hljs-tag"><<span class="hljs-name" style="color: #e45649;">LinearLayout</span> <span class="hljs-attr" style="color: #986801;">xmlns:android</span>=<span class="hljs-string" style="color: #50a14f;">"http://schemas.android.com/apk/res/android"</span>
<span class="hljs-attr" style="color: #986801;">xmlns:tools</span>=<span class="hljs-string" style="color: #50a14f;">"http://schemas.android.com/tools"</span>
<span class="hljs-attr" style="color: #986801;">android:layout_width</span>=<span class="hljs-string" style="color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="color: #986801;">android:layout_height</span>=<span class="hljs-string" style="color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="color: #986801;">tools:context</span>=<span class="hljs-string" style="color: #50a14f;">".MainActivity"</span>></span>
<span class="hljs-tag"><<span class="hljs-name" style="color: #e45649;">dajver.com.videorecyclerview.player.views.AutoPlayVideoRecyclerView</span>
<span class="hljs-attr" style="color: #986801;">android:id</span>=<span class="hljs-string" style="color: #50a14f;">"@+id/recyclerView"</span>
<span class="hljs-attr" style="color: #986801;">android:layout_width</span>=<span class="hljs-string" style="color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="color: #986801;">android:layout_height</span>=<span class="hljs-string" style="color: #50a14f;">"match_parent"</span>/></span>
<span class="hljs-tag"></<span class="hljs-name" style="color: #e45649;">LinearLayout</span>></span>
</code></pre>
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">В нашей активити у нас будет отображаться только один RecyclerView который мы написали, более нам больше ничего и не нужно.</span><br />
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">MainActivity.kt</span><br />
<pre style="background-color: white; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow: auto hidden; padding: 0px; word-break: break-all;"><code class="kotlin hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="color: #a626a4;">import</span> android.os.Bundle
<span class="hljs-keyword" style="color: #a626a4;">import</span> androidx.appcompat.app.AppCompatActivity
<span class="hljs-keyword" style="color: #a626a4;">import</span> dajver.com.videorecyclerview.adapter.VideoRecyclerAdapter
<span class="hljs-keyword" style="color: #a626a4;">import</span> dajver.com.videorecyclerview.models.VideosModel
<span class="hljs-keyword" style="color: #a626a4;">import</span> kotlinx.android.synthetic.main.activity_main.*
<span class="hljs-class"><span class="hljs-keyword" style="color: #a626a4;">class</span> <span class="hljs-title" style="color: #c18401;">MainActivity</span> : <span class="hljs-type" style="color: #986801;">AppCompatActivity</span></span>() {
<span class="hljs-keyword" style="color: #a626a4;">var</span> videoRecyclerAdapter: VideoRecyclerAdapter? = <span class="hljs-literal" style="color: #0184bb;">null</span>
<span class="hljs-keyword" style="color: #a626a4;">public</span> <span class="hljs-keyword" style="color: #a626a4;">override</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">onCreate</span><span class="hljs-params">(savedInstanceState: <span class="hljs-type" style="color: #986801;">Bundle</span>?)</span></span> {
<span class="hljs-keyword" style="color: #a626a4;">super</span>.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
<span class="hljs-keyword" style="color: #a626a4;">var</span> videosList = ArrayList<VideosModel>()
videosList.add(VideosModel(<span class="hljs-string" style="color: #50a14f;">"The redbull party"</span>, <span class="hljs-string" style="color: #50a14f;">"https://bitdash-a.akamaihd.net/content/MI201109210084_1/m3u8s/f08e80da-bf1d-4e3d-8899-f0f6155f6efa.m3u8"</span>))
videosList.add(VideosModel(<span class="hljs-string" style="color: #50a14f;">"The mountains"</span>,<span class="hljs-string" style="color: #50a14f;">"https://bitdash-a.akamaihd.net/content/sintel/hls/playlist.m3u8"</span>))
videosList.add(VideosModel(<span class="hljs-string" style="color: #50a14f;">"Tableronde"</span>, <span class="hljs-string" style="color: #50a14f;">"https://mnmedias.api.telequebec.tv/m3u8/29880.m3u8"</span>))
videosList.add(VideosModel(<span class="hljs-string" style="color: #50a14f;">"Bunny"</span>, <span class="hljs-string" style="color: #50a14f;">"http://184.72.239.149/vod/smil:BigBuckBunny.smil/playlist.m3u8"</span>))
videosList.add(VideosModel(<span class="hljs-string" style="color: #50a14f;">"The redbull party"</span>, <span class="hljs-string" style="color: #50a14f;">"https://bitdash-a.akamaihd.net/content/MI201109210084_1/m3u8s/f08e80da-bf1d-4e3d-8899-f0f6155f6efa.m3u8"</span>))
videosList.add(VideosModel(<span class="hljs-string" style="color: #50a14f;">"The mountains"</span>, <span class="hljs-string" style="color: #50a14f;">"https://bitdash-a.akamaihd.net/content/sintel/hls/playlist.m3u8"</span>))
videosList.add(VideosModel(<span class="hljs-string" style="color: #50a14f;">"Bunny"</span>, <span class="hljs-string" style="color: #50a14f;">"http://184.72.239.149/vod/smil:BigBuckBunny.smil/playlist.m3u8"</span>))
videoRecyclerAdapter = VideoRecyclerAdapter()
videoRecyclerAdapter!!.addItems(videosList)
recyclerView.adapter = videoRecyclerAdapter
}
<span class="hljs-keyword" style="color: #a626a4;">public</span> <span class="hljs-keyword" style="color: #a626a4;">override</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">onPause</span><span class="hljs-params">()</span></span> {
<span class="hljs-keyword" style="color: #a626a4;">super</span>.onPause()
videoRecyclerAdapter?.pause()
}
<span class="hljs-keyword" style="color: #a626a4;">public</span> <span class="hljs-keyword" style="color: #a626a4;">override</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">onDestroy</span><span class="hljs-params">()</span></span> {
<span class="hljs-keyword" style="color: #a626a4;">super</span>.onDestroy()
videoRecyclerAdapter?.stop()
recyclerView.adapter = <span class="hljs-literal" style="color: #0184bb;">null</span>
}
<span class="hljs-keyword" style="color: #a626a4;">public</span> <span class="hljs-keyword" style="color: #a626a4;">override</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">onStop</span><span class="hljs-params">()</span></span> {
<span class="hljs-keyword" style="color: #a626a4;">super</span>.onStop()
videoRecyclerAdapter?.pause()
}
<span class="hljs-keyword" style="color: #a626a4;">public</span> <span class="hljs-keyword" style="color: #a626a4;">override</span> <span class="hljs-function"><span class="hljs-keyword" style="color: #a626a4;">fun</span> <span class="hljs-title" style="color: #4078f2;">onResume</span><span class="hljs-params">()</span></span> {
<span class="hljs-keyword" style="color: #a626a4;">super</span>.onResume()
videoRecyclerAdapter?.resumeLastPlayer()
}
}
</code></pre>
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">— onCreate — у нас инициализирует список с ссылками на потоки видео, и адаптер который будет отображать их. </span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">— onPause, onDestroy, onStop и onResume нам нужны для сохранения жизненного цикла приложения, если пользователь свернет, развернет или выключит приложение, у нас наш поток остановится и не будет играть в фоне, и не создаст проблем при использовании нашего приложения пользователю.</span><br />
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Вроде бы ничего не забыл. Статья оказалась огромной просто, но в любом случае это отличный пример того как можно сделать автоплей в своем приложении. </span><br />
<br style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="font-family: , , "arial" , sans-serif; font-size: large;"><span style="background-color: white;"><b>Исходники:</b></span></span><br />
<b style="background-color: white; color: #992298; font-family: -apple-system, system-ui, Arial, sans-serif; text-decoration-line: none;"><span style="font-size: large;"><a href="https://github.com/dajver/AutoPlayRecyclerViewExample" style="background-color: white; color: #992298; font-family: -apple-system, system-ui, Arial, sans-serif; text-decoration-line: none;">GitHub</a></span></b></div>
dajverhttp://www.blogger.com/profile/09427222798699404442noreply@blogger.com2tag:blogger.com,1999:blog-5677605911484164185.post-20706942598351597272018-05-23T15:04:00.002+03:002019-07-02T23:48:18.592+03:00Пример использования ViewModel<div dir="ltr" style="text-align: left;" trbidi="on">
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Что-то побудило меня написать статью про эту новую фичу. Погуглив пару секунд я наткнулся на замечательную статью на </span><a href="https://medium.com/google-developers/viewmodels-a-simple-example-ed5ac416317e" style="background-color: white; box-sizing: inherit; color: #992298; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px; text-decoration-line: none;">Medium'e</a><span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">, пример который я привожу тут взят оттуда, только с небольшим моим дополнением, а так по сути это реплика статьи с Medium'a…</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Часто бывает когда сталкиваешься с проблемой поворота экрана, данные просто теряются при обновлении активити, и приходится или вызывать снова запрос на получение или сохранять эти данные в onSaveInstanceState(). </span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">ViewModel же помогает сохранять инстанс любого объекта который вы имеете, пусть то будет модель какого-то респонса с сервера, или на пример модель в которой хранятся локальные данные для текущей активити. При повороте экрана да и вообще на протяжении всего жизненого цикла приложения данная информация будет жить пока вы не закроете приложение вообще. </span><br />
<a name='more'></a><br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Что бывает если мы не сохраняем инстанс переменной в onSaveInstanceState() или во ViewModel? Вот вам пример.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<div style="text-align: center;">
<img alt="image" height="400" src="https://github.com/dajver/ViewModelExample/blob/master/imgs/image1.gif?raw=true" style="background-color: white; border-style: none; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px; margin: 0px; max-width: 100%; vertical-align: middle;" width="224" /></div>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">При обновлении активити когда экран поворачивается мы теряем наши данные, и так будет пока мы не сделаем переопределение этой переменной в onSaveInstanceState(). Вот пример кода который показан на этой гифке.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">MainActivity.java</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="java hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"> <span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@BindView</span>(R.id.textA)
TextView textA;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> counterA;
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">protected</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onCreate</span><span class="hljs-params" style="box-sizing: inherit;">(Bundle savedInstanceState)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">super</span>.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>);
displayForTeamA(counterA);
}
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@OnClick</span>(R.id.buttonA)
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onButtonAClick</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
displayForTeamA(counterA++);
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">displayForTeamA</span><span class="hljs-params" style="box-sizing: inherit;">(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> v)</span> </span>{
textA.setText(String.valueOf(v));
}
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">То есть, просто ничего ни где не сохраняется, ничто нигде не записывается, просто есть переменная counterA, которую мы увеличиваем по нажатию кнопки и все. При повороте экрана она просто теряет свой инстанс и пересоздается заново. Для того что бы она у нас записывалась и хранилась пока живо приложение — нам нужно создать класс — модель который будет наследоваться от ViewModel и будет хранить в себе переменные которые мы хотим запомнить. То есть вынести всю логику работы с переменные в отдельный класс что бы он не затрагивал UI.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">ScoreViewModel.java</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="java hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-class" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">class</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">ScoreViewModel</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">extends</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">ViewModel</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> scoreTeamA = <span class="hljs-number" style="box-sizing: inherit; color: #986801;">0</span>;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> scoreTeamB = <span class="hljs-number" style="box-sizing: inherit; color: #986801;">0</span>;
}
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Тут я создал две переменные для хранения данных, их тут можно написать сколько угодно, разных типов и оно все будет сохраняться, для примера будет просто две простые переменные типа int. И этот класс унаследован от ViewModel который собственно и указывает на то что мы в дальнейшем сможем использовать для нашей магии по сохранению данных. </span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Вот мы создали значит свою модель и унаследовали ее от ViewModel, вписали туда все нужные параметры, а что же дальше делать? А дальше нам нужно подключить провайдера который будет хранить инстанс данной модели в активити или фрагменте который мы передадим ему как контекст.</span><br />
<br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="java hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;">ViewModelProviders.of(<THIS ARGUMENT>).get(ScoreViewModel.class);</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #383a42; font-family: "menlo" , "monaco" , "courier new" , monospace; font-size: 14px; white-space: pre-wrap;"><THIS ARGUMENT></span><span style="background-color: #fbfdff; color: #383a42; font-family: "menlo" , "monaco" , "courier new" , monospace; font-size: 14px; white-space: pre-wrap;"> </span><span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">— это или this или getActivity() или какой-либо context UI класса.</span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">ScoreViewModel.class — собственно наш класс — модель который мы создали для хранения, он может называться если что — как угодно.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Дальше нам нужно подключить две библиотеки для того что бы работать с данными провайдером, так как он не идет в стандартной сборке SDK.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">app/build.gradle</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="java hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;">dependencies {
<span class="hljs-function" style="box-sizing: inherit;">implementation <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">fileTree</span><span class="hljs-params" style="box-sizing: inherit;">(dir: <span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">'libs'</span>, include: [<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">'*.jar'</span>])</span>
implementation 'com.android.support:appcompat-v7:27.1.1'
implementation "android.arch.lifecycle:extensions:1.1.0"
implementation "android.arch.lifecycle:viewmodel:1.1.0"
implementation 'com.jakewharton:butterknife:8.8.1'
annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'
}
</span></code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Для пример я привел все библиотеки что у меня тут есть, но нам важны две либы по центру, а именно lifecycle:extensions и lifecycle:viewmodel. Они обе нужны для того что бы использовать нужные классы для реализации (алгоритма или паттерна — как оно там у них называется без понятия) ViewModel. Так же у нас там как всегда ButterKnife и Appcompat для подключения вьюх и работы со стилями Compat.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">activity_main.xml</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="xml hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;"><?xml version="1.0" encoding="utf-8"?></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">LinearLayout</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">xmlns:android</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"http://schemas.android.com/apk/res/android"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_width</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_height</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:gravity</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"center_vertical"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:padding</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"20dp"</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">LinearLayout</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_width</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_height</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"wrap_content"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_weight</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"1"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:orientation</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"vertical"</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">TextView</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:id</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@+id/textA"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_width</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_height</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"wrap_content"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:gravity</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"center_vertical|center_horizontal"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:text</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"0"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:textSize</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"30sp"</span> /></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">Button</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:id</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@+id/buttonA"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_width</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_height</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"wrap_content"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_marginTop</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"50dp"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:onClick</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"onButtonAClick"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:text</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"Button A"</span> /></span>
<span class="hljs-tag" style="box-sizing: inherit;"></<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">LinearLayout</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">LinearLayout</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_width</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_height</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"wrap_content"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_weight</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"1"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:orientation</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"vertical"</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">TextView</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:id</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@+id/textB"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_width</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_height</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"wrap_content"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:gravity</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"center_vertical|center_horizontal"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:text</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"0"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:textSize</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"30sp"</span> /></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">Button</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:id</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@+id/buttonB"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_width</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_height</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"wrap_content"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_marginTop</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"50dp"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:onClick</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"onButtonBClick"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:text</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"Button B"</span> /></span>
<span class="hljs-tag" style="box-sizing: inherit;"></<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">LinearLayout</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"></<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">LinearLayout</span>></span>
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Это не столь важный момент но для полной картинки он нужен, у нас тут две кнопки и две текствьюхи расположеные друг рядом с другом. По нажатию на одну и вторую кнопки у нас будут увеличиваться каунтеры над ними.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">MainActivity.java</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="java hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.arch.lifecycle.ViewModelProviders;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.os.Bundle;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.support.v7.app.AppCompatActivity;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.widget.TextView;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> butterknife.BindView;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> butterknife.ButterKnife;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> butterknife.OnClick;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-class" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">class</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">MainActivity</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">extends</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">AppCompatActivity</span> </span>{
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@BindView</span>(R.id.textA)
TextView textA;
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@BindView</span>(R.id.textB)
TextView textB;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> ScoreViewModel mViewModel;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> counterA;
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">protected</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onCreate</span><span class="hljs-params" style="box-sizing: inherit;">(Bundle savedInstanceState)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">super</span>.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>);
mViewModel = ViewModelProviders.of(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>).get(ScoreViewModel.class);
displayForTeamA(counterA);
displayForTeamB(mViewModel.scoreTeamB);
}
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@OnClick</span>(R.id.buttonA)
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onButtonAClick</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
displayForTeamA(counterA++);
}
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@OnClick</span>(R.id.buttonB)
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onButtonBClick</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
mViewModel.scoreTeamB = mViewModel.scoreTeamB + <span class="hljs-number" style="box-sizing: inherit; color: #986801;">1</span>;
displayForTeamB(mViewModel.scoreTeamB);
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">displayForTeamA</span><span class="hljs-params" style="box-sizing: inherit;">(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> v)</span> </span>{
textA.setText(String.valueOf(v));
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">displayForTeamB</span><span class="hljs-params" style="box-sizing: inherit;">(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> v)</span> </span>{
textB.setText(String.valueOf(v));
}
}
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Собственно к коду выше я добавил новую переменную ScoreViewModel которая является инстансом нашей модели, и в onCreate() я создал при помощи провайдера ViewModelProviders ее инстанс который теперь будет хранить все что мы будем в нее записывать. Дальше по нажатию на onButtonBClick() у нас будет производиться запись инстанса mViewModel.scoreTeamB увеличеный на 1. И так же в onCreate() мы достаем его и отображаем в displayForTeamB(). </span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">И теперь эффект получается такой что слева у нас хранится инстанс который создается в UI и он не сохраняется, а с права у нас хранится инстанс ScoreViewModel и каждый раз при перевороте оно не создает новый инстанс этой переменной, а просто достает из закрамов последний сохраненный вариант этого объекта.</span><br />
<br />
<div style="text-align: center;">
<img alt="image" height="400" src="https://github.com/dajver/ViewModelExample/blob/master/imgs/image2.gif?raw=true" style="background-color: white; border-style: none; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px; margin: 0px; max-width: 100%; vertical-align: middle;" width="224" /></div>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Вот собственно и вся магия. Для примера это очень простой и классный вариант. Если усложнить то можно попробовать создать запрос на пример к серверу, и потом сохранять инстанс респонса в ViewModel и пользоваться им в дальнейших работах на экране. В общем это крутая штука, советую использовать вам в своих проектах.</span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;"><br /></span>
<span style="color: #222222; font-size: large;"><span style="background-color: white;"><b>Исходники:</b></span></span><br />
<span style="color: #222222; font-size: large;"><span style="background-color: white;"><b><a href="https://github.com/dajver/ViewModelExample">GitHub</a></b></span></span></div>
dajverhttp://www.blogger.com/profile/09427222798699404442noreply@blogger.com0tag:blogger.com,1999:blog-5677605911484164185.post-67961984967404414952018-05-22T18:27:00.004+03:002018-05-22T18:30:22.754+03:00GalleryView своими руками<div dir="ltr" style="text-align: left;" trbidi="on">
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">В одном из своих проектов столкнулся я с хотелкой заказчика что бы у нас был слайдер с превьюхой под картинкой, ну то есть обычная галерея. Ну я не долго думаючи взял родную галерею и увидел что ее уже не желательно использовать на устройствах, а замены как таковой нет, ну я и решил написать свою вьюху что бы уже не заморачиваться, тем более есть такая великая штука как RecyclerView которая умеет все.</span><br />
<br />
<div style="text-align: center;">
<img alt="image" height="400" src="https://github.com/dajver/GalleryView/blob/master/imgs/image.gif?raw=true" style="background-color: white; border-style: none; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px; margin: 0px; max-width: 100%; vertical-align: middle;" width="224" /></div>
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Вот такая вьюха с картинками будет. Она будет уметь по нажатию на айтем отображать его в большом виде, ну там окрашивать выбранный айтем вокруг в синенький цвет, что бы было понятно какой выбран ну и т.д.</span><br />
<a href="https://www.blogger.com/null" name="habracut" style="background-color: white; box-sizing: inherit; color: #548eaa; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;"></a><br />
<a name='more'></a><br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">По сути это будет вью в которую мы будем скармливать List в котором у нас будут ссылки на картинки, и дальше при помощи магии оно будет это отображать.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Начнем мы с того что подключим все нужные библиотеки которые нам нужны для отображения картинок, списков, и цеплянию view.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">app/build.gradle</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="java hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;">android {
...
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
dependencies {
<span class="hljs-function" style="box-sizing: inherit;">implementation <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">fileTree</span><span class="hljs-params" style="box-sizing: inherit;">(dir: <span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">'libs'</span>, include: [<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">'*.jar'</span>])</span>
implementation 'com.android.support:appcompat-v7:27.1.1'
implementation 'com.squareup.picasso:picasso:2.71828'
implementation 'com.jakewharton:butterknife:8.8.1'
annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'
implementation 'com.android.support:recyclerview-v7:27.1.1'
}
</span></code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Примерно вот так будет выглядеть наш градл файл, все собственно было выше описано.</span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">support:appcompat — нужен для того что бы у нас подтянулись все нужные классы относящиеся к andorid sdk, фрагменты, активити и т.д.</span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">picasso:picasso — нужен для отображения картинок.</span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">jakewharton:butterknife — нужен для упрощения подключать вьюхи, вместо findViewById мы просто будем писать @BindView(Id), и все.</span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">support:recyclerview — нужен для отображения списков.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Дальше для начала нам нужно создать адаптер для отображения превью картинок, в котором у нас будут все картинки из списка, и по клику мы будем переходить к кликнутой.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">ImageThumbsRecyclerAdapter.java</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="java hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.content.Context;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.support.v7.widget.RecyclerView;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.view.LayoutInflater;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.view.View;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.view.ViewGroup;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.widget.ImageView;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> com.squareup.picasso.Picasso;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> java.util.ArrayList;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> java.util.List;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> butterknife.BindView;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> butterknife.ButterKnife;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> project.dajver.com.galleryview.R;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-class" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">class</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">ImageThumbsRecyclerAdapter</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">extends</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">RecyclerView</span>.<span class="hljs-title" style="box-sizing: inherit; color: #c18401;">Adapter</span><<span class="hljs-title" style="box-sizing: inherit; color: #c18401;">RecyclerView</span>.<span class="hljs-title" style="box-sizing: inherit; color: #c18401;">ViewHolder</span>></span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> List<View> selectedViews = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> ArrayList<>();
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> List<View> allViews = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> ArrayList<>();
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> List<String> productImagesModels;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> OnItemClickListener onItemClickListener;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> Context context;
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">ImageThumbsRecyclerAdapter</span><span class="hljs-params" style="box-sizing: inherit;">(Context context, List<String> productImagesModels)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>.context = context;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>.productImagesModels = productImagesModels;
}
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> RecyclerView.<span class="hljs-function" style="box-sizing: inherit;">ViewHolder <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onCreateViewHolder</span><span class="hljs-params" style="box-sizing: inherit;">(ViewGroup parent, <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> viewType)</span> </span>{
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_horizontal_image_thumbs, parent, <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">false</span>);
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> ReceiveViewHolder(view);
}
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onBindViewHolder</span><span class="hljs-params" style="box-sizing: inherit;">(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">final</span> RecyclerView.ViewHolder holder, <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">final</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> position)</span> </span>{
ReceiveViewHolder viewHolder = (ReceiveViewHolder) holder;
Picasso.get().load(productImagesModels.get(position)).into(viewHolder.image);
allViews.add(viewHolder.itemView);
}
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">getItemCount</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> productImagesModels.size();
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">setCurrentItemActive</span><span class="hljs-params" style="box-sizing: inherit;">(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> position)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">for</span>(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> i = <span class="hljs-number" style="box-sizing: inherit; color: #986801;">0</span>; i < selectedViews.size(); i++) {
selectedViews.remove(i).setSelected(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">false</span>);
}
selectedViews.add(allViews.get(position));
allViews.get(position).setSelected(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">true</span>);
}
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-class" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">class</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">ReceiveViewHolder</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">extends</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">RecyclerView</span>.<span class="hljs-title" style="box-sizing: inherit; color: #c18401;">ViewHolder</span> </span>{
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@BindView</span>(R.id.image)
ImageView image;
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">ReceiveViewHolder</span><span class="hljs-params" style="box-sizing: inherit;">(View itemView)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">super</span>(itemView);
ButterKnife.bind(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>, itemView);
itemView.setOnClickListener(view -> {
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">for</span>(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> i = <span class="hljs-number" style="box-sizing: inherit; color: #986801;">0</span>; i < selectedViews.size(); i++) {
selectedViews.remove(i).setSelected(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">false</span>);
}
selectedViews.add(itemView);
itemView.setSelected(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">true</span>);
onItemClickListener.onItemClick(productImagesModels.get(getAdapterPosition()), getAdapterPosition());
});
}
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">setOnItemClickListener</span><span class="hljs-params" style="box-sizing: inherit;">(OnItemClickListener onItemClickListener)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>.onItemClickListener = onItemClickListener;
}
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-class" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">interface</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">OnItemClickListener</span> </span>{
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onItemClick</span><span class="hljs-params" style="box-sizing: inherit;">(String imagePath, <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> position)</span></span>;
}
}
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">В контструкторе мы принимаем List со всем списком картинок для отображения. так же у нас есть в шапке адаптера два списка — selectedViews и allViews. Они нам нужны для сохранения кликнутых вьюх и удаления остальных отмеченных, об этом чуть ниже.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">В onBindViewHolder() у нас идет заполнение всех вьюх которые мы имеем в списке, и так же заполнение массива allViews, для того что бы потом из него убирать или добавлять в него кликутые вьюхи. </span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Метод setCurrentItemActive() которые делает кликнутый айтем выделеным, и убирает выделение со всех остальных айтемов в списке. </span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Ну и в ReceiveViewHolder который у нас в самом низу адаптера мы отслеживаем клики по айтему и делаем его выделеным, а остальные делаем обычными. Ну и в самом низу мы сделали интерфейс для колбека клика в основную вью.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">item_horizontal_image_thumbs.xml</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="xml hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;"><?xml version="1.0" encoding="utf-8"?></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">LinearLayout</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">xmlns:android</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"http://schemas.android.com/apk/res/android"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">xmlns:app</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"http://schemas.android.com/apk/res-auto"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_width</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"75dp"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_height</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"75dp"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_marginLeft</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"5dp"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:background</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@drawable/image_thumbs_selector"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:foreground</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"?android:selectableItemBackground"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:gravity</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"center_vertical|center_horizontal"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:orientation</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"vertical"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:padding</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"10dp"</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">ImageView</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:id</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@+id/image"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_width</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"75dp"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_height</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"75dp"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">app:srcCompat</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@mipmap/ic_launcher"</span> /></span>
<span class="hljs-tag" style="box-sizing: inherit;"></<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">LinearLayout</span>></span>
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Наш айтем будет состоять всего лишь из одного ImageView в котором мы будем отображать наши превьюшки.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Так же у нас в этом xml подключен селектор выделения айтема image_thumbs_selector, он нам нужен что бы в нужный момент выделять при помощи setSelected() метода кликнутый айтем.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">image_thumbs_selector.xml</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="xml hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;"><?xml version="1.0" encoding="utf-8"?></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">selector</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">xmlns:android</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"http://schemas.android.com/apk/res/android"</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">item</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:state_selected</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"true"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:drawable</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@drawable/selected_image_thumb"</span>/></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">item</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:state_selected</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"false"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:drawable</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@android:color/transparent"</span>/></span>
<span class="hljs-tag" style="box-sizing: inherit;"></<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">selector</span>></span>
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">А так же в нем у нас вызывается selected_image_thumb который рисует вокруг вьюхи тонкую обводку.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">selected_image_thumb.xml</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="xml hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;"><?xml version="1.0" encoding="utf-8"?></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">shape</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">xmlns:android</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"http://schemas.android.com/apk/res/android"</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">stroke</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:width</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"1dp"</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:color</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@color/colorPrimary"</span>/></span>
<span class="hljs-tag" style="box-sizing: inherit;"></<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">shape</span>></span>
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Делаем тонкую обводку в 1 дпи вокруг айтема, цветом colorPrimary который у нас прописан в colors.xml.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Далее нам нужно создать слайдер для того что бы можно было при помощи свайпов влево и вправо так же листать наши картинки и внизу в нашем слайдере с превью они так же переключались. </span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">ImageSliderPagerAdapter.java</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="java hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.content.Context;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.support.v4.view.PagerAdapter;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.view.LayoutInflater;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.view.View;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.view.ViewGroup;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.widget.ImageView;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> com.squareup.picasso.Picasso;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> java.util.List;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> butterknife.BindView;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> butterknife.ButterKnife;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> project.dajver.com.galleryview.R;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-class" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">class</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">ImageSliderPagerAdapter</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">extends</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">PagerAdapter</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> List<String> images;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> LayoutInflater inflater;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> Context context;
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">ImageSliderPagerAdapter</span><span class="hljs-params" style="box-sizing: inherit;">(Context context, List<String> images)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>.context = context;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>.images=images;
inflater = LayoutInflater.from(context);
}
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">destroyItem</span><span class="hljs-params" style="box-sizing: inherit;">(ViewGroup container, <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> position, Object object)</span> </span>{
container.removeView((View) object);
}
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">getCount</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> images.size();
}
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> Object <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">instantiateItem</span><span class="hljs-params" style="box-sizing: inherit;">(ViewGroup viewGroup, <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> position)</span> </span>{
View view = inflater.inflate(R.layout.item_image_slider, viewGroup, <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">false</span>);
ViewHolder viewHolder = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> ViewHolder(view);
Picasso.get().load(images.get(position)).into(viewHolder.image);
viewGroup.addView(view, <span class="hljs-number" style="box-sizing: inherit; color: #986801;">0</span>);
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> view;
}
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">boolean</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">isViewFromObject</span><span class="hljs-params" style="box-sizing: inherit;">(View view, Object object)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> view.equals(object);
}
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-class" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">class</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">ViewHolder</span> </span>{
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@BindView</span>(R.id.image)
ImageView image;
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">ViewHolder</span><span class="hljs-params" style="box-sizing: inherit;">(View view)</span> </span>{
ButterKnife.bind(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>, view);
}
}
}
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">В конструктор мы передаем все такой же List как и в предыдущий адаптер, и отображаем его ImageView. Это будет у нас большая картинка над превьюхами, которая будет свайпаться вправо и влево.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">item_image_slider.xml</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="xml hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;"><?xml version="1.0" encoding="utf-8"?></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">FrameLayout</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">xmlns:android</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"http://schemas.android.com/apk/res/android"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_width</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"fill_parent"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_height</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"fill_parent"</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">ImageView</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:id</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@+id/image"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_width</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"fill_parent"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_height</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"fill_parent"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_gravity</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"center"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:adjustViewBounds</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"true"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:scaleType</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"fitCenter"</span> /></span>
<span class="hljs-tag" style="box-sizing: inherit;"></<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">FrameLayout</span>></span>
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Опять же, одна единственная ImageView в которой будем отображать картинку в нашем view pager.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Дальше нам нужно объеденить эти два адаптера в одной вьюхе что бы они взаимодействовали друг с другом и были одным единым в этой вьюхе. Для начала давайте посмотрим как у нас это будет выглядеть в xml.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">view_image_slider_with_preview.xml</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="xml hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;"><?xml version="1.0" encoding="utf-8"?></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">LinearLayout</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">xmlns:android</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"http://schemas.android.com/apk/res/android"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_width</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_height</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"400dp"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:gravity</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"center_horizontal"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:orientation</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"vertical"</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">android.support.v4.view.ViewPager</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:id</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@+id/pager"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_width</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_height</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_alignParentTop</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"true"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_weight</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"0.1"</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"></<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">android.support.v4.view.ViewPager</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">android.support.v7.widget.RecyclerView</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:id</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@+id/imagesRecyclerView"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_width</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"wrap_content"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_height</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"wrap_content"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_marginTop</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"10dp"</span> /></span>
<span class="hljs-tag" style="box-sizing: inherit;"></<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">LinearLayout</span>></span>
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Как видно из кода, у нас тут всего два элемента, это ViewPager который мы будем использовать для отображения большой картинки и RecyclerView для отображения превью картинок.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">ImageSliderWithPreviewView.java</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="java hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.content.Context;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.support.annotation.Nullable;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.support.v4.view.ViewPager;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.support.v7.widget.LinearLayoutManager;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.support.v7.widget.RecyclerView;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.util.AttributeSet;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.widget.LinearLayout;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> java.util.List;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> butterknife.BindView;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> butterknife.ButterKnife;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> project.dajver.com.galleryview.R;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> project.dajver.com.galleryview.adapters.ImageSliderPagerAdapter;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> project.dajver.com.galleryview.adapters.ImageThumbsRecyclerAdapter;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-class" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">class</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">ImageSliderWithPreviewView</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">extends</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">LinearLayout</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">implements</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">ImageThumbsRecyclerAdapter</span>.<span class="hljs-title" style="box-sizing: inherit; color: #c18401;">OnItemClickListener</span>,
<span class="hljs-title" style="box-sizing: inherit; color: #c18401;">ViewPager</span>.<span class="hljs-title" style="box-sizing: inherit; color: #c18401;">OnPageChangeListener</span> </span>{
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@BindView</span>(R.id.pager)
ViewPager viewPager;
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@BindView</span>(R.id.imagesRecyclerView)
RecyclerView imageThumbsRecyclerView;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> Context context;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> ImageThumbsRecyclerAdapter thumbsRecyclerView;
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">ImageSliderWithPreviewView</span><span class="hljs-params" style="box-sizing: inherit;">(Context context)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">super</span>(context);
init(context);
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">ImageSliderWithPreviewView</span><span class="hljs-params" style="box-sizing: inherit;">(Context context, @Nullable AttributeSet attrs)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">super</span>(context, attrs);
init(context);
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">ImageSliderWithPreviewView</span><span class="hljs-params" style="box-sizing: inherit;">(Context context, @Nullable AttributeSet attrs, <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> defStyleAttr)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">super</span>(context, attrs, defStyleAttr);
init(context);
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">init</span><span class="hljs-params" style="box-sizing: inherit;">(Context context)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>.context = context;
inflate(context, R.layout.view_image_slider_with_preview, <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>);
ButterKnife.bind(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>);
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">setImageList</span><span class="hljs-params" style="box-sizing: inherit;">(List<String> imageList)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">if</span>(imageList != <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">null</span> && imageList.size() > <span class="hljs-number" style="box-sizing: inherit; color: #986801;">0</span>) {
viewPager.setAdapter(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> ImageSliderPagerAdapter(context, imageList));
viewPager.addOnPageChangeListener(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>);
thumbsRecyclerView = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> ImageThumbsRecyclerAdapter(context, imageList);
thumbsRecyclerView.setOnItemClickListener(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>);
imageThumbsRecyclerView.setLayoutManager(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">false</span>));
imageThumbsRecyclerView.setAdapter(thumbsRecyclerView);
}
}
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onItemClick</span><span class="hljs-params" style="box-sizing: inherit;">(String catalogModel, <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> position)</span> </span>{
viewPager.setCurrentItem(position);
}
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onPageScrolled</span><span class="hljs-params" style="box-sizing: inherit;">(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> position, <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">float</span> positionOffset, <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> positionOffsetPixels)</span> </span>{
thumbsRecyclerView.setCurrentItemActive(position);
}
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onPageSelected</span><span class="hljs-params" style="box-sizing: inherit;">(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> position)</span> </span>{ }
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onPageScrollStateChanged</span><span class="hljs-params" style="box-sizing: inherit;">(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> state)</span> </span>{ }
}
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">И тут у нас уже идет объединение всего выше написанного кода в один организм. В init() мы проинициализировали леяут, butter knife и контекст. </span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Дальше у нас идет метод setImageList() в который мы передаем List который дальше пойдет в наши адаптеры для отображения картинок. Так же в этом методе мы задаем View Pager'у OnPageChangeListener который будет в зависимости от свайпа отображать нужную вьюху и передавать в адаптер превью которое нужно выделить. Ну и OnItemClickListener для отслеживания клика по превью что бы открыть определенную картинку в View pager'e.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">В onPageScrolled() мы задаем какую картинку в превью выделить с помощью метода setCurrentItemActive() про который я писал выше.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Ну и теперь осталось только добавить эту вьюху на activity_main и скормить ей список картинок в MainActivity.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">activity_main.xml</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="xml hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;"><?xml version="1.0" encoding="utf-8"?></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">LinearLayout</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">xmlns:android</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"http://schemas.android.com/apk/res/android"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_width</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_height</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:padding</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"20dp"</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">project.dajver.com.galleryview.views.ImageSliderWithPreviewView</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:id</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@+id/imageSliderView"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_width</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"wrap_content"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_height</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"wrap_content"</span> /></span>
<span class="hljs-tag" style="box-sizing: inherit;"></<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">LinearLayout</span>></span>
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Как видно из кода, достаточно просто добавить ее на экран, и все, больше никаких параметров не нужно. Только нужно задать id ей, и все. И дальше в MainActivity скормить List.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">MainActivity.java</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="java hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.os.Bundle;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.support.v7.app.AppCompatActivity;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> java.util.ArrayList;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> java.util.List;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> butterknife.BindView;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> butterknife.ButterKnife;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> project.dajver.com.galleryview.views.ImageSliderWithPreviewView;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-class" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">class</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">MainActivity</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">extends</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">AppCompatActivity</span> </span>{
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@BindView</span>(R.id.imageSliderView)
ImageSliderWithPreviewView imageSliderWithPreviewView;
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">protected</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onCreate</span><span class="hljs-params" style="box-sizing: inherit;">(Bundle savedInstanceState)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">super</span>.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>);
List<String> productImagesModels = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> ArrayList<>();
productImagesModels.add(<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"https://github.com/dajver/GalleryView/blob/master/imgs/image1.jpg?raw=true"</span>);
productImagesModels.add(<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"https://github.com/dajver/GalleryView/blob/master/imgs/image2.jpg?raw=true"</span>);
productImagesModels.add(<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"https://github.com/dajver/GalleryView/blob/master/imgs/image3.jpg?raw=true"</span>);
productImagesModels.add(<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"https://github.com/dajver/GalleryView/blob/master/imgs/image4.jpg?raw=true"</span>);
productImagesModels.add(<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"https://github.com/dajver/GalleryView/blob/master/imgs/image5.jpg?raw=true"</span>);
productImagesModels.add(<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"https://github.com/dajver/GalleryView/blob/master/imgs/image6.jpg?raw=true"</span>);
imageSliderWithPreviewView.setImageList(productImagesModels);
}
}
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">И собственно все что требуется от вас. Дальше оно там будет само подставлять картинки, рисовать вьюху с адаптером и отрабатывать свайпы и клики. Ну не прекрасно ли это?</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Так же нужно не забыть добавить в манифест пермишен для работы с интернетом, а то картинки не подтянутся.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">AndroidManifest.xml</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="xml hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">uses-permission</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:name</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"android.permission.INTERNET"</span> /></span></code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Вот собственно и все что требовалось от нас для того что бы сделать такую вьюху.</span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;"><br /></span>
<span style="color: #222222; font-size: large;"><span style="background-color: white;"><b>Исходники:</b></span></span><br />
<span style="color: #222222; font-size: large;"><span style="background-color: white;"><b><a href="https://github.com/dajver/GalleryView">GitHub</a></b></span></span></div>
dajverhttp://www.blogger.com/profile/09427222798699404442noreply@blogger.com3tag:blogger.com,1999:blog-5677605911484164185.post-24536857247221263032018-04-26T01:12:00.001+03:002018-04-26T01:19:32.651+03:00Создание корзины для мобильного интернет магазина<div dir="ltr" style="text-align: left;" trbidi="on">
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Много раз приходилось писать мобильные интернет магазины, в которых пользователь мог зайти, добавить какое-то количество товара в корзину, и потом купить его, отправив список товара на сервер. В моем примере у нас будет только список продукции, и корзина в которой у нас будут храниться выбранные товары. </span><br />
<div style="text-align: center;">
<br /></div>
<div style="text-align: center;">
<img alt="image" height="400" src="https://github.com/dajver/CartWithBadgeExample/raw/master/images/example.gif" style="background-color: white; border-style: none; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px; margin: 0px; max-width: 100%; vertical-align: middle;" width="224" /></div>
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;"><span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;"><br /></span>
Вот такой у нас будет мини магазин, в котором у нас будет два экрана. Простенько и красивенько, дак еще и с дизайном :) </span><br />
<a name='more'></a><span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">За основу корзины я взял готовое решение корзины с </span><a href="https://github.com/tonyvu2014/android-shoppingcart" style="background-color: white; box-sizing: inherit; color: #992298; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px; text-decoration-line: none;">github'a</a><span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">. Точно не помню с какого, так как там наплодилось куча подобных решений от разных мастеров копипасты. По этому укажу тот который нашел у себя в фейворитах и который больше всех похож на то что я использовал.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Для начала нам нужно набросать логику корзины, она вообще живет отдельной жизнью, как это было в проекте который я привел как оригинальный, то есть этот кусок можно тупо спрятать в отдельный пакедж или вообще проект, и просто подключать его по надобности к любому проекту. </span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">Seleable.java </span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="java hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> java.math.BigDecimal;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-class" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">interface</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">Saleable</span> </span>{
<span class="hljs-function" style="box-sizing: inherit;">BigDecimal <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">getPrice</span><span class="hljs-params" style="box-sizing: inherit;">()</span></span>;
<span class="hljs-function" style="box-sizing: inherit;">String <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">getName</span><span class="hljs-params" style="box-sizing: inherit;">()</span></span>;
}
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Тут у нас интерфейс в котором у нас храниться имя и цена товара, это два главных параметра которые у нас должны быть, остальные параметры как описание, количество и т.д это уже второстепенное, соответственно создаем интерфейс который будет иметь эти два метода.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">И дальше создаем две модели в которых описываем остальные параметры которые нам нужны для хранения данных о продукте. </span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">CartItemsEntityModel.java</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="java hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-class" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">class</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">CartItemsEntityModel</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> ProductEntityModel product;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> quantity;
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">getQuantity</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> quantity;
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">setQuantity</span><span class="hljs-params" style="box-sizing: inherit;">(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> quantity)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>.quantity = quantity;
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> ProductEntityModel <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">getProduct</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> product;
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">setProduct</span><span class="hljs-params" style="box-sizing: inherit;">(ProductEntityModel product)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>.product = product;
}
}
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Тут у нас два объекта, количество, и второй объект который в купе будет иметь название, цену и т.д. Как я писал выше.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">ProductEntityModel.java</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="java hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> java.io.Serializable;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> java.math.BigDecimal;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> project.dajver.com.cartviewwithbadge.cart.helper.i.Saleable;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-class" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">class</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">ProductEntityModel</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">implements</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">Saleable</span>, <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">Serializable</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">static</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">final</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">long</span> serialVersionUID = -<span class="hljs-number" style="box-sizing: inherit; color: #986801;">4073256626483275668L</span>;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> Long id;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> String name;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> BigDecimal price;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> String description;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> String image;
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">ProductEntityModel</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">super</span>();
}
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">boolean</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">equals</span><span class="hljs-params" style="box-sizing: inherit;">(Object o)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">if</span> (o == <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">null</span>) <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">false</span>;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">if</span> (!(o <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">instanceof</span> ProductEntityModel)) <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">false</span>;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> (<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>.id == ((ProductEntityModel) o).getId());
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">hashCode</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">final</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> prime = <span class="hljs-number" style="box-sizing: inherit; color: #986801;">31</span>;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> hash = <span class="hljs-number" style="box-sizing: inherit; color: #986801;">1</span>;
hash = (<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span>) (hash * prime + id);
hash = hash * prime + (name == <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">null</span> ? <span class="hljs-number" style="box-sizing: inherit; color: #986801;">0</span> : name.hashCode());
hash = hash * prime + (price == <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">null</span> ? <span class="hljs-number" style="box-sizing: inherit; color: #986801;">0</span> : price.hashCode());
hash = hash * prime + (description == <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">null</span> ? <span class="hljs-number" style="box-sizing: inherit; color: #986801;">0</span> : description.hashCode());
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> hash;
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> Long <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">getId</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> id;
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">setId</span><span class="hljs-params" style="box-sizing: inherit;">(Long id)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>.id = id;
}
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> BigDecimal <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">getPrice</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> price;
}
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> String <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">getName</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> name;
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">setPrice</span><span class="hljs-params" style="box-sizing: inherit;">(BigDecimal price)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>.price = price;
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">setName</span><span class="hljs-params" style="box-sizing: inherit;">(String name)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>.name = name;
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> String <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">getDescription</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> description;
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">setDescription</span><span class="hljs-params" style="box-sizing: inherit;">(String pDescription)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>.description = pDescription;
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> String <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">getImage</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> image;
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">setImage</span><span class="hljs-params" style="box-sizing: inherit;">(String imageName)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>.image = imageName;
}
}
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Создали объект в котором будем хранить все детали покупки, сделали ее Serializable для доступости передачи этого объекта в Intent'aх или SharedPreferences и Saleable для того что бы хранить его в HashMap в дальнейшем, так как у нас все наши покупки будут находиться внутри этого объекта, который будет находиться внутри HashMap, и по ключу мы будем доставать его.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Так же нам нужно создать несколько эксепшенов для отображения ошибок если они появятся. В нашем случае это если продукт не найден, или же если количество вышло за пределы допустимых значений.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">ProductNotFoundException.java</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="java hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-class" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">class</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">ProductNotFoundException</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">extends</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">RuntimeException</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">static</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">final</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">long</span> serialVersionUID = <span class="hljs-number" style="box-sizing: inherit; color: #986801;">43L</span>;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">static</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">final</span> String DEFAULT_MESSAGE = <span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"Product is not found in the shopping cart."</span>;
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">ProductNotFoundException</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">super</span>(DEFAULT_MESSAGE);
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">ProductNotFoundException</span><span class="hljs-params" style="box-sizing: inherit;">(String message)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">super</span>(message);
}
}
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Для создания сообщения в логах что продукт не найден.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">QuantityOutOfRangeException.java</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="java hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-class" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">class</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">QuantityOutOfRangeException</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">extends</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">RuntimeException</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">static</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">final</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">long</span> serialVersionUID = <span class="hljs-number" style="box-sizing: inherit; color: #986801;">44L</span>;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">static</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">final</span> String DEFAULT_MESSAGE = <span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"Quantity is out of range"</span>;
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">QuantityOutOfRangeException</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">super</span>(DEFAULT_MESSAGE);
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">QuantityOutOfRangeException</span><span class="hljs-params" style="box-sizing: inherit;">(String message)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">super</span>(message);
}
}
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Для отображения выход за пределы определенных границ.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Ну и теперь нам осталось создать главный класс helper который будет в себе содержать создание, обновление, удаление и полное очищение БД. Ну и там дальше еще можно будет получить количество покупок, общее количество денег которые затрачено на весь товар в корзине и т. д.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">CartEntity.java</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="java hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> java.io.Serializable;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> java.math.BigDecimal;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> java.util.HashMap;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> java.util.Map;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> java.util.Set;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> project.dajver.com.cartviewwithbadge.cart.helper.exceptions.QuantityOutOfRangeException;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> project.dajver.com.cartviewwithbadge.cart.helper.exceptions.ProductNotFoundException;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> project.dajver.com.cartviewwithbadge.cart.helper.i.Saleable;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-class" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">class</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">CartEntity</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">implements</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">Serializable</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">static</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">final</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">long</span> serialVersionUID = <span class="hljs-number" style="box-sizing: inherit; color: #986801;">42L</span>;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> Map<Saleable, Integer> cartItemMap = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> HashMap<>();
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> BigDecimal totalPrice = BigDecimal.ZERO;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> totalQuantity = <span class="hljs-number" style="box-sizing: inherit; color: #986801;">0</span>;
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">add</span><span class="hljs-params" style="box-sizing: inherit;">(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">final</span> Saleable sellable, <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> quantity)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">if</span> (cartItemMap.containsKey(sellable)) {
cartItemMap.put(sellable, cartItemMap.get(sellable) + quantity);
} <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">else</span> {
cartItemMap.put(sellable, quantity);
}
totalPrice = totalPrice.add(sellable.getPrice().multiply(BigDecimal.valueOf(quantity)));
totalQuantity += quantity;
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">update</span><span class="hljs-params" style="box-sizing: inherit;">(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">final</span> Saleable sellable, <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> quantity)</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">throws</span> ProductNotFoundException, QuantityOutOfRangeException </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">if</span> (!cartItemMap.containsKey(sellable)) <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">throw</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> ProductNotFoundException();
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">if</span> (quantity < <span class="hljs-number" style="box-sizing: inherit; color: #986801;">0</span>)
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">throw</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> QuantityOutOfRangeException(quantity + <span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">" is not a valid quantity. It must be non-negative."</span>);
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> productQuantity = cartItemMap.get(sellable);
BigDecimal productPrice = sellable.getPrice().multiply(BigDecimal.valueOf(productQuantity));
cartItemMap.put(sellable, quantity);
totalQuantity = totalQuantity - productQuantity + quantity;
totalPrice = totalPrice.subtract(productPrice).add(sellable.getPrice().multiply(BigDecimal.valueOf(quantity)));
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">remove</span><span class="hljs-params" style="box-sizing: inherit;">(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">final</span> Saleable sellable, <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> quantity)</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">throws</span> ProductNotFoundException, QuantityOutOfRangeException </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">if</span> (!cartItemMap.containsKey(sellable)) <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">throw</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> ProductNotFoundException();
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> productQuantity = cartItemMap.get(sellable);
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">if</span> (quantity < <span class="hljs-number" style="box-sizing: inherit; color: #986801;">0</span> || quantity > productQuantity)
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">throw</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> QuantityOutOfRangeException(quantity + <span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">" is not a valid quantity. It must be non-negative and less than the current quantity of the product in the shopping cart."</span>);
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">if</span> (productQuantity == quantity) {
cartItemMap.remove(sellable);
} <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">else</span> {
cartItemMap.put(sellable, productQuantity - quantity);
}
totalPrice = totalPrice.subtract(sellable.getPrice().multiply(BigDecimal.valueOf(quantity)));
totalQuantity -= quantity;
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">remove</span><span class="hljs-params" style="box-sizing: inherit;">(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">final</span> Saleable sellable)</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">throws</span> ProductNotFoundException </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">if</span> (!cartItemMap.containsKey(sellable)) <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">throw</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> ProductNotFoundException();
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> quantity = cartItemMap.get(sellable);
cartItemMap.remove(sellable);
totalPrice = totalPrice.subtract(sellable.getPrice().multiply(BigDecimal.valueOf(quantity)));
totalQuantity -= quantity;
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">clear</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
cartItemMap.clear();
totalPrice = BigDecimal.ZERO;
totalQuantity = <span class="hljs-number" style="box-sizing: inherit; color: #986801;">0</span>;
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">getQuantity</span><span class="hljs-params" style="box-sizing: inherit;">(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">final</span> Saleable sellable)</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">throws</span> ProductNotFoundException </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">if</span> (!cartItemMap.containsKey(sellable)) <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">throw</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> ProductNotFoundException();
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> cartItemMap.get(sellable);
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> BigDecimal <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">getCost</span><span class="hljs-params" style="box-sizing: inherit;">(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">final</span> Saleable sellable)</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">throws</span> ProductNotFoundException </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">if</span> (!cartItemMap.containsKey(sellable)) <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">throw</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> ProductNotFoundException();
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> sellable.getPrice().multiply(BigDecimal.valueOf(cartItemMap.get(sellable)));
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> BigDecimal <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">getTotalPrice</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> totalPrice;
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">getTotalQuantity</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> totalQuantity;
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> Set<Saleable> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">getProducts</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> cartItemMap.keySet();
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> Map<Saleable, Integer> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">getItemWithQuantity</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
Map<Saleable, Integer> cartItemMap = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> HashMap<Saleable, Integer>();
cartItemMap.putAll(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>.cartItemMap);
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> cartItemMap;
}
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> String <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">toString</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
StringBuilder strBuilder = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> StringBuilder();
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">for</span> (Map.Entry<Saleable, Integer> entry : cartItemMap.entrySet()) {
strBuilder.append(String.format(<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"Product: %s, Unit Price: %f, Quantity: %d%n"</span>, entry.getKey().getName(), entry.getKey().getPrice(), entry.getValue()));
}
strBuilder.append(String.format(<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"Total Quantity: %d, Total Price: %f"</span>, totalQuantity, totalPrice));
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> strBuilder.toString();
}
}
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Здесь у нас все методы для работы с записью, обновлением и удалением продуктов из списка продуктов. Каждый метод отвечает за свою функцию, по этому объяснять я не вижу смысла что оно делает. У нас есть хешмеп — cartItemMap, в который мы записывает, из которого удаляем, и в котором обновляем по ключу — объекту наши данные.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Ну и дальше у нас будет класс синглтон, который будет статичным объектом в котором мы по созданию будем хранить данные о продуктах который купил пользователь. </span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">CartHelper.java</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="java hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> java.util.ArrayList;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> java.util.List;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> java.util.Map;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> project.dajver.com.cartviewwithbadge.cart.helper.i.Saleable;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> project.dajver.com.cartviewwithbadge.cart.helper.entity.CartEntity;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> project.dajver.com.cartviewwithbadge.cart.helper.entity.models.CartItemsEntityModel;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> project.dajver.com.cartviewwithbadge.cart.helper.entity.models.ProductEntityModel;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-class" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">class</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">CartHelper</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">static</span> CartEntity cartEntity = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> CartEntity();
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">static</span> CartEntity <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">getCart</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">if</span> (cartEntity == <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">null</span>) {
cartEntity = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> CartEntity();
}
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> cartEntity;
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">static</span> List<CartItemsEntityModel> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">getCartItems</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
List<CartItemsEntityModel> cartItems = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> ArrayList<>();
Map<Saleable, Integer> itemMap = getCart().getItemWithQuantity();
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">for</span> (Map.Entry<Saleable, Integer> entry : itemMap.entrySet()) {
CartItemsEntityModel cartItem = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> CartItemsEntityModel();
cartItem.setProduct((ProductEntityModel) entry.getKey());
cartItem.setQuantity(entry.getValue());
cartItems.add(cartItem);
}
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> cartItems;
}
}
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Тут у нас два метода, getCart() который возвращает объект CartEntity, который мы создали выше, что бы мы могли делать все возможные функции из этого класса. И getCartItems() который возвращает список товаров которые пользователь выбрал в корзину. Собственно и все. Теперь у нас корзина полностью готова, теперь будем учиться его использовать.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Для начала создадим экран в котором у нас будет список продуктов на покупку. У нас будет как бы приложенька технологическая, по этому продавать мы там будем технику. </span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Начнем из далека, нам нужно подключить библиотеки которые мы будем использовать для работы, по традиции это как всегда будет ButterKnife, Picasso и RecyclerView.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">app/build.gradle</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="java hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;">android {
...
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
dependencies {
<span class="hljs-function" style="box-sizing: inherit;">implementation <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">fileTree</span><span class="hljs-params" style="box-sizing: inherit;">(dir: <span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">'libs'</span>, include: [<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">'*.jar'</span>])</span>
implementation 'com.android.support:appcompat-v7:27.1.1'
implementation 'com.squareup.picasso:picasso:2.5.2'
implementation 'com.jakewharton:butterknife:8.8.1'
annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'
implementation 'com.android.support:recyclerview-v7:27.1.1'
}
</span></code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Значит у нас подключены библиотеки в dependencies, и мы еще подключили Java 8 для красивого сокращения кода, возможно какие-то функции понадобятся, в любом случае ретролямбда уже не нужна как раньше, теперь у нас это есть из коробки при помощи Java 8.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Дальше создадим базовые классы для фрагментов и активити. В базовой активити у нас будет меню, которое будет на всех экранах приложения с будет баджем, ну и что бы не писать по два раза одно и тоже мы это все прописываем в базовой активити. </span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">BaseActivity.java</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="java hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.content.Intent;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.os.Bundle;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.support.v4.view.MenuItemCompat;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.support.v7.app.AppCompatActivity;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.view.Menu;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.view.MenuItem;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.view.View;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.widget.TextView;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> butterknife.ButterKnife;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> project.dajver.com.cartviewwithbadge.cart.CartActivity;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> project.dajver.com.cartviewwithbadge.cart.helper.CartHelper;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">abstract</span> <span class="hljs-class" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">class</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">BaseActivity</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">extends</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">AppCompatActivity</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> TextView textCartItemCount;
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">protected</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onCreate</span><span class="hljs-params" style="box-sizing: inherit;">(Bundle savedInstanceState)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">super</span>.onCreate(savedInstanceState);
setContentView(getViewId());
ButterKnife.bind(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>);
onCreateView();
}
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">boolean</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onOptionsItemSelected</span><span class="hljs-params" style="box-sizing: inherit;">(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">final</span> MenuItem item)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">switch</span> (item.getItemId()) {
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">case</span> android.R.id.home:
onBackPressed();
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">true</span>;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">case</span> R.id.cart:
startActivity(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> Intent(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>, CartActivity.class));
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">true</span>;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">default</span>:
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">super</span>.onOptionsItemSelected(item);
}
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">setupBadge</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">if</span> (textCartItemCount != <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">null</span>) {
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">if</span> (CartHelper.getCartItems().size() == <span class="hljs-number" style="box-sizing: inherit; color: #986801;">0</span>) {
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">if</span> (textCartItemCount.getVisibility() != View.GONE) {
textCartItemCount.setVisibility(View.GONE);
}
} <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">else</span> {
textCartItemCount.setText(String.valueOf(Math.min(CartHelper.getCartItems().size(), <span class="hljs-number" style="box-sizing: inherit; color: #986801;">99</span>)));
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">if</span> (textCartItemCount.getVisibility() != View.VISIBLE) {
textCartItemCount.setVisibility(View.VISIBLE);
}
}
}
}
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">boolean</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onCreateOptionsMenu</span><span class="hljs-params" style="box-sizing: inherit;">(Menu menu)</span> </span>{
getMenuInflater().inflate(R.menu.menu_main, menu);
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">final</span> MenuItem menuItem = menu.findItem(R.id.cart);
View actionView = MenuItemCompat.getActionView(menuItem);
textCartItemCount = actionView.findViewById(R.id.cart_badge);
setupBadge();
actionView.setOnClickListener(v -> onOptionsItemSelected(menuItem));
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">true</span>;
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">abstract</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">getViewId</span><span class="hljs-params" style="box-sizing: inherit;">()</span></span>;
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">abstract</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onCreateView</span><span class="hljs-params" style="box-sizing: inherit;">()</span></span>;
}
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Вот собственно о том что я говорил. В onCreate() мы подключаем баттернайф, указали абстрактный метод для прописывания леяута, и вызвали в конце onCreateView() который у нас будет проходить вся логика при создании активити. </span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">onOptionsItemSelected() — выполняет стандартную функцию по для отслеживания клика пользователя на меню.</span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">setupBadge() — у нас создает бадж на иконке если у нас есть товары в корзине, и если нету то прячет его.</span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">onCreateOptionsMenu() — создает кастомную иконку с баджем поверх ее. По клику на нее мы вызываем onOptionsItemSelected().</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Ну и два абстрактных метода для переопределения функций getViewId() и onCreateView().</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">menu_main.xml</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="xml hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;"><?xml version="1.0" encoding="utf-8"?></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">menu</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">xmlns:android</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"http://schemas.android.com/apk/res/android"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">xmlns:app</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"http://schemas.android.com/apk/res-auto"</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">item</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:id</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@+id/cart"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:orderInCategory</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"100"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:title</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@string/cart"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">app:actionLayout</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@layout/view_custom_action_cart"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:icon</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@mipmap/cart"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">app:showAsAction</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"always"</span>/></span>
<span class="hljs-tag" style="box-sizing: inherit;"></<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">menu</span>></span>
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Добавили иконку в меню, задали кастомный леяут с баджем, ну и добавили иконку поверх чисто для вида. Дальше нам нужно создать view_custom_action_cart.xml в котором у нас будет иконка и поверх нее бадж.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">view_custom_action_cart.xml</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="xml hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;"><?xml version="1.0" encoding="utf-8"?></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">FrameLayout</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">style</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"?attr/actionButtonStyle"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">xmlns:android</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"http://schemas.android.com/apk/res/android"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_width</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"wrap_content"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_height</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"wrap_content"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:clipToPadding</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"false"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:focusable</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"true"</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">ImageView</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_width</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"wrap_content"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_height</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"wrap_content"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_gravity</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"center"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:src</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@mipmap/cart"</span>/></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">TextView</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:id</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@+id/cart_badge"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_width</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"20dp"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_height</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"20dp"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_gravity</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"right|end|top"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_marginEnd</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"-5dp"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_marginRight</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"-5dp"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_marginTop</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"3dp"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:background</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@drawable/badge_background"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:gravity</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"center"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:padding</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"3dp"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:textColor</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@color/black"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:text</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"0"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:textSize</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"10sp"</span>/></span>
<span class="hljs-tag" style="box-sizing: inherit;"></<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">FrameLayout</span>></span>
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Ну тут в общем понятно, иконка поверх которой у нас текствью у которого фон зарисован оранжевым цветом и оно все обведено в черный кружочек. Далее нам нужно создать badge_background.xml.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">badge_background.xml</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="xml hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;"><?xml version="1.0" encoding="utf-8"?></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">shape</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">xmlns:android</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"http://schemas.android.com/apk/res/android"</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:shape</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"oval"</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">solid</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:color</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@color/orangeText"</span>/></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">stroke</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:color</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@color/black"</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:width</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"1dp"</span>/></span>
<span class="hljs-tag" style="box-sizing: inherit;"></<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">shape</span>></span>
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Сделали шейп в котором у нас заливка оранженового цвета и черная обводка вокруг. Ниже цвета которые я использовал.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">color.xml</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="xml hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"> <span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">color</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">name</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"orangeText"</span>></span>#ffbb38<span class="hljs-tag" style="box-sizing: inherit;"></<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">color</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">color</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">name</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"black"</span>></span>#000<span class="hljs-tag" style="box-sizing: inherit;"></<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">color</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">color</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">name</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"white"</span>></span>#fff<span class="hljs-tag" style="box-sizing: inherit;"></<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">color</span>></span>
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">По красоте все, у нас будет стильно :) Далее создаем базовый фрагмент, он простой до ужаса.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">BaseFragment.java</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="java hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.app.Activity;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.os.Bundle;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.support.v4.app.Fragment;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.view.LayoutInflater;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.view.View;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.view.ViewGroup;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> butterknife.ButterKnife;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">abstract</span> <span class="hljs-class" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">class</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">BaseFragment</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">extends</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">Fragment</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> Activity context;
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onViewCreated</span><span class="hljs-params" style="box-sizing: inherit;">(View view, Bundle savedInstanceState)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">super</span>.onViewCreated(view, savedInstanceState);
context = getActivity();
onViewCreated(view);
}
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> View <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onCreateView</span><span class="hljs-params" style="box-sizing: inherit;">(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)</span> </span>{
View rootView = inflater.inflate(getViewId(), container, <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">false</span>);
ButterKnife.bind(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>, rootView);
setHasOptionsMenu(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">true</span>);
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> rootView;
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">abstract</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">getViewId</span><span class="hljs-params" style="box-sizing: inherit;">()</span></span>;
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">abstract</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onViewCreated</span><span class="hljs-params" style="box-sizing: inherit;">(View view)</span></span>;
}
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Тут тоже самое что мы делали в BaseActivity только без подключения меню. setHasOptionsMenu(true) — вызываем для того что бы меню можно было вызывать из фрагмента, тут нам оно не нужно, но на всякий случай я вставил и забыл его удалить. :)</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">ProductActivity.java</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="java hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> project.dajver.com.cartviewwithbadge.BaseActivity;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> project.dajver.com.cartviewwithbadge.R;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-class" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">class</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">ProductActivity</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">extends</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">BaseActivity</span> </span>{
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">getViewId</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> R.layout.activity_product;
}
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onCreateView</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{ }
}
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Пустой как моя жизнь. Тут нам ничего не надо, но вообще тут можно что-то добавить что-то что душе угодно, любой функционал. Вся логика будет в ProductFragment. XML будет выглядеть так:</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">activity_product.xml</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="xml hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;"><?xml version="1.0" encoding="utf-8"?></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">LinearLayout</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">xmlns:android</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"http://schemas.android.com/apk/res/android"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_width</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_height</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">xmlns:tools</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"http://schemas.android.com/tools"</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">fragment</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:id</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@+id/products"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:name</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"project.dajver.com.cartviewwithbadge.product.ProductFragment"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_width</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_height</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">tools:layout</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@layout/fragment_product"</span> /></span>
<span class="hljs-tag" style="box-sizing: inherit;"></<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">LinearLayout</span>></span>
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Прицепили фрагмент к активити, что бы отображать его внутри активти. Я так делаю во всех проектах, как по мне на много гибче чем делать в одной активити все.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">ProductFragment.java</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="java hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.content.Intent;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.support.v7.widget.GridLayoutManager;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.support.v7.widget.RecyclerView;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.view.View;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> java.math.BigDecimal;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> butterknife.BindView;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> project.dajver.com.cartviewwithbadge.BaseFragment;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> project.dajver.com.cartviewwithbadge.R;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> project.dajver.com.cartviewwithbadge.cart.CartActivity;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> project.dajver.com.cartviewwithbadge.cart.helper.CartHelper;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> project.dajver.com.cartviewwithbadge.cart.helper.entity.CartEntity;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> project.dajver.com.cartviewwithbadge.cart.helper.entity.models.ProductEntityModel;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> project.dajver.com.cartviewwithbadge.etc.ProductsHelper;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> project.dajver.com.cartviewwithbadge.product.adapter.ProductRecyclerAdapter;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> project.dajver.com.cartviewwithbadge.product.adapter.models.ProductModel;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-class" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">class</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">ProductFragment</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">extends</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">BaseFragment</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">implements</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">ProductRecyclerAdapter</span>.<span class="hljs-title" style="box-sizing: inherit; color: #c18401;">OnItemClickListener</span> </span>{
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@BindView</span>(R.id.recyclerView)
RecyclerView recyclerView;
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">getViewId</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> R.layout.fragment_product;
}
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onViewCreated</span><span class="hljs-params" style="box-sizing: inherit;">(View view)</span> </span>{
ProductRecyclerAdapter productRecyclerAdapter = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> ProductRecyclerAdapter(context, ProductsHelper.getProductsList());
productRecyclerAdapter.setOnItemClickListener(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>);
recyclerView.setLayoutManager(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> GridLayoutManager(context, <span class="hljs-number" style="box-sizing: inherit; color: #986801;">2</span>));
recyclerView.setAdapter(productRecyclerAdapter);
}
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onItemClick</span><span class="hljs-params" style="box-sizing: inherit;">(ProductModel productModel)</span> </span>{
ProductEntityModel product = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> ProductEntityModel();
product.setId(productModel.getId());
product.setName(productModel.getTitle());
product.setDescription(productModel.getDescription());
product.setPrice(BigDecimal.valueOf(productModel.getPrice()));
product.setImage(productModel.getImage());
CartEntity cart = CartHelper.getCart();
cart.add(product, <span class="hljs-number" style="box-sizing: inherit; color: #986801;">1</span>);
Intent intent = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> Intent(context, CartActivity.class);
startActivity(intent);
getActivity().invalidateOptionsMenu();
}
}
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">В onViewCreated() — создаем адаптер который мы еще не создали, но он у нас должен быть. Сетим его в ресайклер вью и показываем по красоте. Да, а еще у нас есть еще класс который содержит в себе продукты которые у нас отображает адаптер, ну вообще в идеале конечно у нас должно подтягиваться из серверной части, но тут у нас будет все локально.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">fragment_product.xml</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="xml hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;"><?xml version="1.0" encoding="utf-8"?></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">LinearLayout</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">xmlns:android</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"http://schemas.android.com/apk/res/android"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_width</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_height</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"match_parent"</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">android.support.v7.widget.RecyclerView</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:id</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@+id/recyclerView"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_width</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_height</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"match_parent"</span> /></span>
<span class="hljs-tag" style="box-sizing: inherit;"></<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">LinearLayout</span>></span>
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">У нас тут только список который будет отображаться со списком товаров.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">ProductModel.java</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="java hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-class" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">class</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">ProductModel</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> Long id;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> Integer price;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> String image;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> String title;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> String description;
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> Long <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">getId</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> id;
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">setId</span><span class="hljs-params" style="box-sizing: inherit;">(Long id)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>.id = id;
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> Integer <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">getPrice</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> price;
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">setPrice</span><span class="hljs-params" style="box-sizing: inherit;">(Integer price)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>.price = price;
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> String <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">getImage</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> image;
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">setImage</span><span class="hljs-params" style="box-sizing: inherit;">(String image)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>.image = image;
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> String <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">getTitle</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> title;
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">setTitle</span><span class="hljs-params" style="box-sizing: inherit;">(String title)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>.title = title;
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> String <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">getDescription</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> description;
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">setDescription</span><span class="hljs-params" style="box-sizing: inherit;">(String description)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>.description = description;
}
}
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Это объект который у нас описывает как будет выглядить продукт — айди, имя, описание, цена и картинка.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">ProductsHelper.java</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="java hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> java.util.ArrayList;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> java.util.List;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> project.dajver.com.cartviewwithbadge.product.adapter.models.ProductModel;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-class" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">class</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">ProductsHelper</span> </span>{
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">static</span> List<ProductModel> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">getProductsList</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
List<ProductModel> productModels = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> ArrayList<>();
ProductModel model = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> ProductModel();
model.setId(<span class="hljs-number" style="box-sizing: inherit; color: #986801;">5678l</span>);
model.setTitle(<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"Honor 6A 2"</span>);
model.setDescription(<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"16Gb Grey"</span>);
model.setImage(<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"https://github.com/dajver/CartWithBadgeExample/blob/master/images/honor.jpg?raw=true"</span>);
model.setPrice(<span class="hljs-number" style="box-sizing: inherit; color: #986801;">599</span>);
productModels.add(model);
model = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> ProductModel();
model.setId(<span class="hljs-number" style="box-sizing: inherit; color: #986801;">5672l</span>);
model.setTitle(<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"Meizu M5s"</span>);
model.setDescription(<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"32Gb Silver"</span>);
model.setImage(<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"https://github.com/dajver/CartWithBadgeExample/blob/master/images/meizu.jpg?raw=true"</span>);
model.setPrice(<span class="hljs-number" style="box-sizing: inherit; color: #986801;">899</span>);
productModels.add(model);
model = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> ProductModel();
model.setId(<span class="hljs-number" style="box-sizing: inherit; color: #986801;">5673l</span>);
model.setTitle(<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"Apple iPhone SE"</span>);
model.setDescription(<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"32Gb Space Gray"</span>);
model.setImage(<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"https://github.com/dajver/CartWithBadgeExample/blob/master/images/iphone.jpg?raw=true"</span>);
model.setPrice(<span class="hljs-number" style="box-sizing: inherit; color: #986801;">1199</span>);
productModels.add(model);
model = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> ProductModel();
model.setId(<span class="hljs-number" style="box-sizing: inherit; color: #986801;">5674l</span>);
model.setTitle(<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"Chuwi Hi10 Pro"</span>);
model.setImage(<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"https://github.com/dajver/CartWithBadgeExample/blob/master/images/chuwi.jpg?raw=true"</span>);
model.setPrice(<span class="hljs-number" style="box-sizing: inherit; color: #986801;">2199</span>);
productModels.add(model);
model = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> ProductModel();
model.setId(<span class="hljs-number" style="box-sizing: inherit; color: #986801;">5675l</span>);
model.setTitle(<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"Fermi S7-plus"</span>);
model.setDescription(<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"10000mAh gray)"</span>);
model.setImage(<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"https://github.com/dajver/CartWithBadgeExample/blob/master/images/batary.jpg?raw=true"</span>);
model.setPrice(<span class="hljs-number" style="box-sizing: inherit; color: #986801;">259</span>);
productModels.add(model);
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> productModels;
}
}
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">В общем то, тут объяснять нечего просто создали несколько продуктов для красоты, продолжим рассматривать ProductFragment. </span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">onItemClick() — у нас по клику на кнопку бай переходит в корзину, в которой у нас уже будет отображаться список покупок для отправки. Каждый клик добавляем 1 товар в корзину, и обновляем меню что бы отображался бадж.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">И давайте создадим адаптер. В нем мы просто отображаем наш список товаров.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">ProductRecyclerAdapter.java</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="java hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.content.Context;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.support.v7.widget.RecyclerView;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.view.LayoutInflater;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.view.View;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.view.ViewGroup;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.widget.Button;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.widget.ImageView;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.widget.TextView;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> com.squareup.picasso.Picasso;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> java.util.List;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> butterknife.BindView;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> butterknife.ButterKnife;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> project.dajver.com.cartviewwithbadge.R;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> project.dajver.com.cartviewwithbadge.product.adapter.models.ProductModel;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-class" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">class</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">ProductRecyclerAdapter</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">extends</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">RecyclerView</span>.<span class="hljs-title" style="box-sizing: inherit; color: #c18401;">Adapter</span><<span class="hljs-title" style="box-sizing: inherit; color: #c18401;">RecyclerView</span>.<span class="hljs-title" style="box-sizing: inherit; color: #c18401;">ViewHolder</span>></span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> List<ProductModel> catalogModels;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> OnItemClickListener onItemClickListener;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> Context context;
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">ProductRecyclerAdapter</span><span class="hljs-params" style="box-sizing: inherit;">(Context context, List<ProductModel> catalogModels)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>.context = context;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>.catalogModels = catalogModels;
}
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> RecyclerView.<span class="hljs-function" style="box-sizing: inherit;">ViewHolder <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onCreateViewHolder</span><span class="hljs-params" style="box-sizing: inherit;">(ViewGroup parent, <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> viewType)</span> </span>{
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_product, parent, <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">false</span>);
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> ReceiveViewHolder(view);
}
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onBindViewHolder</span><span class="hljs-params" style="box-sizing: inherit;">(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">final</span> RecyclerView.ViewHolder holder, <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">final</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> position)</span> </span>{
ReceiveViewHolder viewHolder = (ReceiveViewHolder) holder;
viewHolder.title.setText(catalogModels.get(position).getTitle());
viewHolder.description.setText(catalogModels.get(position).getDescription());
viewHolder.price.setText(String.format(context.getString(R.string.dollars_format), catalogModels.get(position).getPrice()));
Picasso.with(context).load(catalogModels.get(position).getImage()).into(viewHolder.image);
}
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">getItemCount</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> catalogModels.size();
}
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-class" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">class</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">ReceiveViewHolder</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">extends</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">RecyclerView</span>.<span class="hljs-title" style="box-sizing: inherit; color: #c18401;">ViewHolder</span> </span>{
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@BindView</span>(R.id.title)
TextView title;
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@BindView</span>(R.id.description)
TextView description;
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@BindView</span>(R.id.image)
ImageView image;
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@BindView</span>(R.id.price)
TextView price;
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@BindView</span>(R.id.buyButton)
Button buyButton;
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">ReceiveViewHolder</span><span class="hljs-params" style="box-sizing: inherit;">(View itemView)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">super</span>(itemView);
ButterKnife.bind(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>, itemView);
buyButton.setOnClickListener(view -> {
onItemClickListener.onItemClick(catalogModels.get(getAdapterPosition()));
});
}
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">setOnItemClickListener</span><span class="hljs-params" style="box-sizing: inherit;">(OnItemClickListener onItemClickListener)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>.onItemClickListener = onItemClickListener;
}
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-class" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">interface</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">OnItemClickListener</span> </span>{
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onItemClick</span><span class="hljs-params" style="box-sizing: inherit;">(ProductModel productModel)</span></span>;
}
}
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Собственно все тривиально, те кто писали адаптеры кастомные — не должно составить труда понять что тут происходит. В onCreateViewHolder() — проинициализировали леяут. В onBindViewHolder() — забиндили все данные что мы передали в catalogModels. Ну и в ReceiveViewHolder забиндили все вьюхи что нам нужны и устанавливаем на что у нас будет клик.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">XML у нас будет крутой. У нас тут будет и картинка, и описание, и цена. И это все будет выглядит круто и красивенько.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">item_product.xml</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="xml hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;"><?xml version="1.0" encoding="utf-8"?></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">LinearLayout</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">xmlns:android</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"http://schemas.android.com/apk/res/android"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_width</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_height</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"wrap_content"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_marginLeft</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"10dp"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_marginTop</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"10dp"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:background</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@color/white"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:foreground</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"?android:selectableItemBackground"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:gravity</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"center_vertical|center_horizontal"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:orientation</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"vertical"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:padding</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"20dp"</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">ImageView</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:id</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@+id/image"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_width</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"100dp"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_height</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"150dp"</span> /></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">TextView</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:id</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@+id/title"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_width</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"wrap_content"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_height</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"wrap_content"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_marginTop</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"10dp"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:gravity</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"center_vertical|center_horizontal"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:text</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"Samsung Galaxy J7"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:textColor</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@color/black"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:textSize</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"18sp"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:textStyle</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"bold"</span> /></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">TextView</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:id</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@+id/description"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_width</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"wrap_content"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_height</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"wrap_content"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:gravity</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"center_vertical|center_horizontal"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:maxLines</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"4"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:text</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"Plus Duos 64 GB Orchid Gray"</span> /></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">LinearLayout</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_width</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_height</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"wrap_content"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_marginTop</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"10dp"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:orientation</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"horizontal"</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">Button</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:id</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@+id/buyButton"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_width</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"wrap_content"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_height</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"wrap_content"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:backgroundTint</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@color/orangeText"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:text</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"Buy"</span> /></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">TextView</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:id</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@+id/price"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_width</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_height</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"wrap_content"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:gravity</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"right|center_vertical"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:text</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"$1999"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:textColor</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@android:color/black"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:textSize</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"20sp"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:textStyle</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"bold"</span> /></span>
<span class="hljs-tag" style="box-sizing: inherit;"></<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">LinearLayout</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"></<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">LinearLayout</span>></span>
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Давайте кстати еще посмотрим что у нас в string.xml, а то я не знаю куда его засунуть, у нас же оно в разных классах используется.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">strings.xml</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="xml hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">resources</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">string</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">name</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"app_name"</span>></span>CartViewWithBadge<span class="hljs-tag" style="box-sizing: inherit;"></<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">string</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">string</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">name</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"cart"</span>></span>Cart<span class="hljs-tag" style="box-sizing: inherit;"></<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">string</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">string</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">name</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"products"</span>></span>Products<span class="hljs-tag" style="box-sizing: inherit;"></<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">string</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">string</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">name</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"buy"</span>></span>Buy<span class="hljs-tag" style="box-sizing: inherit;"></<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">string</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">string</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">name</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"cart.success.message"</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">formatted</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"false"</span>></span>You bought %s products from your cart. With total price $%s<span class="hljs-tag" style="box-sizing: inherit;"></<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">string</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">string</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">name</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"dollars.format"</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">formatted</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"false"</span>></span>$%s<span class="hljs-tag" style="box-sizing: inherit;"></<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">string</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"></<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">resources</span>></span>
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Собственно это нам понадобится в дальнейшем, по этому пусть будет тут.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Теперь у нас есть все что нужно для отображения корзины. По этому создаем экран на котором у нас будет отображаться наша корзина.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">CartActivity.java</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="java hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> project.dajver.com.cartviewwithbadge.BaseActivity;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> project.dajver.com.cartviewwithbadge.R;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-class" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">class</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">CartActivity</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">extends</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">BaseActivity</span> </span>{
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">getViewId</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> R.layout.activity_cart;
}
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onCreateView</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
getSupportActionBar().setDisplayHomeAsUpEnabled(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">true</span>);
getSupportActionBar().setHomeButtonEnabled(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">true</span>);
}
}
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">onCreateView() — отображаем кнопку назад. Собственно и все.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">activity_cart.xml</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="xml hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;"><?xml version="1.0" encoding="utf-8"?></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">LinearLayout</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">xmlns:android</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"http://schemas.android.com/apk/res/android"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_width</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_height</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">xmlns:tools</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"http://schemas.android.com/tools"</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">fragment</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:id</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@+id/cart"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:name</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"project.dajver.com.cartviewwithbadge.cart.CartFragment"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_width</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_height</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">tools:layout</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@layout/fragment_cart"</span> /></span>
<span class="hljs-tag" style="box-sizing: inherit;"></<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">LinearLayout</span>></span>
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Тоже самое что и в продукте, по этому ничего нового :) Просто цепляем фрагмент к активити, для разделения логики и жизненного цикла.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">CartFragment.java</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="java hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.support.v7.widget.LinearLayoutManager;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.support.v7.widget.RecyclerView;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.view.View;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.widget.Toast;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> butterknife.BindView;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> butterknife.OnClick;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> project.dajver.com.cartviewwithbadge.BaseFragment;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> project.dajver.com.cartviewwithbadge.R;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> project.dajver.com.cartviewwithbadge.cart.adapter.CartRecyclerAdapter;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> project.dajver.com.cartviewwithbadge.cart.helper.CartHelper;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> project.dajver.com.cartviewwithbadge.cart.helper.entity.models.CartItemsEntityModel;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-class" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">class</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">CartFragment</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">extends</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">BaseFragment</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">implements</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">CartRecyclerAdapter</span>.<span class="hljs-title" style="box-sizing: inherit; color: #c18401;">OnItemClickListener</span> </span>{
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@BindView</span>(R.id.recyclerView)
RecyclerView recyclerView;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> CartRecyclerAdapter productRecyclerAdapter;
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">getViewId</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> R.layout.fragment_cart;
}
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onViewCreated</span><span class="hljs-params" style="box-sizing: inherit;">(View view)</span> </span>{
onUpdateList();
}
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onItemClick</span><span class="hljs-params" style="box-sizing: inherit;">(CartItemsEntityModel cartItemsEntityModel)</span> </span>{
<span class="hljs-comment" style="box-sizing: inherit; color: #a0a1a7; font-style: italic;">// open details of product</span>
}
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onItemPlusClicked</span><span class="hljs-params" style="box-sizing: inherit;">(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> position, CartItemsEntityModel cartItemsEntityModel)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> quantity = cartItemsEntityModel.getQuantity();
CartItemsEntityModel cartModel = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> CartItemsEntityModel();
cartModel.setProduct(cartItemsEntityModel.getProduct());
quantity++;
cartModel.setQuantity(quantity);
productRecyclerAdapter.updateItem(position, cartModel);
}
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onItemMinusClicked</span><span class="hljs-params" style="box-sizing: inherit;">(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> position, CartItemsEntityModel cartItemsEntityModel)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> quantity = cartItemsEntityModel.getQuantity();
CartItemsEntityModel cartModel = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> CartItemsEntityModel();
cartModel.setProduct(cartItemsEntityModel.getProduct());
quantity--;
cartModel.setQuantity(quantity);
productRecyclerAdapter.updateItem(position, cartModel);
}
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onUpdateList</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
productRecyclerAdapter = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> CartRecyclerAdapter(context, CartHelper.getCartItems());
productRecyclerAdapter.setOnItemClickListener(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>);
recyclerView.setLayoutManager(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> LinearLayoutManager(context));
recyclerView.setAdapter(productRecyclerAdapter);
}
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@OnClick</span>(R.id.buyButton)
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onBuyClick</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
Toast.makeText(context, String.format(getString(R.string.cart_success_message), CartHelper.getCart().getTotalQuantity(), CartHelper.getCart().getTotalPrice()), Toast.LENGTH_LONG).show();
CartHelper.getCart().clear();
getActivity().finish();
}
}
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Тут у нас вообще прям работа тетаническая выполнена. В onViewCreated() у нас вызывается onUpdateList() который у нас создается адаптер и сетим данные в него. Нам нужен метод onUpdateList() для того что бы обновлять данные в списке когда мы изменяем количество по клику на кнопку "+" или "-". Ну и передаем в адаптер CartHelper.getCartItems() который у нас хранит все наши товары.</span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">onItemMinusClicked() — у нас по клику уменьшает количество айтемов в адаптере, и в самой корзине.</span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">onItemPlusClicked() — соответственно увеличивает количество.</span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">onBuyClick() — по клику на кнопку Buy, мы отображаем тост с количеством купленного товара, и общую сумму на которую мы купили. Дальше стираем для вида что купили из списка все, и возвращаемся в список товаров.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">fragment_cart.xml</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="xml hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;"><?xml version="1.0" encoding="utf-8"?></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">LinearLayout</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">xmlns:android</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"http://schemas.android.com/apk/res/android"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_width</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_height</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:orientation</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"vertical"</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">android.support.v7.widget.RecyclerView</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:id</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@+id/recyclerView"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_width</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_height</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_weight</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"0.1"</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"></<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">android.support.v7.widget.RecyclerView</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">Button</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:id</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@+id/buyButton"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_width</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_height</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"wrap_content"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_margin</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"20dp"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:backgroundTint</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@color/orangeText"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:onClick</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"onBuyClick"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:text</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@string/buy"</span> /></span>
<span class="hljs-tag" style="box-sizing: inherit;"></<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">LinearLayout</span>></span>
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Список и кнопка. Что еще нужно для счастья? Дальше создаем адаптер для отображения, выбранных товаров с кнопочкой увеличить количество или уменьшить.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">CartRecyclerAdapter.java</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="java hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.content.Context;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.support.v7.widget.RecyclerView;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.view.LayoutInflater;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.view.View;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.view.ViewGroup;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.widget.Button;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.widget.ImageView;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.widget.TextView;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> com.squareup.picasso.Picasso;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> java.util.List;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> butterknife.BindView;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> butterknife.ButterKnife;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> project.dajver.com.cartviewwithbadge.R;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> project.dajver.com.cartviewwithbadge.cart.helper.CartHelper;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> project.dajver.com.cartviewwithbadge.cart.helper.entity.models.CartItemsEntityModel;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-class" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">class</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">CartRecyclerAdapter</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">extends</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">RecyclerView</span>.<span class="hljs-title" style="box-sizing: inherit; color: #c18401;">Adapter</span><<span class="hljs-title" style="box-sizing: inherit; color: #c18401;">RecyclerView</span>.<span class="hljs-title" style="box-sizing: inherit; color: #c18401;">ViewHolder</span>></span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> List<CartItemsEntityModel> productEntityModel;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> OnItemClickListener onItemClickListener;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> Context context;
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">CartRecyclerAdapter</span><span class="hljs-params" style="box-sizing: inherit;">(Context context, List<CartItemsEntityModel> productEntityModel)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>.context = context;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>.productEntityModel = productEntityModel;
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">updateItem</span><span class="hljs-params" style="box-sizing: inherit;">(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> position, CartItemsEntityModel cartItemsEntityModel)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">if</span>(cartItemsEntityModel.getQuantity() > <span class="hljs-number" style="box-sizing: inherit; color: #986801;">0</span>) {
productEntityModel.set(position, cartItemsEntityModel);
CartHelper.getCart().update(cartItemsEntityModel.getProduct(), cartItemsEntityModel.getQuantity());
} <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">else</span> {
CartHelper.getCart().remove(productEntityModel.get(position).getProduct());
onItemClickListener.onUpdateList();
}
notifyDataSetChanged();
}
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> RecyclerView.<span class="hljs-function" style="box-sizing: inherit;">ViewHolder <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onCreateViewHolder</span><span class="hljs-params" style="box-sizing: inherit;">(ViewGroup parent, <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> viewType)</span> </span>{
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_cart, parent, <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">false</span>);
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> ReceiveViewHolder(view);
}
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onBindViewHolder</span><span class="hljs-params" style="box-sizing: inherit;">(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">final</span> RecyclerView.ViewHolder holder, <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">final</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> position)</span> </span>{
ReceiveViewHolder viewHolder = (ReceiveViewHolder) holder;
viewHolder.name.setText(productEntityModel.get(position).getProduct().getName());
viewHolder.description.setText(productEntityModel.get(position).getProduct().getDescription());
viewHolder.price.setText(String.format(context.getString(R.string.dollars_format), productEntityModel.get(position).getProduct().getPrice()));
viewHolder.quantity.setText(String.valueOf(productEntityModel.get(position).getQuantity()));
Picasso.with(context).load(productEntityModel.get(position).getProduct().getImage()).into(viewHolder.image);
}
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">getItemCount</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> productEntityModel.size();
}
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-class" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">class</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">ReceiveViewHolder</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">extends</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">RecyclerView</span>.<span class="hljs-title" style="box-sizing: inherit; color: #c18401;">ViewHolder</span> </span>{
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@BindView</span>(R.id.name)
TextView name;
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@BindView</span>(R.id.description)
TextView description;
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@BindView</span>(R.id.image)
ImageView image;
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@BindView</span>(R.id.price)
TextView price;
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@BindView</span>(R.id.quantity)
TextView quantity;
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@BindView</span>(R.id.plus)
Button plus;
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@BindView</span>(R.id.minus)
Button minus;
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">ReceiveViewHolder</span><span class="hljs-params" style="box-sizing: inherit;">(View itemView)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">super</span>(itemView);
ButterKnife.bind(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>, itemView);
itemView.setOnClickListener(view -> {
onItemClickListener.onItemClick(productEntityModel.get(getAdapterPosition()));
});
minus.setOnClickListener(view -> {
onItemClickListener.onItemMinusClicked(getAdapterPosition(), productEntityModel.get(getAdapterPosition()));
});
plus.setOnClickListener(view -> {
onItemClickListener.onItemPlusClicked(getAdapterPosition(), productEntityModel.get(getAdapterPosition()));
});
}
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">setOnItemClickListener</span><span class="hljs-params" style="box-sizing: inherit;">(OnItemClickListener onItemClickListener)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>.onItemClickListener = onItemClickListener;
}
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-class" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">interface</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">OnItemClickListener</span> </span>{
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onItemClick</span><span class="hljs-params" style="box-sizing: inherit;">(CartItemsEntityModel cartItemsEntityModel)</span></span>;
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onItemPlusClicked</span><span class="hljs-params" style="box-sizing: inherit;">(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> position, CartItemsEntityModel cartItemsEntityModel)</span></span>;
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onItemMinusClicked</span><span class="hljs-params" style="box-sizing: inherit;">(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> position, CartItemsEntityModel cartItemsEntityModel)</span></span>;
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onUpdateList</span><span class="hljs-params" style="box-sizing: inherit;">()</span></span>;
}
}
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Значит то что у нас в конструкторе мы сетим список который у нас в корзине я думаю понятно. Дальше в методе updateItem() мы или увеличиваем количество определенного товара или уменьшаем. Если уменьшаем до 0 то просто стираем товар из списка. Ну а дальше по старинке onCreateViewHolder() — сетит леяут. onBindViewHolder() биндит то что у нас в списке в вьюхи.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">item_cart.xml</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="xml hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;"><?xml version="1.0" encoding="utf-8"?></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">LinearLayout</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">xmlns:android</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"http://schemas.android.com/apk/res/android"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">xmlns:app</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"http://schemas.android.com/apk/res-auto"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_width</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_height</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"wrap_content"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_marginLeft</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"10dp"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_marginTop</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"10dp"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:background</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@color/white"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:foreground</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"?android:selectableItemBackground"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:gravity</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"center_vertical|center_horizontal"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:orientation</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"horizontal"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:padding</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"20dp"</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">ImageView</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:id</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@+id/image"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_width</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"100dp"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_height</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"100dp"</span> /></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">LinearLayout</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_width</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_height</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_marginLeft</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"20dp"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:orientation</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"vertical"</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">TextView</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:id</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@+id/name"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_width</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_height</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"wrap_content"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:text</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"TextView"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:textColor</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@color/black"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:textSize</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"18sp"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:textStyle</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"bold"</span> /></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">TextView</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:id</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@+id/description"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_width</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_height</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_marginTop</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"10dp"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_weight</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"0.1"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:text</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"TextView"</span> /></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">LinearLayout</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_width</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_height</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"wrap_content"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:gravity</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"center_vertical"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:orientation</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"horizontal"</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">Button</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:id</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@+id/minus"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_width</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"25dp"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_height</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"25dp"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:background</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@drawable/button_cart_round_background_gradient"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:text</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"-"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:textColor</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@color/white"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:textSize</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"18sp"</span> /></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">TextView</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:id</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@+id/quantity"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_width</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"wrap_content"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_height</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"wrap_content"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_marginLeft</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"20dp"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_marginRight</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"20dp"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:text</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"1"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:textColor</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@color/black"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:textSize</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"18sp"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:textStyle</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"bold"</span> /></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">Button</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:id</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@+id/plus"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_width</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"25dp"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_height</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"25dp"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:background</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@drawable/button_cart_round_background_gradient"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:text</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"+"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:textColor</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@color/white"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:textSize</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"18sp"</span> /></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">TextView</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:id</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@+id/price"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_width</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"wrap_content"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_height</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"wrap_content"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_weight</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"1"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:gravity</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"right"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:text</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"TextView"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:textColor</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@color/black"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:textSize</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"18sp"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:textStyle</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"bold"</span> /></span>
<span class="hljs-tag" style="box-sizing: inherit;"></<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">LinearLayout</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"></<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">LinearLayout</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"></<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">LinearLayout</span>></span>
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Ну тут у нас в общем все тоже самое что было и в продукте, только немного изменили до вида корзины, добавили кнопки "+" и "-". </span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Ну и не забываем добавить в манифест пермишен на работу с интернетом, а то у нас картинки не будут отображаться.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">AndroidManifest.xml</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="xml hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;"><?xml version="1.0" encoding="utf-8"?></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">manifest</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">xmlns:android</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"http://schemas.android.com/apk/res/android"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">package</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"project.dajver.com.cartviewwithbadge"</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">uses-permission</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:name</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"android.permission.INTERNET"</span> /></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">application</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:allowBackup</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"true"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:icon</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@mipmap/ic_launcher"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:label</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@string/app_name"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:roundIcon</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@mipmap/ic_launcher_round"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:supportsRtl</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"true"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:theme</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@style/AppTheme"</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">activity</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:name</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">".product.ProductActivity"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:label</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@string/products"</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">intent-filter</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">action</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:name</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"android.intent.action.MAIN"</span> /></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">category</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:name</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"android.intent.category.LAUNCHER"</span> /></span>
<span class="hljs-tag" style="box-sizing: inherit;"></<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">intent-filter</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"></<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">activity</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">activity</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:name</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">".cart.CartActivity"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:label</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@string/cart"</span> /></span>
<span class="hljs-tag" style="box-sizing: inherit;"></<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">application</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"></<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">manifest</span>></span>
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Добавили активити которые мы используем, добавили пермишены и собственно все.</span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;"><br /></span>
<span style="color: #222222; font-size: large;"><span style="background-color: white;"><b>Исходники:</b></span></span><br />
<span style="color: #222222; font-size: large;"><span style="background-color: white;"><b><a href="https://github.com/dajver/CartWithBadgeExample">GitHub</a></b></span></span></div>
dajverhttp://www.blogger.com/profile/09427222798699404442noreply@blogger.com0tag:blogger.com,1999:blog-5677605911484164185.post-81498006903131351702018-04-19T20:56:00.003+03:002018-04-19T21:01:12.118+03:00Форматируемый EditText для номеров телефона или email'ов<div dir="ltr" style="text-align: left;" trbidi="on">
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Как-то на одном проекте нужно было сделать формат ввода телефона прям очень жестким, что бы оно не давало пользователю двинуться ни вправо ни влево. Полазив по интернету нашел кучу либ которые умеют красивенько это делать, но ради одной строчки не хотелось подключать целую библиотеку и начал я еще по интернету лазить и набрел на какой-то репозиторий на котором я отрыл прям кусок кода — кастомного EditText который умеет все тоже самое что и либы, только это все в одном файле и его можно редактировать как душе угодно!</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<div style="text-align: center;">
<img alt="image" height="92" src="https://github.com/dajver/MaskedEditText/blob/master/imgs/image.gif?raw=true" style="background-color: white; border-style: none; box-sizing: inherit; color: #222222; font-size: 16px; margin: 0px; max-width: 100%; vertical-align: middle;" width="400" /></div>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">В общем результат можно видеть выше, работает просто на ура, и то что нужно для любого проекта где нам нужны жесткие рамки для ввода номера телефона или почты на пример.</span><br />
<a href="https://www.blogger.com/null" name="habracut" style="background-color: white; box-sizing: inherit; color: #548eaa; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;"></a><br />
<a name='more'></a><span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Сама вьюха является наследником EditText'a, соответственно все методы что доступны у EditText'a будут доступны и этой вьюхе, только она еще будет это красивенько форматировать под стиль который мы укажем в верстке этой вьюхи.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">MaskedEditText.java</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="java hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.content.Context;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.content.res.TypedArray;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.text.Editable;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.text.InputFilter;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.text.Selection;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.text.SpannableStringBuilder;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.text.Spanned;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.text.TextWatcher;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.util.AttributeSet;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> project.dajver.com.maskedittext.R;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-class" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">class</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">MaskedEditText</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">extends</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">android</span>.<span class="hljs-title" style="box-sizing: inherit; color: #c18401;">support</span>.<span class="hljs-title" style="box-sizing: inherit; color: #c18401;">v7</span>.<span class="hljs-title" style="box-sizing: inherit; color: #c18401;">widget</span>.<span class="hljs-title" style="box-sizing: inherit; color: #c18401;">AppCompatEditText</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">static</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">final</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">char</span> NUMBER_MASK = <span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">'9'</span>;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">static</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">final</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">char</span> ALPHA_MASK = <span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">'A'</span>;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">static</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">final</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">char</span> ALPHANUMERIC_MASK = <span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">'*'</span>;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">static</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">final</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">char</span> CHARACTER_MASK = <span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">'?'</span>;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">static</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">final</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">char</span> ESCAPE_CHAR = <span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">'\\'</span>;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> String mask;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> String placeholder;
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">MaskedEditText</span><span class="hljs-params" style="box-sizing: inherit;">(Context context)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>(context, <span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">""</span>);
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">MaskedEditText</span><span class="hljs-params" style="box-sizing: inherit;">(Context context, String mask)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>(context, mask, <span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">' '</span>);
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">MaskedEditText</span><span class="hljs-params" style="box-sizing: inherit;">(Context context, String mask, <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">char</span> placeholder)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>(context, <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">null</span>, mask, placeholder);
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">MaskedEditText</span><span class="hljs-params" style="box-sizing: inherit;">(Context context, AttributeSet attr)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>(context, attr, <span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">""</span>);
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">MaskedEditText</span><span class="hljs-params" style="box-sizing: inherit;">(Context context, AttributeSet attr, String mask)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>(context, attr, <span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">""</span>, <span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">' '</span>);
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">MaskedEditText</span><span class="hljs-params" style="box-sizing: inherit;">(Context context, AttributeSet attr, String mask, <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">char</span> placeholder)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">super</span>(context, attr);
TypedArray a = context.obtainStyledAttributes(attr, R.styleable.MaskedEditText);
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">final</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> N = a.getIndexCount();
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">for</span> (<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> i = <span class="hljs-number" style="box-sizing: inherit; color: #986801;">0</span>; i < N; ++i)
{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> at = a.getIndex(i);
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">switch</span> (at)
{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">case</span> R.styleable.MaskedEditText_mask:
mask = (mask.length() > <span class="hljs-number" style="box-sizing: inherit; color: #986801;">0</span> ? mask : a.getString(at));
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">break</span>;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">case</span> R.styleable.MaskedEditText_placeholder:
placeholder = (a.getString(at).length() > <span class="hljs-number" style="box-sizing: inherit; color: #986801;">0</span> && placeholder == <span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">' '</span> ? a.getString(at).charAt(<span class="hljs-number" style="box-sizing: inherit; color: #986801;">0</span>) : placeholder);
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">break</span>;
}
}
a.recycle();
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>.mask = mask;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>.placeholder = String.valueOf(placeholder);
addTextChangedListener(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> MaskTextWatcher());
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">if</span> (mask.length() > <span class="hljs-number" style="box-sizing: inherit; color: #986801;">0</span>)
setText(getText()); <span class="hljs-comment" style="box-sizing: inherit; color: #a0a1a7; font-style: italic;">// sets the text to create the mask</span>
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> String <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">getMask</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> mask;
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">setMask</span><span class="hljs-params" style="box-sizing: inherit;">(String mask)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>.mask = mask;
setText(getText());
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">char</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">getPlaceholder</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> placeholder.charAt(<span class="hljs-number" style="box-sizing: inherit; color: #986801;">0</span>);
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">setPlaceholder</span><span class="hljs-params" style="box-sizing: inherit;">(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">char</span> placeholder)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>.placeholder = String.valueOf(placeholder);
setText(getText());
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> Editable <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">getText</span><span class="hljs-params" style="box-sizing: inherit;">(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">boolean</span> removeMask)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">if</span> (!removeMask) {
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> getText();
} <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">else</span> {
SpannableStringBuilder value = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> SpannableStringBuilder(getText());
stripMaskChars(value);
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> value;
}
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">formatMask</span><span class="hljs-params" style="box-sizing: inherit;">(Editable value)</span> </span>{
InputFilter[] inputFilters = value.getFilters();
value.setFilters(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> InputFilter[<span class="hljs-number" style="box-sizing: inherit; color: #986801;">0</span>]);
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> i = <span class="hljs-number" style="box-sizing: inherit; color: #986801;">0</span>;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> j = <span class="hljs-number" style="box-sizing: inherit; color: #986801;">0</span>;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> maskLength = <span class="hljs-number" style="box-sizing: inherit; color: #986801;">0</span>;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">boolean</span> treatNextCharAsLiteral = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">false</span>;
Object selection = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> Object();
value.setSpan(selection, Selection.getSelectionStart(value), Selection.getSelectionEnd(value), Spanned.SPAN_MARK_MARK);
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">while</span> (i < mask.length()) {
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">if</span> (!treatNextCharAsLiteral && isMaskChar(mask.charAt(i))) {
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">if</span> (j >= value.length()) {
value.insert(j, placeholder);
value.setSpan(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> PlaceholderSpan(), j, j + <span class="hljs-number" style="box-sizing: inherit; color: #986801;">1</span>, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
j++;
} <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">else</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">if</span> (!matchMask(mask.charAt(i), value.charAt(j))) {
value.delete(j, j + <span class="hljs-number" style="box-sizing: inherit; color: #986801;">1</span>);
i--;
maskLength--;
} <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">else</span> {
j++;
}
maskLength++;
} <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">else</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">if</span> (!treatNextCharAsLiteral && mask.charAt(i) == ESCAPE_CHAR) {
treatNextCharAsLiteral = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">true</span>;
} <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">else</span> {
value.insert(j, String.valueOf(mask.charAt(i)));
value.setSpan(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> LiteralSpan(), j, j + <span class="hljs-number" style="box-sizing: inherit; color: #986801;">1</span>, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
treatNextCharAsLiteral = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">false</span>;
j++;
maskLength++;
}
i++;
}
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">while</span> (value.length() > maskLength) {
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> pos = value.length() - <span class="hljs-number" style="box-sizing: inherit; color: #986801;">1</span>;
value.delete(pos, pos + <span class="hljs-number" style="box-sizing: inherit; color: #986801;">1</span>);
}
Selection.setSelection(value, value.getSpanStart(selection), value.getSpanEnd(selection));
value.removeSpan(selection);
value.setFilters(inputFilters);
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">stripMaskChars</span><span class="hljs-params" style="box-sizing: inherit;">(Editable value)</span> </span>{
PlaceholderSpan[] pspans = value.getSpans(<span class="hljs-number" style="box-sizing: inherit; color: #986801;">0</span>, value.length(), PlaceholderSpan.class);
LiteralSpan[] lspans = value.getSpans(<span class="hljs-number" style="box-sizing: inherit; color: #986801;">0</span>, value.length(), LiteralSpan.class);
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">for</span> (<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> k = <span class="hljs-number" style="box-sizing: inherit; color: #986801;">0</span>; k < pspans.length; k++) {
value.delete(value.getSpanStart(pspans[k]), value.getSpanEnd(pspans[k]));
}
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">for</span> (<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> k = <span class="hljs-number" style="box-sizing: inherit; color: #986801;">0</span>; k < lspans.length; k++) {
value.delete(value.getSpanStart(lspans[k]), value.getSpanEnd(lspans[k]));
}
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">boolean</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">matchMask</span><span class="hljs-params" style="box-sizing: inherit;">(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">char</span> mask, <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">char</span> value)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">boolean</span> ret = (mask == NUMBER_MASK && Character.isDigit(value));
ret = ret || (mask == ALPHA_MASK && Character.isLetter(value));
ret = ret || (mask == ALPHANUMERIC_MASK && (Character.isDigit(value) || Character.isLetter(value)));
ret = ret || mask == CHARACTER_MASK;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> ret;
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">boolean</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">isMaskChar</span><span class="hljs-params" style="box-sizing: inherit;">(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">char</span> mask)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">switch</span> (mask) {
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">case</span> NUMBER_MASK:
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">case</span> ALPHA_MASK:
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">case</span> ALPHANUMERIC_MASK:
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">case</span> CHARACTER_MASK:
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">true</span>;
}
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">false</span>;
}
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> <span class="hljs-class" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">class</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">MaskTextWatcher</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">implements</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">TextWatcher</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">boolean</span> updating = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">false</span>;
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">afterTextChanged</span><span class="hljs-params" style="box-sizing: inherit;">(Editable s)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">if</span> (updating || mask.length() == <span class="hljs-number" style="box-sizing: inherit; color: #986801;">0</span>)
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span>;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">if</span> (!updating) {
updating = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">true</span>;
stripMaskChars(s);
formatMask(s);
updating = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">false</span>;
}
}
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">beforeTextChanged</span><span class="hljs-params" style="box-sizing: inherit;">(CharSequence s, <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> start, <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> count, <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> after)</span> </span>{
}
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onTextChanged</span><span class="hljs-params" style="box-sizing: inherit;">(CharSequence s, <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> start, <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> before, <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> count)</span> </span>{
}
}
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> <span class="hljs-class" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">class</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">PlaceholderSpan</span> </span>{
<span class="hljs-comment" style="box-sizing: inherit; color: #a0a1a7; font-style: italic;">// this class is used just to keep track of placeholders in the text</span>
}
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> <span class="hljs-class" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">class</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">LiteralSpan</span> </span>{
<span class="hljs-comment" style="box-sizing: inherit; color: #a0a1a7; font-style: italic;">// this class is used just to keep track of literal chars in the text</span>
}
}
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Кода много, делает он многое, но вся настройка происходит именно тут. Маска у нас вся будет настраивается из xml, соответственно нам нужен файл атрибутов для того что бы эти параметры передавать из xml во вьюху, для этого нам нужну создать файл attrs.xml и в него вписать нужные нам атрибуты.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">attrs.xml</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="xml hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;"><?xml version="1.0" encoding="utf-8"?></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">resources</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">declare-styleable</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">name</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"MaskedEditText"</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">attr</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">name</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"mask"</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">format</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"string"</span> /></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">attr</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">name</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"placeholder"</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">format</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"string"</span> /></span>
<span class="hljs-tag" style="box-sizing: inherit;"></<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">declare-styleable</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"></<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">resources</span>></span>
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">А дальше смотрим в констркутор который у нас самый последний, и в нем у нас идет настройка, в нем задается сама маска в виде 99 (999) 99-99-999, и задается разделитель который будет внизу под цифрами, остальной код у нас добавляет этот фильтр на текст и все. Я, честно, весь код рассматривать не буду, его тут много, часть сетит текст в вьюху, часть изменяет его, и несколько методов которые возвращают текст отформатированный или же пустой, то есть чисто введенные цифры.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Дальше нам нужно это как-то использовать, а как? Просто. Достаточно добавить в наш activity_main нашу вьюху, и дальше настроить ее на наш лад.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">activity_main.xml</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="xml hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;"><?xml version="1.0" encoding="utf-8"?></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">LinearLayout</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">xmlns:android</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"http://schemas.android.com/apk/res/android"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">xmlns:app</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"http://schemas.android.com/apk/res-auto"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_width</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_height</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:padding</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"20dp"</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">project.dajver.com.maskedittext.view.MaskedEditText</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:id</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@+id/phone"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_width</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_height</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"wrap_content"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:inputType</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"phone"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">app:mask</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"+99 (999) 999-99-99"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">app:placeholder</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"_"</span> /></span>
<span class="hljs-tag" style="box-sizing: inherit;"></<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">LinearLayout</span>></span>
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Мы задали формат маски — "+99 (999) 999-99-99", и задали что бы разделителем был "_", дальше поставили тип ввода что бы были цифры без точек и запятых, только цифры, и на этом все. После запуска, можно будет проверить как оно будет работать. Очень удобно и просто в использовании, спасибо тому доброму человеку который это сделал :)</span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;"><br /></span>
<span style="color: #222222; font-size: large;"><span style="background-color: white;"><b>Исходники:</b></span></span><br />
<span style="color: #222222; font-size: large;"><span style="background-color: white;"><b><a href="https://github.com/dajver/MaskedEditText">GitHub</a></b></span></span></div>
dajverhttp://www.blogger.com/profile/09427222798699404442noreply@blogger.com3tag:blogger.com,1999:blog-5677605911484164185.post-15867783987939549482018-04-10T18:06:00.000+03:002018-04-10T18:08:07.468+03:00Анимирование кнопка с прогрессом долгого нажатия<div dir="ltr" style="text-align: left;" trbidi="on">
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Бывают не тривиальные задания на подобии создания простых вьюх которые расширяют функционал приложения, добавляют какую-то изюминку, так вот в нашем случае у нас будет кнопка по нажатию и удержанию на которую у нас будет происходить заполнение кнопки, а по достижению конца кнопки анимация будет обнуляться, и будет отображаться сообщение о том что мы закончили задание. </span><br />
<br />
<div style="text-align: center;">
<img alt="image" height="400" src="https://github.com/dajver/LongPressButtonView/blob/master/img/example.gif?raw=true" style="background-color: white; border-style: none; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px; margin: 0px; max-width: 100%; vertical-align: middle;" width="223" /></div>
<a href="https://www.blogger.com/null" name="habracut" style="background-color: white; box-sizing: inherit; color: #548eaa; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;"></a><br />
<a name='more'></a><span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Просто и красиво. Начнем мы с того что подключим как не странно только одну библиотеку, ButterKnife. Этого нам будет достаточно для написания этой вью. По сути ButterKnife особо нам в этом не поможет, но поможет красиво подключать в активити и вьюхах элементы без не красивого findViewById.</span><br />
<br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="java hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;">dependencies {
<span class="hljs-function" style="box-sizing: inherit;">implementation <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">fileTree</span><span class="hljs-params" style="box-sizing: inherit;">(dir: <span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">'libs'</span>, include: [<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">'*.jar'</span>])</span>
implementation 'com.android.support:appcompat-v7:27.1.1'
compile 'com.jakewharton:butterknife:8.8.1'
annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'
}
</span></code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Тут у нас только ButterKnife и SupportLibrary. Этого и хватит. Дальше перейдем к написанию вьюхи которая будет у нас как бы задним фоном кнопки, в ней у нас будет рисоваться сама кнопка и логика анимации заполнения.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">ButtonBackgroundView.java</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="java hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.animation.Animator;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.animation.AnimatorListenerAdapter;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.animation.ValueAnimator;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.content.Context;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.graphics.Canvas;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.graphics.Color;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.graphics.Paint;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.graphics.RectF;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.util.AttributeSet;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.view.View;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> project.dajver.com.longclickbuttonview.R;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-class" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">class</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">ButtonBackgroundView</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">extends</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">View</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> Paint mSolidPaint;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> RectF mSolidRect;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">float</span> mSolidMultiplier;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">float</span> mClipMultiplier;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> Paint mStrokePaint;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> RectF mStrokeRect;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">float</span> mStrokeMultiplier;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> Paint mWipePaint;
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">ButtonBackgroundView</span><span class="hljs-params" style="box-sizing: inherit;">(Context context)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">super</span>(context);
init();
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">ButtonBackgroundView</span><span class="hljs-params" style="box-sizing: inherit;">(Context context, AttributeSet attrs)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">super</span>(context, attrs);
init();
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">ButtonBackgroundView</span><span class="hljs-params" style="box-sizing: inherit;">(Context context, AttributeSet attrs, <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> defStyleAttr)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">super</span>(context, attrs, defStyleAttr);
init();
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">init</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
mSolidPaint = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> Paint();
mSolidPaint.setColor(getResources().getColor(R.color.colorPrimary));
mSolidPaint.setAntiAlias(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">true</span>);
mStrokePaint = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> Paint();
mStrokePaint.setColor(getResources().getColor(R.color.colorPrimary));
mStrokePaint.setStyle(Paint.Style.STROKE);
mStrokePaint.setStrokeWidth(getResources().getDimension(R.dimen.ring_width));
mStrokePaint.setAntiAlias(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">true</span>);
mWipePaint = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> Paint();
mWipePaint.setColor(Color.WHITE);
mWipePaint.setAlpha(<span class="hljs-number" style="box-sizing: inherit; color: #986801;">51</span>);
mWipePaint.setAntiAlias(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">true</span>);
mSolidRect = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> RectF();
mStrokeRect = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> RectF();
resetAnimatedValues();
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">resetAnimatedValues</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
mSolidMultiplier = <span class="hljs-number" style="box-sizing: inherit; color: #986801;">1.0f</span>;
mStrokeMultiplier = <span class="hljs-number" style="box-sizing: inherit; color: #986801;">1.0f</span>;
mStrokePaint.setAlpha(<span class="hljs-number" style="box-sizing: inherit; color: #986801;">0</span>);
}
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">protected</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onDraw</span><span class="hljs-params" style="box-sizing: inherit;">(Canvas canvas)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> width = canvas.getWidth();
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">float</span> halfWidth = width / <span class="hljs-number" style="box-sizing: inherit; color: #986801;">2.0f</span>;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">float</span> adjustedHalfWidth = halfWidth * <span class="hljs-number" style="box-sizing: inherit; color: #986801;">0.78260869565217f</span>;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">float</span> solidHalfWidth = adjustedHalfWidth * mSolidMultiplier;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">float</span> strokeHalfWidth = adjustedHalfWidth * mStrokeMultiplier;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">float</span> strokeDifference = strokeHalfWidth - solidHalfWidth;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> height = canvas.getHeight();
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">float</span> halfHeight = height / <span class="hljs-number" style="box-sizing: inherit; color: #986801;">2.0f</span>;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">float</span> solidHalfHeight = halfHeight * mSolidMultiplier * <span class="hljs-number" style="box-sizing: inherit; color: #986801;">0.46808510638298f</span>;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">float</span> strokeHeightDifference = solidHalfHeight + strokeDifference;
canvas.drawARGB(<span class="hljs-number" style="box-sizing: inherit; color: #986801;">0</span>, <span class="hljs-number" style="box-sizing: inherit; color: #986801;">0</span>, <span class="hljs-number" style="box-sizing: inherit; color: #986801;">0</span>, <span class="hljs-number" style="box-sizing: inherit; color: #986801;">0</span>);
mStrokeRect.set(halfWidth - strokeHalfWidth, halfHeight - strokeHeightDifference, halfWidth + strokeHalfWidth, halfHeight + strokeHeightDifference);
canvas.drawRoundRect(mStrokeRect, strokeHeightDifference, strokeHeightDifference, mStrokePaint);
mSolidRect.set(halfWidth - solidHalfWidth, halfHeight - solidHalfHeight, halfWidth + solidHalfWidth, halfHeight + solidHalfHeight);
canvas.drawRoundRect(mSolidRect, solidHalfHeight, solidHalfHeight, mSolidPaint);
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">float</span> clipStart = halfWidth - solidHalfWidth;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">float</span> clipEnd = clipStart + (solidHalfWidth * <span class="hljs-number" style="box-sizing: inherit; color: #986801;">2.0f</span>) * mClipMultiplier;
canvas.clipRect(clipStart, <span class="hljs-number" style="box-sizing: inherit; color: #986801;">0</span>, clipEnd, height);
canvas.drawRoundRect(mSolidRect, solidHalfHeight, solidHalfHeight, mWipePaint);
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> Animator <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">getWipeAnimator</span><span class="hljs-params" style="box-sizing: inherit;">(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">long</span> animationTimeMs)</span> </span>{
ValueAnimator wipeAnimator = ValueAnimator.ofFloat(<span class="hljs-number" style="box-sizing: inherit; color: #986801;">0.0f</span>, <span class="hljs-number" style="box-sizing: inherit; color: #986801;">1.0f</span>).setDuration(animationTimeMs);
wipeAnimator.addUpdateListener(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> ValueAnimator.AnimatorUpdateListener() {
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onAnimationUpdate</span><span class="hljs-params" style="box-sizing: inherit;">(ValueAnimator valueAnimator)</span> </span>{
mClipMultiplier = valueAnimator.getAnimatedFraction();
invalidate();
}
});
wipeAnimator.addListener(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> AnimatorListenerAdapter() {
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onAnimationCancel</span><span class="hljs-params" style="box-sizing: inherit;">(Animator animation)</span> </span>{
mClipMultiplier = <span class="hljs-number" style="box-sizing: inherit; color: #986801;">0f</span>;
invalidate();
}
});
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> wipeAnimator;
}
}</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">В самом верху класса мы определили какие переменные нам понадобятся для отрисовки кнопки, дальше в конструкторе проинициализировали метод init(), в котором у нас идет инициализация цвета фона, скругление, и т.д. В этом методе у нас вызывается метод resetAnimatedValues() который обнуляет всю анимацию на вьюхе, когда она у нас первый раз появляется на экране, в дальнейшем она понадобится для возвращения вьюхи в прежний вид когда мы ее закрасим другим цветом. </span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">В методе onDraw() мы производим определенные манипуляции по рисованию кнопки, задаем форму кнопки, цвет, сразу рисуем поверх всего наш прогресс, но делаем его равным 0, так как в дальнейшем мы будем его увеличивать до определенного состояния.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">И в getWipeAnimator() мы меняем состояние нашего слоя прогресса для того что бы отображать продолжительность нажатия кнопки.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Так же нам нужно добавить colors и dimens которые используются в этой вьюхе. У меня они выглядят вот так.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">color.xml</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="xml hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;"><?xml version="1.0" encoding="utf-8"?></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">resources</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">color</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">name</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"colorPrimary"</span>></span>#3F51B5<span class="hljs-tag" style="box-sizing: inherit;"></<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">color</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">color</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">name</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"colorPrimaryDark"</span>></span>#303F9F<span class="hljs-tag" style="box-sizing: inherit;"></<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">color</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">color</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">name</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"colorAccent"</span>></span>#FF4081<span class="hljs-tag" style="box-sizing: inherit;"></<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">color</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">color</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">name</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"white"</span>></span>#FFF<span class="hljs-tag" style="box-sizing: inherit;"></<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">color</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"></<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">resources</span>></span>
</code></pre>
<br />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">dimens.xml</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="xml hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;"><?xml version="1.0" encoding="utf-8"?></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">resources</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">dimen</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">name</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"ring_width"</span>></span>2dp<span class="hljs-tag" style="box-sizing: inherit;"></<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">dimen</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">dimen</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">name</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"button_width"</span>></span>330dp<span class="hljs-tag" style="box-sizing: inherit;"></<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">dimen</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">dimen</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">name</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"button_height"</span>></span>94dp<span class="hljs-tag" style="box-sizing: inherit;"></<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">dimen</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"></<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">resources</span>></span>
</code></pre>
<br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Теперь нам нужно используя эту вьюху создать еще одну, которая будет комбинировать в себе наш фон, и текст поверх него.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">ButtonView.java</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="java hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.animation.Animator;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.content.Context;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.graphics.Rect;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.os.Handler;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.util.AttributeSet;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.view.LayoutInflater;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.view.MotionEvent;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.view.View;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.widget.FrameLayout;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> butterknife.BindView;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> butterknife.ButterKnife;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> butterknife.OnTouch;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> project.dajver.com.longclickbuttonview.R;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-class" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">class</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">ButtonView</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">extends</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">FrameLayout</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">static</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">final</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">long</span> HOLD_TIME_MS = <span class="hljs-number" style="box-sizing: inherit; color: #986801;">1800L</span>;
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@BindView</span>(R.id.background)
ButtonBackgroundView mBackground;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> Animator mLongPressAnimator;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> Rect mBoundsRectangle;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> Handler mHandler;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> OnButtonLongPressReachedEndListener listener;
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">ButtonView</span><span class="hljs-params" style="box-sizing: inherit;">(Context context)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">super</span>(context);
init();
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">ButtonView</span><span class="hljs-params" style="box-sizing: inherit;">(Context context, AttributeSet attrs)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">super</span>(context, attrs);
init();
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">ButtonView</span><span class="hljs-params" style="box-sizing: inherit;">(Context context, AttributeSet attrs, <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> defStyleAttr)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">super</span>(context, attrs, defStyleAttr);
init();
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">init</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
LayoutInflater.from(getContext()).inflate(R.layout.view_long_press_button, <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>);
ButterKnife.bind(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>);
mBoundsRectangle = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> Rect();
mHandler = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> Handler();
}
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> Runnable mOnLongPressed = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> Runnable() {
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">run</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">if</span> (mLongPressAnimator != <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">null</span>) {
mLongPressAnimator.cancel();
listener.onButtonLongPressReachedEnd();
}
}
};
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@OnTouch</span>(R.id.hold_to_end_button)
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">boolean</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onTouchPulsingButton</span><span class="hljs-params" style="box-sizing: inherit;">(View view, MotionEvent event)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">switch</span> (event.getAction()) {
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">case</span> MotionEvent.ACTION_DOWN:
mBoundsRectangle.set(view.getLeft(), view.getTop(), view.getRight(), view.getBottom());
mLongPressAnimator = mBackground.getWipeAnimator(HOLD_TIME_MS);
mLongPressAnimator.start();
mHandler.postDelayed(mOnLongPressed, HOLD_TIME_MS);
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">break</span>;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">case</span> MotionEvent.ACTION_MOVE:
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">if</span> (mBoundsRectangle.contains(view.getLeft() + (<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span>) event.getX(), view.getTop() + (<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span>) event.getY())) {
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">break</span>;
}
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">case</span> MotionEvent.ACTION_UP:
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">case</span> MotionEvent.ACTION_CANCEL:
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">case</span> MotionEvent.ACTION_OUTSIDE:
mHandler.removeCallbacks(mOnLongPressed);
mLongPressAnimator.cancel();
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">break</span>;
}
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">true</span>;
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">setOnButtonLongPressReachedEndListener</span><span class="hljs-params" style="box-sizing: inherit;">(OnButtonLongPressReachedEndListener listener)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>.listener = listener;
}
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-class" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">interface</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">OnButtonLongPressReachedEndListener</span> </span>{
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onButtonLongPressReachedEnd</span><span class="hljs-params" style="box-sizing: inherit;">()</span></span>;
}
}
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Эта вьюха нам нужна для того что бы наша кнопка выглядела полноценно, что бы у нас был не просто закругленный прямоугольник, а еще и текст который бы пояснял что нужно сделать для достижения нужного эфекта. Собственно в самом верху класса мы проинициализировали наш ButtonBackgroundView, задали количество секунд (1800L) которые мы будем использовать для расчета окончания нажатия, и несколько переменных для анимации, таймера и лисенер для создания колбека в активити по окончанию действия.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Проинициализировав метод init() в конструкторах, и подключив наш layout в этом методе мы переходим дальше. В методе mOnLongPressed() проверяется, что если mLongPressAnimator != null, значит удаляем анимацию из вьюхи, и возвращаем в колбек что пользователь достиг конца кнопки, а если же mLongPressAnimator будет равен null, будет значит что не дождался…</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">onTouchPulsingButton() у нас отслеживает долгое нажатие и создает анимацию появления прогресса на кнопке, в зависимости от статуса. Если это ACTION_DOWN — мы рисуем анимацию по таймеру, заполняя mBoundsRectangle, который нам нужен для просчета размера кнопки, что бы кнопка заполнялась в не зависимости от размеров которые мы ей задали в начале. Если же это ACTION_UP, ACTION_CANCEL или ACTION_OUTSIDE — мы убираем ее с вьюхи и отключаем таймер.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Ну, а в самом низу класса у нас колбек и сеттер для него. Они нам нужны для того что бы получать результат и возвращать его в активити.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Сам же xml вьюхи выглядит вот так:</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">view_long_press_button.xml</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="xml hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;"><?xml version="1.0" encoding="utf-8"?></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">FrameLayout</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">xmlns:android</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"http://schemas.android.com/apk/res/android"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:id</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@+id/hold_to_end_button"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_width</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@dimen/button_width"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_height</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@dimen/button_height"</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">project.dajver.com.longclickbuttonview.view.ButtonBackgroundView</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:id</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@+id/background"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_width</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_height</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"match_parent"</span>/></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">TextView</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:id</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@+id/text"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_width</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_height</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:gravity</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"center"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:text</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@string/hold.to.end"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:textAllCaps</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"false"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:textColor</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@color/white"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:textSize</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"24sp"</span>/></span>
<span class="hljs-tag" style="box-sizing: inherit;"></<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">FrameLayout</span>></span>
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Подключили наш фон для кнопки, и положили текст поверх нее текст для того что бы было хоть чуть-чуть похоже на кнопку, вроде бы выглядит убедительно.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Ну а теперь осталось только заиспользовать эту кнопку в нашей активити.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">MainActivity.java</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="java hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.os.Bundle;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.support.v7.app.AppCompatActivity;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.widget.Toast;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> butterknife.BindView;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> butterknife.ButterKnife;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> project.dajver.com.longclickbuttonview.view.ButtonView;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-class" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">class</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">MainActivity</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">extends</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">AppCompatActivity</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">implements</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">ButtonView</span>.<span class="hljs-title" style="box-sizing: inherit; color: #c18401;">OnButtonLongPressReachedEndListener</span> </span>{
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@BindView</span>(R.id.buttonView)
ButtonView buttonView;
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">protected</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onCreate</span><span class="hljs-params" style="box-sizing: inherit;">(Bundle savedInstanceState)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">super</span>.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>);
buttonView.setOnButtonLongPressReachedEndListener(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>);
}
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onButtonLongPressReachedEnd</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
Toast.makeText(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>, getString(R.string.you_ended_this_button), Toast.LENGTH_LONG).show();
}
}
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">В onCreate() проинициализировали layout, ButterKnife и назначили колбеку место где он будет возвращать результат. onButtonLongPressReachedEnd() наш метод который возвращает результат. Собственно и все. Наша размета будет выглядеть очень просто.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">activity_main.xml</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="xml hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;"><?xml version="1.0" encoding="utf-8"?></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">LinearLayout</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">xmlns:android</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"http://schemas.android.com/apk/res/android"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_width</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_height</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:gravity</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"center_vertical|center_horizontal"</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">project.dajver.com.longclickbuttonview.view.ButtonView</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:id</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@+id/buttonView"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_width</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"wrap_content"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_height</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"wrap_content"</span> /></span>
<span class="hljs-tag" style="box-sizing: inherit;"></<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">LinearLayout</span>></span>
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Просто добавили кнопку на экран и отцетровали, собственно и все.</span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;"><br /></span>
<span style="color: #222222; font-size: large;"><span style="background-color: white;"><b>Исходники:</b></span></span><br />
<span style="color: #222222; font-size: large;"><span style="background-color: white;"><b><a href="https://github.com/dajver/LongPressButtonView">GitHub</a></b></span></span></div>
dajverhttp://www.blogger.com/profile/09427222798699404442noreply@blogger.com0tag:blogger.com,1999:blog-5677605911484164185.post-77522096575123588312018-03-20T14:23:00.000+02:002018-04-03T18:52:59.507+03:00Кастомная CarouselView в домашних условиях<div dir="ltr" style="text-align: left;" trbidi="on">
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Очень давно ничего не писал, как всегда куча проектов и куча времени уходит на работу, но тут выдался свободный часок и я решил написать по быстрому заметку об карусели которую я как-то реализовывал в одном проекте. </span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Для реализации карусели я использовал готовую библиотеку </span><a href="https://github.com/gtomato/carouselview" style="background-color: white; box-sizing: inherit; color: #992298; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px; text-decoration-line: none;">CarouselView</a><span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;"> но немного ее изменив.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Что бы вы понимали что такое карусель, вот пример того что реализует библиотека которую я использовал для реализации своей</span><br />
<div style="text-align: center;">
<img alt="image" height="400" src="https://camo.githubusercontent.com/3f11838582c1fa4cedac5a08eb738d2ccc22509a/68747470733a2f2f67746f6d61746f2e6769746875622e696f2f6361726f7573656c766965772f6d656469612f6d65727279676f726f756e642d666c61742e676966" style="background-color: white; border-style: none; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px; margin: 0px; max-width: 100%; vertical-align: middle;" width="224" /></div>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Мне же нужно было что бы карусель работала немного иначе чем она сделанна, мне нужно было что бы главная картинка была большая, а остальные были как бы позади нее.</span><br />
<div style="text-align: center;">
<img alt="image" height="400" src="https://github.com/dajver/CarouselView/blob/master/img/example.gif?raw=true" style="background-color: white; border-style: none; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px; margin: 0px; max-width: 100%; vertical-align: middle;" width="223" /></div>
<a href="https://www.blogger.com/null" name="habracut" style="background-color: white; box-sizing: inherit; color: #548eaa; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;"></a><br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;"></span><br />
<a name='more'></a><br />
<br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">В общем начнем делать нашу карусель. Добавляем несколько библиотек в build.gradle.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">app/build.gradle</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="java hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;">dependencies {
<span class="hljs-function" style="box-sizing: inherit;">implementation <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">fileTree</span><span class="hljs-params" style="box-sizing: inherit;">(dir: <span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">'libs'</span>, include: [<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">'*.jar'</span>])</span>
implementation 'com.android.support:appcompat-v7:26.1.0'
implementation 'com.gtomato.android.library:carouselview:2.0.1'
implementation 'com.jakewharton:butterknife:8.8.1'
annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'
implementation 'com.squareup.picasso:picasso:2.5.2'
}
</span></code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Тут мы добавили ButterKnife для подгрузки вьюх, Picasso для загрузки картинок и CarouselView для карусели. Дальше нам нужно написать собственный класс «трансформатор» который будет создавать 3Д эффект.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">FlatMarryGoRoundSyndTransformer.java</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="java hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.view.View;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> com.gtomato.android.ui.manager.CarouselLayoutManager;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> com.gtomato.android.ui.widget.CarouselView;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-class" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">class</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">FlatMarryGoRoundSyndTransformer</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">implements</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">CarouselView</span>.<span class="hljs-title" style="box-sizing: inherit; color: #c18401;">ViewTransformer</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> mNumPies = <span class="hljs-number" style="box-sizing: inherit; color: #986801;">3</span>;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">double</span> mPieRad = Math.PI * <span class="hljs-number" style="box-sizing: inherit; color: #986801;">2.0</span> / mNumPies;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">double</span> mHorizontalViewPort = <span class="hljs-number" style="box-sizing: inherit; color: #986801;">0.55</span>;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">double</span> mViewPerspective = -<span class="hljs-number" style="box-sizing: inherit; color: #986801;">0.6</span>;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">double</span> mFarScale = <span class="hljs-number" style="box-sizing: inherit; color: #986801;">0.55</span>;
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onAttach</span><span class="hljs-params" style="box-sizing: inherit;">(CarouselLayoutManager layoutManager)</span> </span>{
layoutManager.setDrawOrder(CarouselView.DrawOrder.CenterFront);
}
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">transform</span><span class="hljs-params" style="box-sizing: inherit;">(View view, <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">float</span> position)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> parentWidth = ((View) view.getParent()).getMeasuredWidth();
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> parentHeight = ((View) view.getParent()).getMeasuredHeight();
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">double</span> rotateRad = Math.PI * <span class="hljs-number" style="box-sizing: inherit; color: #986801;">1.5</span> + position * mPieRad;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">double</span> a = parentWidth * mHorizontalViewPort / <span class="hljs-number" style="box-sizing: inherit; color: #986801;">2.0</span>;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">double</span> b = parentHeight * mViewPerspective / <span class="hljs-number" style="box-sizing: inherit; color: #986801;">3</span>;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">double</span> x = a * Math.cos(rotateRad);
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">double</span> y = b * (<span class="hljs-number" style="box-sizing: inherit; color: #986801;">1</span> - Math.sin(rotateRad));
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">double</span> maxY = <span class="hljs-number" style="box-sizing: inherit; color: #986801;">2</span> * b;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">double</span> scale = Math.max(<span class="hljs-number" style="box-sizing: inherit; color: #986801;">0</span>, (mFarScale - <span class="hljs-number" style="box-sizing: inherit; color: #986801;">1</span>) * (y - maxY) / (<span class="hljs-number" style="box-sizing: inherit; color: #986801;">0</span> - maxY) + <span class="hljs-number" style="box-sizing: inherit; color: #986801;">1</span>);
y -= maxY;
view.setTranslationX((<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">float</span>) x);
view.setTranslationY((<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">float</span>) y);
view.setScaleX((<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">float</span>) scale);
view.setScaleY((<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">float</span>) scale);
}
}
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Тут очень сложная математика происходит, я не уверен что я сам понял что сделал, но в целом постараюсь описать логику. Все настройки для работы карусели у нас находятся в самом верху класса в переменных mNumPies, mPieRad, mHorizontalViewPort, mViewPerspective и mFarScale.</span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">mNumPies — количество айтемов на экране.</span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">mPieRad — с его помощью мы расчитываем количество айтемов.</span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">mHorizontalViewPort — горизонтальная перспектива для отображения айтемов.</span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">mViewPerspective — вертикальная перспектива с которой будут отображаться айтемы.</span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">mFarScale — как далеко они будут находиться друг от друга.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">В самом верху метода transform() мы получаем размеры вьюхи что бы поместить на нее нашу горзинтально скролящийся RecyclerView. Дальше по формуле элипса мы раскладываем перспективу</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<code style="background-color: white; box-sizing: inherit; color: #222222; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px;">x(t) = a cos t<br style="box-sizing: inherit;" />y(t) = b sin t<br style="box-sizing: inherit;" />where t ∈ [0, 2π]</code><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Далее у нас размер будет зависеть от mViewPerspective, то есть если мы поставим не -0.6, а на пример 1 — скейл увеличится и будет так что картинки будут по бокам будут больше чем центральная. Дальше переставляем центральную позицию айтема так что бы он был y </span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<code style="background-color: white; box-sizing: inherit; color: #222222; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px;">∈ [-maxY/2, maxY/2]</code><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">то есть по центру главный и по бокам все остальные элементы списка. Дальше задаем все эти данные для перемещения по x и y, и для размера на экране. По этому классу все.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Дальше нам нужно создать адаптер что бы он отображал наши картинки которые мы хотим отображать. </span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">CarouselRecyclerAdapter.java</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="java hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.content.Context;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.support.v7.widget.RecyclerView;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.view.LayoutInflater;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.view.View;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.view.ViewGroup;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.widget.ImageView;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> com.squareup.picasso.Picasso;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> java.util.ArrayList;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> java.util.List;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> butterknife.BindView;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> butterknife.ButterKnife;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> project.dajver.com.carouselview.R;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-class" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">class</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">CarouselRecyclerAdapter</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">extends</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">RecyclerView</span>.<span class="hljs-title" style="box-sizing: inherit; color: #c18401;">Adapter</span><<span class="hljs-title" style="box-sizing: inherit; color: #c18401;">RecyclerView</span>.<span class="hljs-title" style="box-sizing: inherit; color: #c18401;">ViewHolder</span>> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> List<String> carouselList = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> ArrayList<>();
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> Context context;
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">CarouselRecyclerAdapter</span><span class="hljs-params" style="box-sizing: inherit;">(Context context, List<String> carouselList)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>.context = context;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>.carouselList = carouselList;
}
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> RecyclerView.<span class="hljs-function" style="box-sizing: inherit;">ViewHolder <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onCreateViewHolder</span><span class="hljs-params" style="box-sizing: inherit;">(ViewGroup parent, <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> viewType)</span> </span>{
View rowView = LayoutInflater.from(context).inflate(R.layout.item_carousel, <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">null</span>);
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> ViewHolder(rowView);
}
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onBindViewHolder</span><span class="hljs-params" style="box-sizing: inherit;">(RecyclerView.ViewHolder holder, <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> position)</span> </span>{
ViewHolder viewHolder = (ViewHolder) holder;
Picasso.with(context).load(carouselList.get(position)).into(viewHolder.image);
}
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">getItemCount</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> carouselList.size();
}
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-class" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">class</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">ViewHolder</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">extends</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">RecyclerView</span>.<span class="hljs-title" style="box-sizing: inherit; color: #c18401;">ViewHolder</span></span>{
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@BindView</span>(R.id.promImage)
ImageView image;
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">ViewHolder</span><span class="hljs-params" style="box-sizing: inherit;">(View view)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">super</span>(view);
ButterKnife.bind(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>, view);
}
}
}
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Тут все стандартно, мы создали адаптер, в нем указали какой леяут будем использовать для отображения вью, дальше присвоили каждому айтему картинку по позишену и собственно все. </span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">item_carousel.xml</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="xml hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;"><?xml version="1.0" encoding="utf-8"?></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">LinearLayout</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">xmlns:android</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"http://schemas.android.com/apk/res/android"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_width</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_height</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"wrap_content"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:gravity</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"center_horizontal"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:orientation</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"vertical"</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">ImageView</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:id</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@+id/promImage"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_width</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"100dp"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_height</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"150dp"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_gravity</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"center_horizontal"</span> /></span>
<span class="hljs-tag" style="box-sizing: inherit;"></<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">LinearLayout</span>></span>
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Добавляем на наш айтем ImageView, размером 100 по ширине и 150 по высоте, что бы был как постер. И дальше собираем все это до кучи в нашем MainActivity. XML для MainActivity будет выглядеть тоже очень просто.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">activity_main.xml</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="xml hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;"><?xml version="1.0" encoding="utf-8"?></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">LinearLayout</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">xmlns:android</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"http://schemas.android.com/apk/res/android"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_width</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_height</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:gravity</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"center_vertical"</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">com.gtomato.android.ui.widget.CarouselView</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:id</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@+id/carousel"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_width</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_height</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"150dp"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_alignParentBottom</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"true"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_alignParentLeft</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"true"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_alignParentStart</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"true"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_marginBottom</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"5dp"</span> /></span>
<span class="hljs-tag" style="box-sizing: inherit;"></<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">LinearLayout</span>></span>
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">По сути просто разместили карусель вью на экране для использовани в дальнейших извращениях.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">MainActivity.java</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="java hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.os.Bundle;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.support.v7.app.AppCompatActivity;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.support.v7.widget.RecyclerView;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.view.View;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.widget.Toast;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> com.gtomato.android.ui.widget.CarouselView;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> java.util.ArrayList;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> java.util.List;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> butterknife.BindView;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> butterknife.ButterKnife;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> project.dajver.com.carouselview.adapter.CarouselRecyclerAdapter;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> project.dajver.com.carouselview.view.FlatMarryGoRoundSyndTransformer;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-class" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">class</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">MainActivity</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">extends</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">AppCompatActivity</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">implements</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">CarouselView</span>.<span class="hljs-title" style="box-sizing: inherit; color: #c18401;">OnItemClickListener</span> </span>{
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@BindView</span>(R.id.carousel)
CarouselView carouselView;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> List<String> carouselList;
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">protected</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onCreate</span><span class="hljs-params" style="box-sizing: inherit;">(Bundle savedInstanceState)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">super</span>.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>);
carouselList = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> ArrayList<>();
carouselList.add(<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"https://s-media-cache-ak0.pinimg.com/originals/f2/d2/eb/f2d2eb69fb80e312d310c32786bf8182.png"</span>);
carouselList.add(<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"https://vignette.wikia.nocookie.net/marveldatabase/images/1/1a/The_Avengers_%28film%29_poster_011.jpg"</span>);
carouselList.add(<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"https://i.pinimg.com/originals/13/35/b1/1335b128be40578eec379be437f02de7.jpg"</span>);
carouselList.add(<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"https://i.pinimg.com/originals/6d/2b/b3/6d2bb3023ada5ea320f54bb4fc3fe50a.jpg"</span>);
carouselList.add(<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"http://moviemarker.co.uk/wp-content/uploads/2012/03/Thor-Film-Poster.jpg"</span>);
carouselList.add(<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"http://www.cbc.ca/strombo/content/images/a-cool-look-at-rejected-posters-for-classic-films-feature2.jpg"</span>);
carouselList.add(<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"http://mediablogs.keshacademy.com/cmacleannanwatkinsas/files/2016/09/free-movie-film-poster-harry-potter-phoenix-2iwng7l.jpg"</span>);
CarouselRecyclerAdapter carouselRecyclerAdapter = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> CarouselRecyclerAdapter(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>, carouselList);
carouselView.setTransformer(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> FlatMarryGoRoundSyndTransformer());
carouselView.setAdapter(carouselRecyclerAdapter);
carouselView.setOnItemClickListener(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>);
}
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onItemClick</span><span class="hljs-params" style="box-sizing: inherit;">(RecyclerView.Adapter adapter, View view, <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> position, <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> adapterPosition)</span> </span>{
Toast.makeText(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>, carouselList.get(position), Toast.LENGTH_LONG).show();
}
}
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">В onCreate() мы задали список картинок, дальше передали этот список в адаптер, потом задали этот адаптер в карусель вью и задали наш трансформер FlatMarryGoRoundSyndTransformer для карусели, который мы только вот написали. Ну и присвоили onClick метод для карусели. </span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">И не забываем добавить пермишены для доступа в интернет что бы картинки подгрузились.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">AndroidManifest.xml</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="xml hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"> <span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">uses-permission</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:name</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"android.permission.INTERNET"</span> /></span>
</code></pre>
<br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">И вот так вот мы смогли сделать красивенькую карусель для отображения картинок в приложении. Возможно это будет кому-то полезно.</span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;"><br /></span>
<span style="color: #222222; font-size: large;"><span style="background-color: white;"><b>Исходники:</b></span></span><br />
<span style="color: #222222; font-size: large;"><span style="background-color: white;"><b><a href="https://github.com/dajver/CarouselView">GitHub</a></b></span></span></div>
dajverhttp://www.blogger.com/profile/09427222798699404442noreply@blogger.com0tag:blogger.com,1999:blog-5677605911484164185.post-21263615035764447572017-12-28T14:57:00.002+02:002017-12-28T14:57:20.280+02:00Рисование полигона на GoogleMap в виде круга для выделения области карты<div dir="ltr" style="text-align: left;" trbidi="on">
<span style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;">Наверняка многие сталкивались с такой штукой как рисование на карте, может не в разработке, но в использовании каких либо приложений, их просто куча. Так вот заказчики бывает насмотрятся на такие приложения и потом хотят себе такое же, а ты сидишь такой, не знаешь за что хвататься, а тут еще и эта фича которую ты вообще без понятия как реализовывать. По этому это маленькая заметка будет о том как рисовать радиус на карте, сохранять список выделенных координат и дальше что-то с ними делать, отправлять на сервер, или же расчитывать какие-то параметры, это уже как говорится на выбор разработчика.</span><br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" /><br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" /><span style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;">Все как бы на много проще чем кажется, по сути вся эта статья будет состоять из одного класса, очень не привычно для моего блога, так как я обычно у меня проект если состоит из какого-то кода, то это куча классов и методов которые что-то делают, но сегодня будет не так.</span><br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" /><br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" /><div style="text-align: center;">
<img alt="image" height="400" src="https://github.com/dajver/DrawFreeHandPolygoneMap/raw/master/imgs/img_screenshoot.png?raw=true" style="background-color: white; border-style: none; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px; margin: 0px; max-width: 100%; vertical-align: middle;" width="224" /></div>
<a href="https://www.blogger.com/null" name="habracut" style="background-color: white; box-sizing: inherit; color: #548eaa; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;"></a><a name='more'></a><br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" /><span style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;">В общем в нашем MainActivity нам нужно будет подключить карту, и после этого отследить onTouch событие когда пользователь будет рисовать на карте, а потом что бы после того как будет нарисован какой-то круг, вся область за этим кругом была затемнена, а сам круг был обычного цвета карты, что бы был акцент именно на этой области. В общем как на скриншоте. По этому давайте подключим все библиотеки, у нас это ButterKnife и maps api.</span><br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" /><br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" /><span style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px; font-weight: bolder;">app/build.gradle</span><br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" /><pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="java hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;">dependencies {
<span class="hljs-function" style="box-sizing: inherit;">implementation <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">fileTree</span><span class="hljs-params" style="box-sizing: inherit;">(dir: <span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">'libs'</span>, include: [<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">'*.jar'</span>])</span>
implementation 'com.android.support:appcompat-v7:26.1.0'
implementation 'com.google.android.gms:play-services-location:9.6.1'
implementation 'com.google.android.gms:play-services-maps:9.6.1'
compile 'com.jakewharton:butterknife:8.8.1'
annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'
}
</span></code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" /><span style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;">ButterKnife используем для удобства подключения вьюх и остальных ресурсов в проект. Карты очевидно используем для отображения карт :)</span><br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" /><br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" /><span style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;">Дальше нам нужно нарисовать нашу разметку, в ней у нас будет карта и фрейм леяут поверх нее.</span><br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" /><br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" /><span style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px; font-weight: bolder;">activity_main.xml</span><br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" /><pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="xml hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;"><?xml version="1.0" encoding="utf-8"?></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">FrameLayout</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">xmlns:android</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"http://schemas.android.com/apk/res/android"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_width</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"fill_parent"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_height</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"fill_parent"</span> ></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">fragment</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:id</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@+id/map"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_width</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"fill_parent"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_height</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"fill_parent"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">class</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"com.google.android.gms.maps.SupportMapFragment"</span> /></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">FrameLayout</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:id</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@+id/fram_map"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_width</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"fill_parent"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_height</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"fill_parent"</span> ></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">Button</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:id</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@+id/drawBtn"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_width</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"wrap_content"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_height</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"wrap_content"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:onClick</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"onDrawClick"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:text</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"Free Draw"</span> /></span>
<span class="hljs-tag" style="box-sizing: inherit;"></<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">FrameLayout</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"></<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">FrameLayout</span>></span>
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" /><span style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;">Как я и говорил, у нас будет карта, она будет у нас основным объектом на экране, поверх у нас FrameLayout в котором кнопка по нажатию на которую мы будем чистить карту и потом рисован на ней.</span><br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" /><br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" /><span style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px; font-weight: bolder;">MainActivity.java</span><br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" /><pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="java hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.graphics.Point;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.os.Bundle;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.support.v7.app.AppCompatActivity;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.util.Log;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.view.MotionEvent;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.view.View;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.widget.Button;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.widget.FrameLayout;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> com.google.android.gms.maps.GoogleMap;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> com.google.android.gms.maps.OnMapReadyCallback;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> com.google.android.gms.maps.SupportMapFragment;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> com.google.android.gms.maps.model.LatLng;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> com.google.android.gms.maps.model.Polygon;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> com.google.android.gms.maps.model.PolygonOptions;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> com.google.android.gms.maps.model.PolylineOptions;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> java.util.ArrayList;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> java.util.List;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> butterknife.BindColor;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> butterknife.BindView;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> butterknife.ButterKnife;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> butterknife.OnClick;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-class" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">class</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">MainActivity</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">extends</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">AppCompatActivity</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">implements</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">OnMapReadyCallback</span>, <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">View</span>.<span class="hljs-title" style="box-sizing: inherit; color: #c18401;">OnTouchListener</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> GoogleMap googleMap;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> source = <span class="hljs-number" style="box-sizing: inherit; color: #986801;">0</span>;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> destination = <span class="hljs-number" style="box-sizing: inherit; color: #986801;">1</span>;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">boolean</span> isMapMoveable = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">false</span>;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">boolean</span> screenLeave = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">false</span>;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> ArrayList<LatLng> latLngArrayList = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> ArrayList<>();
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@BindView</span>(R.id.fram_map)
FrameLayout framMap;
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@BindView</span>(R.id.drawBtn)
Button drawBtn;
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@BindColor</span>(R.color.colorPrimary)
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> colorPrimary;
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@BindColor</span>(R.color.transparentGray)
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> transparentGray;
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">protected</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onCreate</span><span class="hljs-params" style="box-sizing: inherit;">(Bundle savedInstanceState)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">super</span>.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>);
SupportMapFragment customMapFragment = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map));
customMapFragment.getMapAsync(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>);
}
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@OnClick</span>(R.id.drawBtn)
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onDrawClick</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
isMapMoveable = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">true</span>;
drawBtn.setVisibility(View.GONE);
latLngArrayList.removeAll(latLngArrayList);
googleMap.clear();
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">drawMap</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">if</span> (latLngArrayList.size() > <span class="hljs-number" style="box-sizing: inherit; color: #986801;">1</span>) {
googleMap.addPolyline(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> PolylineOptions().add(
latLngArrayList.get(source),
latLngArrayList.get(destination))
.width(<span class="hljs-number" style="box-sizing: inherit; color: #986801;">20</span>)
.color(colorPrimary)
);
source++;
destination++;
}
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> List<LatLng> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">createOuterBounds</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">final</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">float</span> delta = <span class="hljs-number" style="box-sizing: inherit; color: #986801;">0.01f</span>;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> ArrayList<LatLng>() {{
add(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> LatLng(<span class="hljs-number" style="box-sizing: inherit; color: #986801;">90</span> - delta, -<span class="hljs-number" style="box-sizing: inherit; color: #986801;">180</span> + delta));
add(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> LatLng(<span class="hljs-number" style="box-sizing: inherit; color: #986801;">0</span>, -<span class="hljs-number" style="box-sizing: inherit; color: #986801;">180</span> + delta));
add(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> LatLng(-<span class="hljs-number" style="box-sizing: inherit; color: #986801;">90</span> + delta, -<span class="hljs-number" style="box-sizing: inherit; color: #986801;">180</span> + delta));
add(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> LatLng(-<span class="hljs-number" style="box-sizing: inherit; color: #986801;">90</span> + delta, <span class="hljs-number" style="box-sizing: inherit; color: #986801;">0</span>));
add(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> LatLng(-<span class="hljs-number" style="box-sizing: inherit; color: #986801;">90</span> + delta, <span class="hljs-number" style="box-sizing: inherit; color: #986801;">180</span> - delta));
add(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> LatLng(<span class="hljs-number" style="box-sizing: inherit; color: #986801;">0</span>, <span class="hljs-number" style="box-sizing: inherit; color: #986801;">180</span> - delta));
add(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> LatLng(<span class="hljs-number" style="box-sizing: inherit; color: #986801;">90</span> - delta, <span class="hljs-number" style="box-sizing: inherit; color: #986801;">180</span> - delta));
add(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> LatLng(<span class="hljs-number" style="box-sizing: inherit; color: #986801;">90</span> - delta, <span class="hljs-number" style="box-sizing: inherit; color: #986801;">0</span>));
add(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> LatLng(<span class="hljs-number" style="box-sizing: inherit; color: #986801;">90</span> - delta, -<span class="hljs-number" style="box-sizing: inherit; color: #986801;">180</span> + delta));
}};
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">drawFinalPolygon</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
latLngArrayList.add(latLngArrayList.get(<span class="hljs-number" style="box-sizing: inherit; color: #986801;">0</span>));
PolygonOptions polygonOptions = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> PolygonOptions();
polygonOptions.fillColor(transparentGray);
polygonOptions.addAll(createOuterBounds());
polygonOptions.strokeColor(colorPrimary);
polygonOptions.strokeWidth(<span class="hljs-number" style="box-sizing: inherit; color: #986801;">20</span>);
polygonOptions.addHole(latLngArrayList);
Polygon polygon = googleMap.addPolygon(polygonOptions);
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">for</span>(LatLng latLng : polygon.getPoints()) {
Log.e(<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"latitude"</span>, <span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">""</span> + latLng.latitude);
Log.e(<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"longitude"</span>, <span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">""</span> + latLng.longitude);
}
}
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onMapReady</span><span class="hljs-params" style="box-sizing: inherit;">(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">final</span> GoogleMap googleMap)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>.googleMap = googleMap;
framMap.setOnTouchListener(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>);
}
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">boolean</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onTouch</span><span class="hljs-params" style="box-sizing: inherit;">(View view, MotionEvent event)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">if</span> (isMapMoveable) {
Point point = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> Point(Math.round(event.getX()), Math.round(event.getY()));
LatLng latLng = googleMap.getProjection().fromScreenLocation(point);
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">double</span> latitude = latLng.latitude;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">double</span> longitude = latLng.longitude;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> eventaction = event.getAction();
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">switch</span> (eventaction) {
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">case</span> MotionEvent.ACTION_DOWN:
screenLeave = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">false</span>;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">case</span> MotionEvent.ACTION_MOVE:
latLngArrayList.add(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> LatLng(latitude, longitude));
screenLeave = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">false</span>;
drawMap();
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">case</span> MotionEvent.ACTION_UP:
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">if</span> (!screenLeave) {
screenLeave = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">true</span>;
} <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">else</span> {
isMapMoveable = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">false</span>;
source = <span class="hljs-number" style="box-sizing: inherit; color: #986801;">0</span>;
destination = <span class="hljs-number" style="box-sizing: inherit; color: #986801;">1</span>;
drawBtn.setVisibility(View.VISIBLE);
drawFinalPolygon();
}
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">break</span>;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">default</span>:
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">break</span>;
}
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">if</span> (isMapMoveable) {
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">true</span>;
} <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">else</span> {
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">false</span>;
}
} <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">else</span> {
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">false</span>;
}
}
}
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" /><span style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;">Рассмотрим все по порядку. В самом верху класса мы определили все переменные и ресурсы типа карты, GoogleMap и ArrayList в который мы будем сохранять наши координаты. </span><br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" /><span style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;">Дальше в методе onCreate() мы подключили SupportMapFragment и ButterKnife. </span><br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" /><span style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;">Метод onDrawClick() обрабатывает клик по кнопке, чистит карту делает карту рисовабельной и удаляет все из списка.</span><br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" /><span style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;">drawMap() — метод который добавляет полигоны на карту по ходу дела рисования пальцем на карте.</span><br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" /><span style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;">createOuterBounds() — метод который зарисовывает всю область вокруг нарисованного круга.</span><br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" /><span style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;">drawFinalPolygon() — очевидно рисует финальную версию полигона на карте по координатам которые мы сохранили в ArrayList и заканчивает круг в начальную точку с которой он начинался. Ну и дальше по желанию распечатывает в лог координаты которые были использованы на карте.</span><br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" /><span style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;">onMapReady() — метод класса GoogleMap, он вызывается когда карта готова к использованию.</span><br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" /><span style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;">onTouch() — метод в котором происходит вся магия, в начале мы проверяем если карта готова к началу рисования, то есть проверяется isMapMoveable, если да, тогда мы начинаем отслеживать нажатие на экран и отслеживать координаты на карте. По окончанию когда мы отпускаем карту по событию MotionEvent.ACTION_UP мы делаем isMapMoveable = false для того что бы мы снова могли двигать картой. И делаем кнопку снова видимой для очистки экрана и новой возможности для рисования.</span><br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" /><br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" /><span style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;">Не забываем что нам нужно в AndroidManifest прописать доступ в интернет и мета-данные для работы с картой.</span><br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" /><br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" /><span style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px; font-weight: bolder;">AndroidManifest.xml</span><br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" /><pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="xml hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;"><?xml version="1.0" encoding="utf-8"?></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">manifest</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">xmlns:android</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"http://schemas.android.com/apk/res/android"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">package</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"project.dajver.com.drawgesturesmap"</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">uses-permission</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:name</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"android.permission.INTERNET"</span> /></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">application</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:allowBackup</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"true"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:icon</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@mipmap/ic_launcher"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:label</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@string/app_name"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:supportsRtl</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"true"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:theme</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@style/AppTheme"</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">activity</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:name</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">".MainActivity"</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">intent-filter</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">action</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:name</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"android.intent.action.MAIN"</span> /></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">category</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:name</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"android.intent.category.LAUNCHER"</span> /></span>
<span class="hljs-tag" style="box-sizing: inherit;"></<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">intent-filter</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"></<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">activity</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">meta-data</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:name</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"com.google.android.geo.API_KEY"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:value</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@string/google.maps.api.key"</span>/></span>
<span class="hljs-tag" style="box-sizing: inherit;"></<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">application</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"></<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">manifest</span>></span>
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" /><span style="color: #222222; font-size: large;"><span style="background-color: white;"><b>Исходники:</b></span></span><br />
<span style="color: #222222; font-size: large;"><span style="background-color: white;"><b><a href="https://github.com/dajver/DrawFreeHandPolygoneMap">GitHub</a></b></span></span></div>
dajverhttp://www.blogger.com/profile/09427222798699404442noreply@blogger.com0tag:blogger.com,1999:blog-5677605911484164185.post-70136727506967909512017-12-07T00:19:00.000+02:002017-12-07T01:08:56.138+02:00Конвертируем PPT в картинку<div dir="ltr" style="text-align: left;" trbidi="on">
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjCRpybHNgSQC8M389WQ_VC5dDnTLrK5uwHJm-5iAOtaUu4LidwDql946hk8FTiw5oMWa_R30wGnaO4dp3JRiXr6eoJXII9lnnTy-Zfnows94hDpF_cxjWHI3jJA3MJAnGPdcrQg-B4IeQ/s1600/ppt-to-jpg-300.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="180" data-original-width="300" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjCRpybHNgSQC8M389WQ_VC5dDnTLrK5uwHJm-5iAOtaUu4LidwDql946hk8FTiw5oMWa_R30wGnaO4dp3JRiXr6eoJXII9lnnTy-Zfnows94hDpF_cxjWHI3jJA3MJAnGPdcrQg-B4IeQ/s1600/ppt-to-jpg-300.jpg" /></a></div>
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Значит про конвертацию PDF в картинку мы поговорили, а вот про конвертацию PowerPoint слайдов в картинки мы еще не видели. По сути проект такой же как и </span><a href="http://dajver.blogspot.com/2017/12/pdf.html" style="background-color: white; box-sizing: inherit; color: #992298; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px; text-decoration-line: none;">предыдущий</a><span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">, структуру он будет иметь такую же, я не знаю зачем я пишу отдельную статью, наверно для удобства что бы не мешать колбасу с макаронами. В любом случае я создал два проекта на гитхабе и полезней когда функции разделены для примера в разные проекты, ну мне так кажется. </span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Написание данной функции такое же как и в предыдущей статье, пришлось выкручиваться так как просмотрщиков ppt файлов особо нет, по этому приходится разделять слайды на картинки и потом собирать их в том же ViewPager. Опять же, в примере я буду получать всего одну картинку, но если захотеть то можно в цикле получать весь список слайдов и потом сохранять их и отображать в ViewPager. </span><br />
<a name='more'></a><br />
В проекте как всегда будем использовать библиотеки. Самая главная либа которая нас интересует это <a href="https://mvnrepository.com/artifact/org.apache.poi/poi-scratchpad/3.2-FINAL" style="background-color: white; box-sizing: inherit; color: #992298; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px; text-decoration-line: none;">POI</a><span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;"> которая позволяет читать Microsoft'овские файлы, просто всемогущая библиотека. Я уже писал про нее как-то </span><a href="http://dajver.blogspot.com/2014/02/ms-excel-android.html" style="background-color: white; box-sizing: inherit; color: #992298; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px; text-decoration-line: none;">пару лет назад</a><span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">, там я разбирал как читать Excel файлы, как оказалось опыт 2х годичной давности пригодился. Так же у нас будет </span><a href="https://github.com/Karumi/Dexter" style="background-color: white; box-sizing: inherit; color: #992298; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px; text-decoration-line: none;">Dexter</a><span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;"> для запроса пермишена на чтение и запись и </span><a href="https://github.com/JakeWharton/butterknife" style="background-color: white; box-sizing: inherit; color: #992298; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px; text-decoration-line: none;">ButterKnife</a><span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;"> для удобного поиска вьюх в xml.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">app/build.gradle</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="java hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;">dependencies {
<span class="hljs-function" style="box-sizing: inherit;">implementation <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">fileTree</span><span class="hljs-params" style="box-sizing: inherit;">(dir: <span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">'libs'</span>, include: [<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">'*.jar'</span>])</span>
implementation 'com.android.support:appcompat-v7:26.1.0'
implementation 'org.apache.poi:poi-scratchpad:3.2-FINAL'
implementation 'com.karumi:dexter:4.2.0'
implementation 'com.jakewharton:butterknife:8.8.1'
annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'
}
</span></code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">После подключения всех либ, мы как и в предыдущем проекте должны создать </span><a href="https://github.com/dajver/PPTToImageExample/blob/master/app/src/main/java/project/dajver/com/ppttoimage/task/utils/ImageFilePathUtils.java" style="background-color: white; box-sizing: inherit; color: #992298; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px; text-decoration-line: none;">ImageFilePathUtils</a><span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">, что бы не постить его во второй раз я просто оставлю ссылку на него на GitHub, все равно все исходники доступны там.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Этот класс нам нужен для удобного преобразования ссылки на файл полученный в onActivityResult() после того как мы достанем его из файлового менеджера.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Дальше нам нужно создать AsyncTask который будет конвертировать файл. Опять же как и в </span><a href="http://dajver.blogspot.com/2017/12/pdf.html" style="background-color: white; box-sizing: inherit; color: #992298; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px; text-decoration-line: none;">предыдущем проекте</a><span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;"> я не буду использовать Rx потому что простота тут на первом месте, по этому кому надо тот переделает этот AsynkTask в вид RxAndroid'a.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">PPTToImageTask.java</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="java hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.content.Context;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.os.AsyncTask;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> org.apache.poi.hslf.HSLFSlideShow;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> org.apache.poi.hslf.usermodel.PictureData;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> org.apache.poi.poifs.filesystem.POIFSFileSystem;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> java.io.File;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> java.io.FileInputStream;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> java.io.FileOutputStream;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> java.io.IOException;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-class" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">class</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">PPTToImageTask</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">extends</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">AsyncTask</span><<span class="hljs-title" style="box-sizing: inherit; color: #c18401;">String</span>, <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">Integer</span>, <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">String</span>> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> Context context;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> OnFileWasConvertedListener onFileWasConvertedListener;
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">PPTToImageTask</span><span class="hljs-params" style="box-sizing: inherit;">(Context context)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>.context = context;
}
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">protected</span> String <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">doInBackground</span><span class="hljs-params" style="box-sizing: inherit;">(String... strings)</span> </span>{
HSLFSlideShow ppt = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">null</span>;
FileOutputStream out = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">null</span>;
File newFile = getCacheDir(context);;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">try</span> {
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">final</span> String pathToFile = strings[<span class="hljs-number" style="box-sizing: inherit; color: #986801;">0</span>];
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">final</span> String extension = pathToFile.substring(pathToFile.lastIndexOf(<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"."</span>));
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">if</span> (extension.toLowerCase().equals(<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">".ppt"</span>)) {
POIFSFileSystem fs = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> POIFSFileSystem(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> FileInputStream(pathToFile));
ppt = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> HSLFSlideShow(fs);
PictureData[] pdata = ppt.getPictures();
PictureData pict = pdata[<span class="hljs-number" style="box-sizing: inherit; color: #986801;">0</span>];
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">byte</span>[] data = pict.getData();
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">if</span> (newFile.exists()) {
newFile.delete();
}
out = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> FileOutputStream(newFile);
out.write(data);
out.close();
}
} <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">catch</span> (IOException e) {
e.printStackTrace();
}
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> newFile != <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">null</span> ? newFile.getAbsolutePath() : <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">null</span>;
}
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">protected</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onPostExecute</span><span class="hljs-params" style="box-sizing: inherit;">(String result)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">if</span> (result != <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">null</span>) {
File file = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> File(result);
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">if</span> (file.exists()) {
onFileWasConvertedListener.onFileWasConverted(file.getAbsolutePath());
}
}
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">setOnFileWasConvertedListener</span><span class="hljs-params" style="box-sizing: inherit;">(OnFileWasConvertedListener onFileWasConvertedListener)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>.onFileWasConvertedListener = onFileWasConvertedListener;
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> File <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">getCacheDir</span><span class="hljs-params" style="box-sizing: inherit;">(Context context)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> context.getCacheDir();
}
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-class" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">interface</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">OnFileWasConvertedListener</span> </span>{
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onFileWasConverted</span><span class="hljs-params" style="box-sizing: inherit;">(String path)</span></span>;
}
}
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">В этом классе нас интересует метод doInBackground() в котором происходит вся конвертация. В нем мы получаем ссылку на файл дальше после проверок расширения файла и создания пустого для записи мы переходим к разбиванию файла с помощью класса POIFSFileSystem в который мы передали ссылку на файл, дальше методов getPictures() мы получили массив картинок со слайдера и с помощью не сложных махинаций pdata[0] получили первый слайд, ну и дальше сохраняем это все в файл — картинку и передаем ссылку на этот файл в колбек который возвращает эту ссылку в activity.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Дальше в активити мы просто отображаем то, что у нас вышло в конвертации.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">activity_main.xml</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="xml hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;"><?xml version="1.0" encoding="utf-8"?></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">LinearLayout</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">xmlns:android</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"http://schemas.android.com/apk/res/android"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">xmlns:app</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"http://schemas.android.com/apk/res-auto"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_width</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_height</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:gravity</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"center_vertical|center_horizontal"</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">RelativeLayout</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_width</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"wrap_content"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_height</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"wrap_content"</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">ImageView</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:id</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@+id/image"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_width</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"wrap_content"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_height</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"wrap_content"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_weight</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"1"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:onClick</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"onImageClick"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">app:srcCompat</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@mipmap/ic_launcher"</span> /></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">ProgressBar</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:id</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@+id/progressBar"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">style</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"?android:attr/progressBarStyle"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_width</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"wrap_content"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_height</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"wrap_content"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:visibility</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"gone"</span> /></span>
<span class="hljs-tag" style="box-sizing: inherit;"></<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">RelativeLayout</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"></<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">LinearLayout</span>></span>
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Разметка у нас будет выглядеть так же как и в </span><a href="http://dajver.blogspot.com/2017/12/pdf.html" style="background-color: white; box-sizing: inherit; color: #992298; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px; text-decoration-line: none;">предыдущей статье</a><span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">, у нас будет картинка и прогресс бар который будет отображать прогресс конвертации. Ну и картинка по нажатию на которую у нас будет открываться выбор файла, и после выбора в ней будем отображать собственно то, что у нас получилось.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">MainActivity будет выглядеть точь в точь так же как и в </span><a href="http://dajver.blogspot.com/2017/12/pdf.html" style="background-color: white; box-sizing: inherit; color: #992298; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px; text-decoration-line: none;">предыдущей статье,</a><span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;"> отличаться будет только метод onActivityResult() в котором вместо PDFToImageTask будет вызываться PPTToImageTask.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">MainActivity.java</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="java hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.Manifest;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.content.Intent;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.graphics.Bitmap;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.graphics.BitmapFactory;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.os.Bundle;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.support.v7.app.AppCompatActivity;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.view.View;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.widget.ImageView;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.widget.ProgressBar;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> com.karumi.dexter.Dexter;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> com.karumi.dexter.MultiplePermissionsReport;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> com.karumi.dexter.PermissionToken;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> com.karumi.dexter.listener.PermissionRequest;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> com.karumi.dexter.listener.multi.MultiplePermissionsListener;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> java.io.File;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> java.util.List;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> butterknife.BindView;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> butterknife.ButterKnife;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> butterknife.OnClick;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> project.dajver.com.ppttoimage.task.PPTToImageTask;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> project.dajver.com.ppttoimage.task.utils.ImageFilePathUtils;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-class" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">class</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">MainActivity</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">extends</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">AppCompatActivity</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">implements</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">PPTToImageTask</span>.<span class="hljs-title" style="box-sizing: inherit; color: #c18401;">OnFileWasConvertedListener</span>,
<span class="hljs-title" style="box-sizing: inherit; color: #c18401;">MultiplePermissionsListener</span> </span>{
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@BindView</span>(R.id.image)
ImageView imageView;
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@BindView</span>(R.id.progressBar)
ProgressBar progressBar;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> PICKFILE_REQUEST_CODE = <span class="hljs-number" style="box-sizing: inherit; color: #986801;">1213</span>;
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">protected</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onCreate</span><span class="hljs-params" style="box-sizing: inherit;">(Bundle savedInstanceState)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">super</span>.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>);
Dexter.withActivity(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>)
.withPermissions(Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE)
.withListener(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>)
.check();
}
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@OnClick</span>(R.id.image)
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onImageClick</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
Intent intent = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> Intent(Intent.ACTION_GET_CONTENT);
intent.setType(<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"file/*"</span>);
startActivityForResult(intent, PICKFILE_REQUEST_CODE);
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">protected</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onActivityResult</span><span class="hljs-params" style="box-sizing: inherit;">(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> requestCode, <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> resultCode, Intent data)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">if</span>(resultCode == RESULT_OK) {
progressBar.setVisibility(View.VISIBLE);
String fPath = ImageFilePathUtils.getPath(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>, data.getData());
PPTToImageTask pdfToImageTask = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> PPTToImageTask(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>);
pdfToImageTask.setOnFileWasConvertedListener(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>);
pdfToImageTask.execute(fPath);
}
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">super</span>.onActivityResult(requestCode, resultCode, data);
}
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onFileWasConverted</span><span class="hljs-params" style="box-sizing: inherit;">(String path)</span> </span>{
progressBar.setVisibility(View.GONE);
Bitmap myBitmap = BitmapFactory.decodeFile(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> File(path).getAbsolutePath());
imageView.setImageBitmap(myBitmap);
}
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onPermissionsChecked</span><span class="hljs-params" style="box-sizing: inherit;">(MultiplePermissionsReport report)</span> </span>{ }
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onPermissionRationaleShouldBeShown</span><span class="hljs-params" style="box-sizing: inherit;">(List<PermissionRequest> permissions, PermissionToken token)</span> </span>{ }
}
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Здесь у нас в onCreate() мы инициализируем ButterKnife для удобной работы с вьюхами и инициализируем Dexter для удобства создания запроса на доступ к чтению и записи файлов. Дальше у нас вызывается по клику на картинку метод onImageClick(), который открывает доступный файловый менеджер. После выбора файла у нас вызывается onActivityResult() в котором у нас идет вызов PPTToImageTask для конвертации файла в картинку и отображение прогресс бара пока картинка будет конвертироваться. И в конце вызывается onFileWasConverted() который отображает нашу картинку в ImageView и прячет прогресс бар.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Как и в предыдущей статье нам нужны разрешения на доступ в манифесте, по этому не забываем добавить их.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">AndroidManifest.xml</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="xml hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;">...
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">uses-permission</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:name</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"android.permission.WRITE_EXTERNAL_STORAGE"</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">tools:node</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"replace"</span> /></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">uses-permission</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:name</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"android.permission.READ_EXTERNAL_STORAGE"</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">tools:node</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"replace"</span> /></span>
...
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Я честно не знаю почему я разбил это все на две статьи, но раз уж на то пошло пусть так и будет, возможно это даже к лучшему. Дальше по идее компилируем проект и все должно быть нормально, нажимаем на иконку приложения по центру экрана, выбираем файл в появившемся окне выбора и ждем когда появится картинка. Радуемся.</span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;"><br /></span>
<span style="color: #222222; font-size: large;"><span style="background-color: white;"><b>Исходники:</b></span></span><br />
<span style="color: #222222; font-size: large;"><span style="background-color: white;"><b><a href="https://github.com/dajver/PPTToImageExample">GitHub</a></b></span></span></div>
dajverhttp://www.blogger.com/profile/09427222798699404442noreply@blogger.com0tag:blogger.com,1999:blog-5677605911484164185.post-82573352775495659932017-12-06T23:44:00.003+02:002017-12-07T01:09:21.786+02:00Конвертируем PDF в картинку<div dir="ltr" style="text-align: left;" trbidi="on">
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiPSyd7zyUkQE1GuRIbESLhyphenhyphenAsoD8Du2pAkY1bI0EZHdlKlaCzuB873XTPIDTwnsCs2WWaLTF5Jxvptz12etEVJneZLRwTS0cIMO4woyvvE2mUlX_G2rfqHr67b_h0WiPEN4iRPSzSMZE0/s1600/pdf-to-jpg-300.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="180" data-original-width="300" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiPSyd7zyUkQE1GuRIbESLhyphenhyphenAsoD8Du2pAkY1bI0EZHdlKlaCzuB873XTPIDTwnsCs2WWaLTF5Jxvptz12etEVJneZLRwTS0cIMO4woyvvE2mUlX_G2rfqHr67b_h0WiPEN4iRPSzSMZE0/s1600/pdf-to-jpg-300.jpg" /></a></div>
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Случается такая фигня что бывает нужно создать читалку pdf файлов, на гитхабе есть в принципе читалки которые позволяют отображать pdf файлы в собственных вьюхах, но они очень медленные и как-то очень громоздкие, обычно все те функции что они имеют по сути и не нужны. Вот в моем случае и понадобилось просто отобразить страницы pdf файла, я решил это сделать в картинках что бы это можно было отображать в виде страниц в view pager. </span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">В этом примере я буду отображать только одну картинку, первую страницу файла, для простоты понимания того как это работает, что бы не нагружать проект лишними элементами.</span><br />
<a name='more'></a><br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Как всегда начинаем мы работу с пустого проекта, в который нам нужно добавить библиотеки. Библиотеки мы будем использовать </span><a href="https://github.com/JoanZapata/android-pdfview" style="background-color: white; box-sizing: inherit; color: #992298; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px; text-decoration-line: none;">PdfView</a><span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">, немного кастомизированную для корректной работы конвертера, так же будем использовать </span><a href="https://github.com/Karumi/Dexter" style="background-color: white; box-sizing: inherit; color: #992298; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px; text-decoration-line: none;">Dexter</a><span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;"> для попрошайничества пермишенов на запись и чтение из файловой системы, ну и </span><a href="https://github.com/JakeWharton/butterknife" style="background-color: white; box-sizing: inherit; color: #992298; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px; text-decoration-line: none;">ButterKnife</a><span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;"> для удобного биндинга вьюх.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Я для того что бы пофиксить PdfView скачивал его отдельно и подключал как проект, так что у меня он есть уже подключенный, если хотите можете попробовать его подключить через имплементацию чисто либу, не проект, может у вас заработает без фиксов в либе. Что конкретно я фиксил не помню так как это было давно так что проще скачать проект с моего гитхаба :). </span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">app/build.gradle</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="java hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;">dependencies {
<span class="hljs-function" style="box-sizing: inherit;">implementation <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">fileTree</span><span class="hljs-params" style="box-sizing: inherit;">(dir: <span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">'libs'</span>, include: [<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">'*.jar'</span>])</span>
implementation 'com.android.support:appcompat-v7:26.1.0'
implementation 'com.karumi:dexter:4.2.0'
implementation <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">project</span><span class="hljs-params" style="box-sizing: inherit;">(<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">':pdfview'</span>)</span>
implementation 'com.jakewharton:butterknife:8.8.1'
annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'
}
</span></code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Дальше после того как мы подключили все библиотеки и все прошло нормально, нам нужно создать класс который будет отвечать за работу конвертации пути файлов из непонятного для нас в понятный, что бы проще было находить сохраненные файлы после того как мы будем их получать в onActivityResult().</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">ImageFilePathUtils.java</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="java hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.content.ContentUris;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.content.Context;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.database.Cursor;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.net.Uri;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.os.Build;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.os.Environment;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.os.storage.StorageManager;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.provider.DocumentsContract;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.provider.MediaStore;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> java.lang.reflect.Array;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> java.lang.reflect.Method;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-class" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">class</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">ImageFilePathUtils</span> </span>{
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">static</span> String <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">getPath</span><span class="hljs-params" style="box-sizing: inherit;">(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">final</span> Context context, <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">final</span> Uri uri)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">final</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">boolean</span> isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">if</span> (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">if</span>(uri != <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">null</span>) {
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">if</span> (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">if</span> (isExternalStorageDocument(uri)) {
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">final</span> String docId = DocumentsContract.getDocumentId(uri);
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">final</span> String[] split = docId.split(<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">":"</span>);
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">final</span> String type = split[<span class="hljs-number" style="box-sizing: inherit; color: #986801;">0</span>];
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">if</span> (<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"primary"</span>.equalsIgnoreCase(type)) {
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> Environment.getExternalStorageDirectory() + <span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"/"</span> + split[<span class="hljs-number" style="box-sizing: inherit; color: #986801;">1</span>];
}<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">else</span> {
<span class="hljs-comment" style="box-sizing: inherit; color: #a0a1a7; font-style: italic;">//Below logic is how External Storage provider build URI for documents</span>
StorageManager mStorageManager = (StorageManager) context.getSystemService(Context.STORAGE_SERVICE);
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">try</span> {
Class<?> storageVolumeClazz = Class.forName(<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"android.os.storage.StorageVolume"</span>);
Method getVolumeList = mStorageManager.getClass().getMethod(<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"getVolumeList"</span>);
Method getUuid = storageVolumeClazz.getMethod(<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"getUuid"</span>);
Method getState = storageVolumeClazz.getMethod(<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"getState"</span>);
Method getPath = storageVolumeClazz.getMethod(<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"getPath"</span>);
Method isPrimary = storageVolumeClazz.getMethod(<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"isPrimary"</span>);
Method isEmulated = storageVolumeClazz.getMethod(<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"isEmulated"</span>);
Object result = getVolumeList.invoke(mStorageManager);
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">final</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> length = Array.getLength(result);
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">for</span> (<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> i = <span class="hljs-number" style="box-sizing: inherit; color: #986801;">0</span>; i < length; i++) {
Object storageVolumeElement = Array.get(result, i);
<span class="hljs-comment" style="box-sizing: inherit; color: #a0a1a7; font-style: italic;">//String uuid = (String) getUuid.invoke(storageVolumeElement);</span>
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">final</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">boolean</span> mounted = Environment.MEDIA_MOUNTED.equals( getState.invoke(storageVolumeElement) )
|| Environment.MEDIA_MOUNTED_READ_ONLY.equals(getState.invoke(storageVolumeElement));
<span class="hljs-comment" style="box-sizing: inherit; color: #a0a1a7; font-style: italic;">//if the media is not mounted, we need not get the volume details</span>
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">if</span> (!mounted) <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">continue</span>;
<span class="hljs-comment" style="box-sizing: inherit; color: #a0a1a7; font-style: italic;">//Primary storage is already handled.</span>
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">if</span> ((Boolean)isPrimary.invoke(storageVolumeElement) && (Boolean)isEmulated.invoke(storageVolumeElement)) <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">continue</span>;
String uuid = (String) getUuid.invoke(storageVolumeElement);
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">if</span> (uuid != <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">null</span> && uuid.equals(type))
{
String res =getPath.invoke(storageVolumeElement) + <span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"/"</span> +split[<span class="hljs-number" style="box-sizing: inherit; color: #986801;">1</span>];
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> res;
}
}
}
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">catch</span> (Exception ex) {
}
}
} <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">else</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">if</span> (isDownloadsDocument(uri)) {
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">final</span> String id = DocumentsContract.getDocumentId(uri);
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">final</span> Uri contentUri = ContentUris.withAppendedId(
Uri.parse(<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"content://downloads/public_downloads"</span>), Long.valueOf(id));
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> getDataColumn(context, contentUri, <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">null</span>, <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">null</span>);
} <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">else</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">if</span> (isMediaDocument(uri)) {
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">final</span> String docId = DocumentsContract.getDocumentId(uri);
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">final</span> String[] split = docId.split(<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">":"</span>);
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">final</span> String type = split[<span class="hljs-number" style="box-sizing: inherit; color: #986801;">0</span>];
Uri contentUri = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">null</span>;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">if</span> (<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"image"</span>.equals(type)) {
contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
} <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">else</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">if</span> (<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"video"</span>.equals(type)) {
contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
} <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">else</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">if</span> (<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"audio"</span>.equals(type)) {
contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
}
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">final</span> String selection = <span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"_id=?"</span>;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">final</span> String[] selectionArgs = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> String[]{
split[<span class="hljs-number" style="box-sizing: inherit; color: #986801;">1</span>]
};
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> getDataColumn(context, contentUri, selection, selectionArgs);
}
} <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">else</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">if</span> (<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"content"</span>.equalsIgnoreCase(uri.getScheme())) {
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">if</span> (isGooglePhotosUri(uri))
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> uri.getLastPathSegment();
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> getDataColumn(context, uri, <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">null</span>, <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">null</span>);
} <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">else</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">if</span> (<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"file"</span>.equalsIgnoreCase(uri.getScheme())) {
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> uri.getPath();
}
}
}
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">null</span>;
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">static</span> String <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">getDataColumn</span><span class="hljs-params" style="box-sizing: inherit;">(Context context, Uri uri, String selection, String[] selectionArgs)</span> </span>{
Cursor cursor = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">null</span>;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">final</span> String column = <span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"_data"</span>;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">final</span> String[] projection = {
column
};
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">try</span> {
cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs,
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">null</span>);
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">if</span> (cursor != <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">null</span> && cursor.moveToFirst()) {
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">final</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> index = cursor.getColumnIndexOrThrow(column);
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> cursor.getString(index);
}
} <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">finally</span> {
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">if</span> (cursor != <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">null</span>)
cursor.close();
}
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">null</span>;
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">static</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">boolean</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">isExternalStorageDocument</span><span class="hljs-params" style="box-sizing: inherit;">(Uri uri)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> <span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"com.android.externalstorage.documents"</span>.equals(uri.getAuthority());
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">static</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">boolean</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">isDownloadsDocument</span><span class="hljs-params" style="box-sizing: inherit;">(Uri uri)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> <span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"com.android.providers.downloads.documents"</span>.equals(uri.getAuthority());
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">static</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">boolean</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">isMediaDocument</span><span class="hljs-params" style="box-sizing: inherit;">(Uri uri)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> <span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"com.android.providers.media.documents"</span>.equals(uri.getAuthority());
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">static</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">boolean</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">isGooglePhotosUri</span><span class="hljs-params" style="box-sizing: inherit;">(Uri uri)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> <span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"com.google.android.apps.photos.content"</span>.equals(uri.getAuthority());
}
}
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Особо останавливаться на этом классе не буду, он стырен из stackoverflow очень давно и как-то я его до сих пор использую так как он решает кучу проблем с рисованием ссылок на файлы после получения онных в onActivityResult(). В общем нас интересует только метод getPath(), он нам возвращает реальную ссылку на файл.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Дальше мы создадим AsyncTask который будет в фоне генерировать нам нашу картинку из pdf файла. Я не захотел нагружать проект Rx'ом как я это делал в прошлых статьях так-как хотелось попроще сделать все, но если прям сильно хочется то я думаю те кто его используют, смогут перевести этот AsyncTask в вид RxAndroid'а. Если что </span><a href="http://dajver.blogspot.com/2017/11/rx-android.html" style="background-color: white; box-sizing: inherit; color: #992298; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px; text-decoration-line: none;">вот тут</a><span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;"> статья про RxAndroid который делает код очень эстетически красивым.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">PDFToImageTask.java</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="java hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.content.Context;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.graphics.Bitmap;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.graphics.RectF;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.net.Uri;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.os.AsyncTask;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> org.vudroid.core.DecodeServiceBase;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> org.vudroid.core.codec.CodecPage;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> org.vudroid.pdfdroid.codec.PdfContext;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> java.io.File;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> java.io.FileOutputStream;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> java.io.IOException;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> java.io.OutputStream;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-class" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">class</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">PDFToImageTask</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">extends</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">AsyncTask</span><<span class="hljs-title" style="box-sizing: inherit; color: #c18401;">File</span>, <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">Void</span>, <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">String</span>> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> Context context;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> OnPDFToImageConvertedListener onPDFToImageConvertedListener;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> String fileName;
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">PDFToImageTask</span><span class="hljs-params" style="box-sizing: inherit;">(Context context)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>.context = context;
}
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">protected</span> String <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">doInBackground</span><span class="hljs-params" style="box-sizing: inherit;">(File... files)</span> </span>{
File originFile = files[<span class="hljs-number" style="box-sizing: inherit; color: #986801;">0</span>];
fileName = originFile.getName().toLowerCase().replace(<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">".pdf"</span>, <span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">".jpeg"</span>);
File filePath = getCacheDir(context);
File file = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> File (filePath, fileName);
String path = file.getPath();
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">if</span>(!<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> File(path).exists()) {
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">try</span> {
DecodeServiceBase decodeService = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> DecodeServiceBase(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> PdfContext());
decodeService.setContentResolver(context.getContentResolver());
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">if</span> (originFile.exists()) {
decodeService.open(Uri.fromFile(originFile));
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> pageCount = decodeService.getPageCount();
CodecPage page = decodeService.getPage(<span class="hljs-number" style="box-sizing: inherit; color: #986801;">0</span>);
RectF rectF = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> RectF(<span class="hljs-number" style="box-sizing: inherit; color: #986801;">0</span>, <span class="hljs-number" style="box-sizing: inherit; color: #986801;">0</span>, <span class="hljs-number" style="box-sizing: inherit; color: #986801;">1</span>, <span class="hljs-number" style="box-sizing: inherit; color: #986801;">1</span>);
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">double</span> scaleBy = Math.min(<span class="hljs-number" style="box-sizing: inherit; color: #986801;">2480</span> / (<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">double</span>) page.getWidth(), <span class="hljs-number" style="box-sizing: inherit; color: #986801;">3508</span> / (<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">double</span>) page.getHeight());
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> with = (<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span>) (page.getWidth() * scaleBy);
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> height = (<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span>) (page.getHeight() * scaleBy);
Bitmap bitmap = page.renderBitmap(with, height, rectF);
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">try</span> {
OutputStream outputStream = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> FileOutputStream(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> File(getCacheDir(context), System.currentTimeMillis() + <span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">".JPEG"</span>));
bitmap.compress(Bitmap.CompressFormat.JPEG, <span class="hljs-number" style="box-sizing: inherit; color: #986801;">100</span>, outputStream);
outputStream.close();
path = saveImageAndGetURI(bitmap).toString();
} <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">catch</span> (IOException e) {
e.printStackTrace();
}
}
} <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">catch</span> (Exception ex) {
ex.printStackTrace();
}
}
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> path;
}
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">protected</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onPostExecute</span><span class="hljs-params" style="box-sizing: inherit;">(String uris)</span> </span>{
onPDFToImageConvertedListener.onPDFToImageConverted(uris);
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> Uri <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">saveImageAndGetURI</span><span class="hljs-params" style="box-sizing: inherit;">(Bitmap finalBitmap)</span> </span>{
File file = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> File (getCacheDir(context), fileName);
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">if</span> (file.exists ()) file.delete ();
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">try</span> {
FileOutputStream out = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> FileOutputStream(file);
finalBitmap.compress(Bitmap.CompressFormat.JPEG, <span class="hljs-number" style="box-sizing: inherit; color: #986801;">100</span>, out);
out.flush();
out.close();
} <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">catch</span> (Exception e) {
e.printStackTrace();
}
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> Uri.parse(file.getPath());
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> File <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">getCacheDir</span><span class="hljs-params" style="box-sizing: inherit;">(Context context)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> context.getCacheDir();
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">setOnPDFToImageConvertedListener</span><span class="hljs-params" style="box-sizing: inherit;">(OnPDFToImageConvertedListener onPDFToImageConvertedListener)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>.onPDFToImageConvertedListener = onPDFToImageConvertedListener;
}
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-class" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">interface</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">OnPDFToImageConvertedListener</span> </span>{
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onPDFToImageConverted</span><span class="hljs-params" style="box-sizing: inherit;">(String imageUri)</span></span>;
}
}
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">В этом классе нас интересует метод doInBackground() который у нас принимает адрес файла который мы хотим конвертнуть и дальше делает какую-то магию непонятную которую нам нужно разобрать. После того как мы поменяем разрешение файла в его имени и создании пустого файла в папке кеша программы мы переходим в к самому интересному, к конвертации. У нас в try идет вызов DecodeServiceBase класса который является классом библиотеки PdfView, вот он то и производит разбитие файла на фреймы и дальше мы берем первую страницу файла с помощью метода getPage(0), и делаем ее битмап и дальше сохраняем в файл с форматом jpeg. Дальше возвращаем путь к сохраненной картинке в onPostExecute() в активити для отображения.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Вот собственно и вся магия. Все очень просто, когда ты делал такое и шаришь как это делать. :) Дальше нам нужно в активити вызвать этот класс для конвертации и отобразить картинку в ImageView.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Для начала нарисуем леяут с картинкой и прогрессбаром для визуализации работы конвертера.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">activity_main.xml</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="xml hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;"><?xml version="1.0" encoding="utf-8"?></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">LinearLayout</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">xmlns:android</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"http://schemas.android.com/apk/res/android"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">xmlns:app</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"http://schemas.android.com/apk/res-auto"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_width</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_height</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:gravity</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"center_vertical|center_horizontal"</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">RelativeLayout</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_width</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"wrap_content"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_height</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"wrap_content"</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">ImageView</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:id</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@+id/image"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_width</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"wrap_content"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_height</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"wrap_content"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_weight</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"1"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:onClick</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"onImageClick"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">app:srcCompat</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@mipmap/ic_launcher"</span> /></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">ProgressBar</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:id</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@+id/progressBar"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">style</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"?android:attr/progressBarStyle"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_width</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"wrap_content"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_height</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"wrap_content"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_weight</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"1"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:visibility</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"gone"</span> /></span>
<span class="hljs-tag" style="box-sizing: inherit;"></<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">RelativeLayout</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"></<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">LinearLayout</span>></span>
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Я это все поместил в RelativeLayout для красоты что бы оно лежало друг на друге, пока мы конвертируем, progressBar будет крутиться пока у нас происходит конвертация и исчезнет как только картинка будет готова к отображению.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Дальше напишем нашу activity что бы она делал все что я описывал выше. Получала pdf файл и конвертировала его в картинку и отображала в ImageView. А еще мы подписали ImageView на onClick событие что бы по нажатию на нее у нас открывался какой-то файловый менеджер для получения списка файлов.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">MainActivity.java</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="java hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.Manifest;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.content.Intent;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.graphics.Bitmap;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.graphics.BitmapFactory;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.os.Bundle;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.support.v7.app.AppCompatActivity;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.view.View;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.widget.ImageView;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.widget.ProgressBar;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> com.karumi.dexter.Dexter;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> com.karumi.dexter.MultiplePermissionsReport;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> com.karumi.dexter.PermissionToken;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> com.karumi.dexter.listener.PermissionRequest;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> com.karumi.dexter.listener.multi.MultiplePermissionsListener;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> java.io.File;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> java.util.List;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> butterknife.BindView;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> butterknife.ButterKnife;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> butterknife.OnClick;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> project.dajver.com.pdftoimage.task.PDFToImageTask;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> project.dajver.com.pdftoimage.task.utils.ImageFilePathUtils;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-class" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">class</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">MainActivity</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">extends</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">AppCompatActivity</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">implements</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">PDFToImageTask</span>.<span class="hljs-title" style="box-sizing: inherit; color: #c18401;">OnPDFToImageConvertedListener</span>,
<span class="hljs-title" style="box-sizing: inherit; color: #c18401;">MultiplePermissionsListener</span> </span>{
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@BindView</span>(R.id.image)
ImageView imageView;
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@BindView</span>(R.id.progressBar)
ProgressBar progressBar;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> PICKFILE_REQUEST_CODE = <span class="hljs-number" style="box-sizing: inherit; color: #986801;">1213</span>;
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">protected</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onCreate</span><span class="hljs-params" style="box-sizing: inherit;">(Bundle savedInstanceState)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">super</span>.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>);
Dexter.withActivity(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>)
.withPermissions(Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE)
.withListener(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>)
.check();
}
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@OnClick</span>(R.id.image)
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onImageClick</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
Intent intent = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> Intent(Intent.ACTION_GET_CONTENT);
intent.setType(<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"file/*"</span>);
startActivityForResult(intent, PICKFILE_REQUEST_CODE);
}
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">protected</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onActivityResult</span><span class="hljs-params" style="box-sizing: inherit;">(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> requestCode, <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> resultCode, Intent data)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">if</span>(resultCode == RESULT_OK) {
progressBar.setVisibility(View.VISIBLE);
String fPath = ImageFilePathUtils.getPath(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>, data.getData());
PDFToImageTask pdfToImageTask = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> PDFToImageTask(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>);
pdfToImageTask.setOnPDFToImageConvertedListener(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>);
pdfToImageTask.execute(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> File(fPath));
}
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">super</span>.onActivityResult(requestCode, resultCode, data);
}
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onPDFToImageConverted</span><span class="hljs-params" style="box-sizing: inherit;">(String imageUri)</span> </span>{
progressBar.setVisibility(View.GONE);
Bitmap myBitmap = BitmapFactory.decodeFile(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> File(imageUri).getAbsolutePath());
imageView.setImageBitmap(myBitmap);
}
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onPermissionsChecked</span><span class="hljs-params" style="box-sizing: inherit;">(MultiplePermissionsReport report)</span> </span>{ }
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onPermissionRationaleShouldBeShown</span><span class="hljs-params" style="box-sizing: inherit;">(List<PermissionRequest> permissions, PermissionToken token)</span> </span>{ }
}
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Для начала нас интересует метод onCreate(), в котором мы подключили ButterKnife для удобного поиска вьюх в xml и Dexter для удобного запроса на пермишены для чтения и записи файлов. Далее в onImageClick() мы сделали Intent для открытия файлового менеджера, и в onActivityResult() получаем файл который был выбран, показываем ProgressBar и запускаем наш AsyncTask для конвертации. В конце всего этого действия мы отображаем нашу картинку в ImageView в методе onPDFToImageConverted() и прячем ProgressBar.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Ну и не забываем добавить пермишены в AndroidManifest для того что бы приложение знало какие пермишены нам нужны.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">AndroidManifest.xml</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="xml hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;">...
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">uses-permission</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:name</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"android.permission.WRITE_EXTERNAL_STORAGE"</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">tools:node</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"replace"</span> /></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">uses-permission</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:name</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"android.permission.READ_EXTERNAL_STORAGE"</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">tools:node</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"replace"</span> /></span>
...
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Ну и вроде бы все, вроде ничего не забыл. Компилируем проект, выбираем картинку и пробуем конвертировать, должно все работать.</span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;"><br /></span>
<span style="color: #222222; font-size: large;"><span style="background-color: white;"><b>Исходники:</b></span></span><br />
<span style="color: #222222; font-size: large;"><span style="background-color: white;"><b><a href="https://github.com/dajver/PDFToImageExample">GitHub</a></b></span></span></div>
dajverhttp://www.blogger.com/profile/09427222798699404442noreply@blogger.com0tag:blogger.com,1999:blog-5677605911484164185.post-7160334592813417772017-11-30T15:30:00.002+02:002017-11-30T15:30:45.231+02:00Создание кастомного пина на Google map<div dir="ltr" style="text-align: left;" trbidi="on">
<span style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;">Случается такое что попадается проект в котором приходится изворачиваться с кастомизацией элементов на экране. Сейчас возможности доросли до такого уровня что почти каждый стандартный элемент в андроиде можно переписать под себя, раньше это тоже было возможно, но как-то никто не парился, а теперь настали новые времена, и заказчики под напором дизайнеров хотят все красивей и красивей разного рода вьюхи, бывает что некоторые просто нереално сделать с первого раза. </span><br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" /><br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" /><span style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;">Но это статья не про такой вид вьюх. Сегодня все будет проще, так как нам нужно всего лишь сделать кастомный пин на карте, в котором будет находится фотка человека. Для этого мы создадим кастомную вьюху и в ней проделаем элементарные махинации по рисованию магии на экране.</span><br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" /><br />
<div style="text-align: center;">
<img alt="image" height="400" src="https://raw.githubusercontent.com/dajver/RoundCustomMapPinExample/master/imgs/image.png" style="background-color: white; border-style: none; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px; margin: 0px; max-width: 100%; vertical-align: middle;" width="224" /></div>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" /><span style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;">У нас тут и Джордж Клуни, и Роберт Де Ниро и Дональд Трамп, прям отличная пьянка!</span><br />
<br />
<a name='more'></a><br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" /><span style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;">Начнем мы все с того же с чего я всегда начинаю статьи, — с настройки проекта, а это добавление библиотек в build.gradle. Использовать библиотеки всегда желательнее чем использовать самописные костыли, по этому старайтесь максимально чаще находить готовые библиотеки по каким-то задачам, будь то работа с сервером (</span><a href="http://dajver.blogspot.com/2017/05/retrofit.html" style="background-color: white; box-sizing: inherit; color: #992298; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px; text-decoration-line: none;">Retofit</a><span style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;">), работа с базой данных (</span><a href="http://dajver.blogspot.com/2017/06/realm.html" style="background-color: white; box-sizing: inherit; color: #992298; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px; text-decoration-line: none;">Realm</a><span style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;"> или </span><a href="http://dajver.blogspot.com/2017/11/room.html" style="background-color: white; box-sizing: inherit; color: #992298; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px; text-decoration-line: none;">Room</a><span style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;">) или какая-то библиотека помогающая на пример с пермишенами в новых версиях андроида (</span><a href="https://github.com/Karumi/Dexter" style="background-color: white; box-sizing: inherit; color: #992298; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px; text-decoration-line: none;">Dexter</a><span style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;">).</span><br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" /><br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" /><span style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px; font-weight: bolder;">app/build.gradle</span><br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" /><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="java hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;">android {
...
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
dependencies {
<span class="hljs-function" style="box-sizing: inherit;">implementation <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">fileTree</span><span class="hljs-params" style="box-sizing: inherit;">(dir: <span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">'libs'</span>, include: [<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">'*.jar'</span>])</span>
implementation 'com.android.support:appcompat-v7:26.1.0'
implementation 'de.hdodenhof:circleimageview:2.1.0'
implementation 'com.jakewharton:butterknife:8.8.1'
annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'
implementation 'io.reactivex.rxjava2:rxandroid:2.0.1'
implementation 'io.reactivex.rxjava2:rxjava:2.1.5'
implementation 'com.google.android.gms:play-services-maps:11.6.+'
}</span></code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" /><span style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;">И так, что же мы имеем у себя в app/build.gradle. У нас будет использоваться пара библиотек, а это — CircleImageView, ButterKnife, Google Map Services и RxAndroid. Последнюю я буду использовать чисто для красоты кода, не знаю как кому, а мне очень нравится как оно выглядит в проекте и всех настаиваю так же писать код. Так же у нас будет включена Java 8 для работы с лямбдой.</span><br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" /><br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" /><span style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;">Теперь у нас готов плацдарм для работы с проектом. У нас создалась активити и леяут к ней, в ней мы будем создавать карту, подключается карта очень легко, в отличии от предыдущих версий когда требовалось кучу кода писать, теперь у нас достаточно создать на леяуте фрагмент с картой, и дальше подключить ее в активити, и все, у нас есть карта!</span><br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" /><br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" /><span style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;">Как же будет выглядеть MainActivity с картой. Для начала нам нужно добавить фрагмент с картой в леяут, сделаем это.</span><br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" /><br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" /><span style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px; font-weight: bolder;">activity_main.xml</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="xml hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;"><?xml version="1.0" encoding="utf-8"?></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">LinearLayout</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">xmlns:android</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"http://schemas.android.com/apk/res/android"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">xmlns:app</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"http://schemas.android.com/apk/res-auto"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">xmlns:tools</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"http://schemas.android.com/tools"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_width</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_height</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">tools:context</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"project.dajver.com.roundpinwithavatarexample.MainActivity"</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">fragment</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">xmlns:android</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"http://schemas.android.com/apk/res/android"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">xmlns:tools</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"http://schemas.android.com/tools"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_width</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_height</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:id</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@+id/map"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">tools:context</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">".MapsActivity"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:name</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"com.google.android.gms.maps.SupportMapFragment"</span> /></span>
<span class="hljs-tag" style="box-sizing: inherit;"></<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">LinearLayout</span>></span>
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" /><span style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;">Супер, у нас есть карта на экране активити, теперь нам нужно подключить и заставить ее работать в самом классе. Для этого нам нужно создать объект SupportMapFragment и подключить к нему наш фрагмент map.</span><br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" /><br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" /><span style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px; font-weight: bolder;">MainActivity.java</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="java hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.os.Bundle;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.support.v7.app.AppCompatActivity;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> com.google.android.gms.maps.GoogleMap;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> com.google.android.gms.maps.OnMapReadyCallback;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> com.google.android.gms.maps.SupportMapFragment;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> com.google.android.gms.maps.model.BitmapDescriptorFactory;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> com.google.android.gms.maps.model.MarkerOptions;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> java.util.ArrayList;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> io.reactivex.android.schedulers.AndroidSchedulers;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> io.reactivex.schedulers.Schedulers;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> project.dajver.com.roundpinwithavatarexample.view.model.PinsModel;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> project.dajver.com.roundpinwithavatarexample.view.repo.RepositoryImpl;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-class" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">class</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">MainActivity</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">extends</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">AppCompatActivity</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">implements</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">OnMapReadyCallback</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> GoogleMap mMap;
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">protected</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onCreate</span><span class="hljs-params" style="box-sizing: inherit;">(Bundle savedInstanceState)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">super</span>.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
mapFragment.getMapAsync(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>);
}
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onMapReady</span><span class="hljs-params" style="box-sizing: inherit;">(GoogleMap googleMap)</span> </span>{
}
}
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" /><span style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;">Как видно из кода у нас есть объект GoogleMap который мы в дальнейшем будем использовать как метку для добавления пинов на карту, перемещение камеры по карте и так далее. И есть объект SupportMapFragment который собственно и есть карта, и к нему у нас подключен колбек getMapAsync который по готовности карты вернет нам что карта готова к работе, и дальше мы будем готовы устанавливать разные пины на карту и т.д. Так же для того что бы карта работала нам нужно добавить API Key для работы, его можно зарегистрировать </span><a href="https://console.developers.google.com/apis" style="background-color: white; box-sizing: inherit; color: #992298; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px; text-decoration-line: none;">тут</a><span style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;">. И после того как сгенерируете код для карты, нужно будет его указать в string.xml.</span><br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" /><br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" /><span style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px; font-weight: bolder;">string.xml</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="xml hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"> <span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">string</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">name</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"google_api_key_map"</span>></span>AIzaSyBcCGUs7wKBzZJApPY-jAiDjkssHgz9UD94<span class="hljs-tag" style="box-sizing: inherit;"></<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">string</span>></span>
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" /><span style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;">Собственно дальше нам нужно создать класс который будет описывать создание пина из картинки и определенного шаблона. У нас будет три вида пинов, красный, желтый и зеленый, я это сделал чисто для примера, а так их можно сделать хоть 150 видов, но у нас их будет три. Для начала нам нужно создать вьюху которая будет шаблоном для пина. У нас так же будут использоваться три картинки для них и одна заглушка если нету картинки пользователя.</span><br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" /><br />
<div style="text-align: center;">
<img alt="image" src="https://github.com/dajver/RoundCustomMapPinExample/blob/master/app/src/main/res/mipmap-xhdpi/green_map_pin.png?raw=true" style="background-color: white; border-style: none; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px; margin: 0px; max-width: 100%; vertical-align: middle;" /><span style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;"> </span><img alt="image" src="https://github.com/dajver/RoundCustomMapPinExample/blob/master/app/src/main/res/mipmap-xhdpi/red_map_pin.png?raw=true" style="background-color: white; border-style: none; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px; margin: 0px; max-width: 100%; vertical-align: middle;" /><span style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;"> </span><img alt="image" src="https://github.com/dajver/RoundCustomMapPinExample/blob/master/app/src/main/res/mipmap-xhdpi/yelow_map_pin.png?raw=true" style="background-color: white; border-style: none; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px; margin: 0px; max-width: 100%; vertical-align: middle;" /><span style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;"> </span><img alt="image" src="https://github.com/dajver/RoundCustomMapPinExample/blob/master/app/src/main/res/mipmap-xhdpi/user_profile_image.png?raw=true" style="background-color: white; border-style: none; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px; margin: 0px; max-width: 100%; vertical-align: middle;" /></div>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" /><span style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px; font-weight: bolder;">view_custom_map_pin.xml</span><br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" /><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="xml hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;"><?xml version="1.0" encoding="utf-8"?></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">RelativeLayout</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">xmlns:android</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"http://schemas.android.com/apk/res/android"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:id</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@+id/custom_marker_view"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_width</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"72dp"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_height</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"93dp"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:background</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@mipmap/red_map_pin"</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">de.hdodenhof.circleimageview.CircleImageView</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:id</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@+id/profile_image"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_width</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"60dp"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_height</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"60dp"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_centerHorizontal</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"true"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_gravity</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"center_horizontal"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_marginTop</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"6dp"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:contentDescription</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@null"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:scaleType</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"centerCrop"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:src</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@mipmap/user_profile_image"</span> /></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">TextView</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:id</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@+id/userName"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_width</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"wrap_content"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_height</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"wrap_content"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_alignEnd</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@+id/profile_image"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_alignRight</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@+id/profile_image"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_alignTop</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@+id/profile_image"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_marginLeft</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"5dp"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_marginRight</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"5dp"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_marginTop</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"20dp"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:singleLine</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"true"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:text</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"TextView"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:textColor</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@color/white"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:visibility</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"gone"</span> /></span>
<span class="hljs-tag" style="box-sizing: inherit;"></<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">RelativeLayout</span>></span>
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" /><span style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;">В ней у нас RelativeLayout у которого наложен фон в виде одной из картинок для пина, так же внутри у нас ImageView скругленный для аватара, и TextView под ним для того что бы если у нас нет аватара то отображалось хотя бы имя, по умолчанию он не видимый.</span><br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" /><br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" /><span style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;">Так же у нас используются цвета, белый, красный, зеленый и желтый, их я указал в colors.xml файле.</span><br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" /><br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" /><span style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px; font-weight: bolder;">colors.xml</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="xml hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"> <span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">color</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">name</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"yellow"</span>></span>#f5dc4f<span class="hljs-tag" style="box-sizing: inherit;"></<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">color</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">color</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">name</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"red"</span>></span>#e74a4a<span class="hljs-tag" style="box-sizing: inherit;"></<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">color</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">color</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">name</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"green"</span>></span>#1aa36d<span class="hljs-tag" style="box-sizing: inherit;"></<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">color</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">color</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">name</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"white"</span>></span>#fff<span class="hljs-tag" style="box-sizing: inherit;"></<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">color</span>></span>
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" /><span style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;">Ну а теперь напишем что бы это все работало так как нам нужно.</span><br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" /><br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" /><span style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px; font-weight: bolder;">CustomPinView.java</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="java hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.content.Context;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.graphics.Bitmap;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.graphics.Canvas;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.graphics.Color;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.graphics.Paint;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.graphics.Rect;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.support.annotation.AttrRes;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.support.annotation.NonNull;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.support.annotation.Nullable;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.util.AttributeSet;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.view.View;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.widget.FrameLayout;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.widget.RelativeLayout;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.widget.TextView;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> butterknife.BindView;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> butterknife.ButterKnife;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> de.hdodenhof.circleimageview.CircleImageView;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> project.dajver.com.roundpinwithavatarexample.R;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-class" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">class</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">CustomPinView</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">extends</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">FrameLayout</span> </span>{
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@BindView</span>(R.id.profile_image)
CircleImageView markerImageView;
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@BindView</span>(R.id.custom_marker_view)
RelativeLayout customMarkerView;
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@BindView</span>(R.id.userName)
TextView userName;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> Context context;
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">CustomPinView</span><span class="hljs-params" style="box-sizing: inherit;">(@NonNull Context context)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">super</span>(context);
init(context);
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">CustomPinView</span><span class="hljs-params" style="box-sizing: inherit;">(@NonNull Context context, @Nullable AttributeSet attrs)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">super</span>(context, attrs);
init(context);
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">CustomPinView</span><span class="hljs-params" style="box-sizing: inherit;">(@NonNull Context context, @Nullable AttributeSet attrs, @AttrRes <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> defStyleAttr)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">super</span>(context, attrs, defStyleAttr);
init(context);
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">init</span><span class="hljs-params" style="box-sizing: inherit;">(Context context)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>.context = context;
inflate(context, R.layout.view_custom_map_pin, <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>);
ButterKnife.bind(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>);
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">setBackground</span><span class="hljs-params" style="box-sizing: inherit;">(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> id)</span> </span>{
customMarkerView.setBackgroundResource(id);
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">setIcon</span><span class="hljs-params" style="box-sizing: inherit;">(Bitmap bmpImg, String name, String mapStatus)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">if</span>(bmpImg != <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">null</span>)
markerImageView.setImageBitmap(bmpImg);
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">else</span> {
Rect rect = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> Rect(<span class="hljs-number" style="box-sizing: inherit; color: #986801;">0</span>, <span class="hljs-number" style="box-sizing: inherit; color: #986801;">0</span>, <span class="hljs-number" style="box-sizing: inherit; color: #986801;">1</span>, <span class="hljs-number" style="box-sizing: inherit; color: #986801;">1</span>);
Bitmap image = Bitmap.createBitmap(rect.width(), rect.height(), Bitmap.Config.ARGB_8888);
Canvas canvas = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> Canvas(image);
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> color = Color.RED;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">if</span>(mapStatus.equals(<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"one"</span>))
color = getResources().getColor(R.color.yellow);
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">else</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">if</span>(mapStatus.equals(<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"two"</span>))
color = getResources().getColor(R.color.green);
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">else</span>
color = getResources().getColor(R.color.red);
Paint paint = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> Paint();
paint.setColor(color);
canvas.drawRect(rect, paint);
markerImageView.setImageBitmap(image);
userName.setVisibility(View.VISIBLE);
userName.setText(name);
}
}
}
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" /><span style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;">Что мы тут видим? В методе init() инициализируем нашу вьюху, ButterKnife и дальше у нас идут методы сеттеры для имени и аватара. Что в имени то понятно, просто задаем имя, а вот в аватаре мы создаем на основе битмапа который нам передаст метод скачивающий фотку с интернета и присваиваем его в ImageView или же если битмап пустой то делаем картинку на основе статуса который у нас передается в mapStatus, и ставим в зависимости от статуса тот или иной цвет на фон и указываем имя пользователя.</span><br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" /><br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" /><span style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;">Дальше нам нужно создать класс который будет скачивать фотку с интернета, для этого создадим класс который будет включать в себя все нужные методы для работы, в моем случае это будет один метод для скачивания фотографий.</span><br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" /><br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" /><span style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;">Как я писал ранее в статье про </span><a href="http://dajver.blogspot.com/2017/11/rx-android.html" style="background-color: white; box-sizing: inherit; color: #992298; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px; text-decoration-line: none;">RxAndroid</a><span style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;"> мы создадим интерфейс который будет в себе содержать метод возвращающий нам в результате местоположение пина на карте и сам пин картинкой.</span><br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" /><br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" /><span style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px; font-weight: bolder;">IRepository.java</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="java hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> io.reactivex.Observable;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> project.dajver.com.roundpinwithavatarexample.view.repo.model.PinsModel;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> project.dajver.com.roundpinwithavatarexample.view.repo.model.ResponseModel;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-class" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">interface</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">IRepository</span> </span>{
<span class="hljs-function" style="box-sizing: inherit;">Observable<ResponseModel> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">getImages</span><span class="hljs-params" style="box-sizing: inherit;">(String url, PinsModel model)</span></span>;
}
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" /><span style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;">Вот мы создали интерфейс, в котором создали метод возвращающий нам ResponseModel в котором у нас содержится Bitmap и LatLng. Вот его структура.</span><br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" /><br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" /><span style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px; font-weight: bolder;">ResponseModel.java</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="java hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.graphics.Bitmap;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> com.google.android.gms.maps.model.LatLng;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-class" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">class</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">ResponseModel</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> Bitmap image;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> LatLng latLng;
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">ResponseModel</span><span class="hljs-params" style="box-sizing: inherit;">(Bitmap image, LatLng latLng)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>.image = image;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>.latLng = latLng;
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> Bitmap <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">getImage</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> image;
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">setImage</span><span class="hljs-params" style="box-sizing: inherit;">(Bitmap image)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>.image = image;
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> LatLng <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">getLatLng</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> latLng;
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">setLatLng</span><span class="hljs-params" style="box-sizing: inherit;">(LatLng latLng)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>.latLng = latLng;
}
}
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" /><span style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;">В него мы передадим все параметры когда получим в итоге, и дальше из него же будем доставать эти данные для отображения на карте. А еще в метод getImages() мы передаем ссылку и PinsModel в котором у нас содержится вся информация по пину, айди, имя, картинка, и статус карты (цвет пина). </span><br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" /><br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" /><span style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px; font-weight: bolder;">PinsModel.java</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="java hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-class" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">class</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">PinsModel</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> Integer id;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> String fullName;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> String avatarUrl;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> String mapStatus;
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">PinsModel</span><span class="hljs-params" style="box-sizing: inherit;">(Integer id, String fullName, String avatarUrl, String mapStatus)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>.id = id;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>.fullName = fullName;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>.avatarUrl = avatarUrl;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>.mapStatus = mapStatus;
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> Integer <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">getId</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> id;
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">setId</span><span class="hljs-params" style="box-sizing: inherit;">(Integer id)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>.id = id;
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> String <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">getFullName</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> fullName;
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">setFullName</span><span class="hljs-params" style="box-sizing: inherit;">(String fullName)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>.fullName = fullName;
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> String <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">getAvatarUrl</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> avatarUrl;
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">setAvatarUrl</span><span class="hljs-params" style="box-sizing: inherit;">(String avatarUrl)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>.avatarUrl = avatarUrl;
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> String <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">getMapStatus</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> mapStatus;
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">setMapStatus</span><span class="hljs-params" style="box-sizing: inherit;">(String mapStatus)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>.mapStatus = mapStatus;
}
}
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" /><span style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;">Дальше нам нужно создать реализацию интерфейса IRepository, и написать там метод для скачивания картинок с интернета.</span><br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" /><br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" /><span style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px; font-weight: bolder;">RepositoryImpl.java</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="java hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.app.Activity;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.content.Context;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.graphics.Bitmap;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.graphics.BitmapFactory;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.graphics.Canvas;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.util.DisplayMetrics;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.view.View;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.view.ViewGroup;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> com.google.android.gms.maps.model.LatLng;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> java.io.InputStream;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> java.util.Random;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> io.reactivex.Observable;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> project.dajver.com.roundpinwithavatarexample.R;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> project.dajver.com.roundpinwithavatarexample.view.CustomPinView;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> project.dajver.com.roundpinwithavatarexample.view.repo.model.PinsModel;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> project.dajver.com.roundpinwithavatarexample.view.repo.model.ResponseModel;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-class" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">class</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">RepositoryImpl</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">implements</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">IRepository</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> Context context;
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">RepositoryImpl</span><span class="hljs-params" style="box-sizing: inherit;">(Context context)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>.context = context;
}
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> Observable<ResponseModel> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">getImages</span><span class="hljs-params" style="box-sizing: inherit;">(String url, PinsModel pinsModel)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> Observable.create(observableEmitter -> {
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">try</span> {
Bitmap bmpImg = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">null</span>;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">try</span> {
InputStream in = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> java.net.URL(url).openStream();
bmpImg = BitmapFactory.decodeStream(in);
} <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">catch</span> (Exception e) {
e.printStackTrace();
}
CustomPinView customPinView = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> CustomPinView(context);
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">if</span>(pinsModel.getMapStatus().equals(<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"one"</span>))
customPinView.setBackground(R.mipmap.yelow_map_pin);
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">else</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">if</span>(pinsModel.getMapStatus().equals(<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"two"</span>))
customPinView.setBackground(R.mipmap.green_map_pin);
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">else</span>
customPinView.setBackground(R.mipmap.red_map_pin);
customPinView.setIcon(bmpImg, pinsModel.getFullName(), pinsModel.getMapStatus());
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> rand = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> Random().nextInt(<span class="hljs-number" style="box-sizing: inherit; color: #986801;">151</span> - <span class="hljs-number" style="box-sizing: inherit; color: #986801;">14</span>) + <span class="hljs-number" style="box-sizing: inherit; color: #986801;">14</span>;
LatLng randLatLng = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> LatLng(-rand, rand);
ResponseModel responseModel = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> ResponseModel(createDrawableFromView(context, customPinView), randLatLng);
observableEmitter.onNext(responseModel);
} <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">catch</span> (Exception e) {
observableEmitter.onError(e);
} <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">finally</span> {
observableEmitter.onComplete();
}
});
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> Bitmap <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">createDrawableFromView</span><span class="hljs-params" style="box-sizing: inherit;">(Context context, View view)</span> </span>{
DisplayMetrics displayMetrics = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> DisplayMetrics();
((Activity) context).getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
view.setLayoutParams(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
view.measure(displayMetrics.widthPixels, displayMetrics.heightPixels);
view.layout(<span class="hljs-number" style="box-sizing: inherit; color: #986801;">0</span>, <span class="hljs-number" style="box-sizing: inherit; color: #986801;">0</span>, displayMetrics.widthPixels, displayMetrics.heightPixels);
view.buildDrawingCache();
Bitmap bitmap = Bitmap.createBitmap(view.getMeasuredWidth(), view.getMeasuredHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> Canvas(bitmap);
view.draw(canvas);
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> bitmap;
}
}
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" /><span style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;">После того как мы заимплементировали IRepository в этот класс, нам предложит студия добавить обязательные методы, и после того как вы добавите их оно создаст наш метод из интерфейса в который мы написали реализацию скачивания и в дальнейшем преобразование в зависимости от статуса пин в наш кастомный. Метод createDrawableFromView() позволяет нам преобразовать наш пин в доступную для ImageView версию для отображения, по этому мы из пина делаем Bitmap. Да кстати хочу заметить что локейшн я сделал рандомный, так что пины будут распологаться рандомно на карте…</span><br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" /><br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" /><span style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;">Ну а дальше осталось только вернуться в MainActivity и прописать создание пинов на карте. Для этого смотрим в метод onMapReady() который у нас на данный момент пустой, но буквально через секунду мы его заполним.</span><br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" /><br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" /><span style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px; font-weight: bolder;">MainActivity.java</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="java hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onMapReady</span><span class="hljs-params" style="box-sizing: inherit;">(GoogleMap googleMap)</span> </span>{
mMap = googleMap;
ArrayList<PinsModel> pinsModels = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> ArrayList<>();
pinsModels.add(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> PinsModel(<span class="hljs-number" style="box-sizing: inherit; color: #986801;">0</span>, <span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"George Clooney"</span>, <span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"https://petapixel.com/assets/uploads/2012/04/famous1_mini.jpg"</span>, <span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"one"</span>));
pinsModels.add(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> PinsModel(<span class="hljs-number" style="box-sizing: inherit; color: #986801;">1</span>, <span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"Donald Trump"</span>, <span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"http://www.samhurdphotography.com/wp-content/uploads/2014/06/dc-celebrity-portrait-photographers.jpg"</span>, <span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"two"</span>));
pinsModels.add(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> PinsModel(<span class="hljs-number" style="box-sizing: inherit; color: #986801;">2</span>, <span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"Robert De Niro"</span>, <span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"https://www.thefamouspeople.com/profiles/images/robert-de-niro-3.jpg"</span>, <span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"three"</span>));
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">for</span> (<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> i = <span class="hljs-number" style="box-sizing: inherit; color: #986801;">0</span>; i < pinsModels.size(); i++) {
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> RepositoryImpl(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>).getImages(pinsModels.get(i).getAvatarUrl(), pinsModels.get(i))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(responseModel -> {
mMap.addMarker(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> MarkerOptions()
.position(responseModel.getLatLng())
.icon(BitmapDescriptorFactory.fromBitmap(responseModel.getImage())));
});
}
}
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" /><span style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;">В самом начале метода мы присваиваем mMap его инстанс который вернул нам колбек, что бы дальше можно было работать с ним для добавления разных фишек на карту. Создаем список с нужными нам картинками и личностями, в моем случае их три, и потом в цикле я их отображаю скачивая их фотографии с помощью нашего класса RepositoryImpl. И в результате добавляю их на карту с кастомным локейшеном и кастомной картинкой.</span><br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" /><br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" /><span style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;">Ну и осталось в манифесте прописать пермишен для работы с интернетом и мета данные для работы карты.</span><br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" /><br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" /><span style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px; font-weight: bolder;">AndroidManifest.xml</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="xml hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;"><?xml version="1.0" encoding="utf-8"?></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">manifest</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">xmlns:android</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"http://schemas.android.com/apk/res/android"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">package</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"project.dajver.com.roundpinwithavatarexample"</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">uses-permission</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:name</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"android.permission.INTERNET"</span> /></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">application</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:allowBackup</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"true"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:icon</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@mipmap/ic_launcher"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:label</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@string/app_name"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:supportsRtl</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"true"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:theme</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@style/AppTheme"</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">activity</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:name</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">".MainActivity"</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">intent-filter</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">action</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:name</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"android.intent.action.MAIN"</span> /></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">category</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:name</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"android.intent.category.LAUNCHER"</span> /></span>
<span class="hljs-tag" style="box-sizing: inherit;"></<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">intent-filter</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"></<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">activity</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">meta-data</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:name</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"com.google.android.geo.API_KEY"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:value</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@string/google_api_key_map"</span>/></span>
<span class="hljs-tag" style="box-sizing: inherit;"></<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">application</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"></<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">manifest</span>></span>
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" /><span style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;">Как то так. Дальше можно компилировать. Если нет ошибок это замечательно, если есть то проверяем еще раз и смотрим не забыли ли мы что-то добавить.</span><br />
<span style="background-color: white; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;"><br /></span>
<span style="color: #222222; font-size: large;"><span style="background-color: white;"><b>Исходники:</b></span></span><br />
<span style="color: #222222; font-size: large;"><span style="background-color: white;"><b><a href="https://github.com/dajver/RoundCustomMapPinExample">GitHub</a></b></span></span></div>
dajverhttp://www.blogger.com/profile/09427222798699404442noreply@blogger.com0tag:blogger.com,1999:blog-5677605911484164185.post-10742717761337016882017-11-16T17:11:00.001+02:002017-11-16T17:15:58.185+02:00Добавляем индикатор в Toolbar и в TabLayout<div dir="ltr" style="text-align: left;" trbidi="on">
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Иногда в приложения требуется добавить какой-то индикатор уведомляющий пользователя о новых нотификейшенах, пропущеных фильмах или объявлениях. Для этого часто приходится использовать библиотеки или какие-то костыли для отображения. В этой статье я раскажу о двух костылях которые мне пригождаются часто. первый это индикатор в тулбаре, и второй это количество «чего-то» в фрагменте, и нам нужно отображать в табе количество «этого».</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Начну с простого. Отображение индикатора в тулбаре. Создаем проект, пустой, в котором у нас будет только активность и леяут к ней. Так же нам нужно будет создать еще дополнительно вьюху в которой у нас будет кастомный вид этой иконки, и по надобности мы будем ее применять.</span><br />
<a name='more'></a><br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<br />
<h3 style="-webkit-font-smoothing: antialiased; background-color: white; box-sizing: inherit; color: #222222; font-family: "Fira Sans", sans-serif; font-size: 20px; font-weight: 500; line-height: 28px; margin: 0px; padding: 0px;">
Индикатор на иконке в Toolbar</h3>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Для начала нам нужно создать саму менюшку. В ней у нас будет две иконки. Они будут вот так выглядеть.</span><br />
<br />
<div style="text-align: center;">
<img src="https://habrastorage.org/webt/dg/6n/m1/dg6nm1-clepf7rc19uzbtknbsk8.png" style="background-color: white; border-style: none; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px; margin: 0px; max-width: 100%; vertical-align: middle;" /> <span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;"> </span><img src="https://habrastorage.org/webt/cn/c9/cu/cnc9cumbvetibkfvooxk0soxupu.png" style="background-color: white; border-style: none; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px; margin: 0px; max-width: 100%; vertical-align: middle;" /></div>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">menu_main.xml</span><br />
<br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="xml hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;"><?xml version="1.0" encoding="utf-8"?></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">menu</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">xmlns:android</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"http://schemas.android.com/apk/res/android"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">xmlns:app</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"http://schemas.android.com/apk/res-auto"</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">item</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:id</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@+id/groups"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:title</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"My Groups"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:icon</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@mipmap/icon_invited_users"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">app:showAsAction</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"always"</span> /></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">item</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:id</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@+id/panics"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:title</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"Panics"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:icon</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@mipmap/icon_panic_counts"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">app:showAsAction</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"always"</span> /></span>
<span class="hljs-tag" style="box-sizing: inherit;"></<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">menu</span>></span>
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">А еще нам нужно создать точку которая будет поверх иконки.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">notification_round_badge.xml</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="xml hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;"><?xml version="1.0" encoding="utf-8"?></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">shape</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">xmlns:android</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"http://schemas.android.com/apk/res/android"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:shape</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"oval"</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">solid</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:color</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@color/colorAccent"</span> /></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">corners</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:bottomLeftRadius</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"2dp"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:bottomRightRadius</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"2dp"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:topLeftRadius</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"2dp"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:topRightRadius</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"2dp"</span> /></span>
<span class="hljs-tag" style="box-sizing: inherit;"></<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">shape</span>></span>
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">А еще нам понадобится иконка с точкой, для кастомизации вида нашей иконки.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">view_menu_icon_badge.xml</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="xml hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;"><?xml version="1.0" encoding="utf-8"?></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">FrameLayout</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">xmlns:android</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"http://schemas.android.com/apk/res/android"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:id</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@+id/counterPanel"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_width</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"32dp"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_height</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"32dp"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:background</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@mipmap/icon_invited_users"</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">LinearLayout</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:id</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@+id/counterValuePanel"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_width</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_height</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_gravity</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"bottom|left"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:gravity</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"bottom"</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">ImageView</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:id</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@+id/counterBackground"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_width</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"7dp"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_height</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"7dp"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:background</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@drawable/notification_round_badge"</span> /></span>
<span class="hljs-tag" style="box-sizing: inherit;"></<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">LinearLayout</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"></<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">FrameLayout</span>></span>
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Ну, а теперь нам осталось еще это все собрать в кучу, активити. </span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">MainToolbarActivity.java</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="java hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.graphics.Bitmap;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.graphics.drawable.BitmapDrawable;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.graphics.drawable.Drawable;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.os.Bundle;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.support.v7.app.AppCompatActivity;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.view.LayoutInflater;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.view.Menu;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.view.MenuInflater;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.view.View;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-class" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">class</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">MainToolbarActivity</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">extends</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">AppCompatActivity</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">boolean</span> isYouWantToShowBadge = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">false</span>;
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">protected</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onCreate</span><span class="hljs-params" style="box-sizing: inherit;">(Bundle savedInstanceState)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">super</span>.onCreate(savedInstanceState);
setContentView(R.layout.activity_toolbar_main);
}
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">boolean</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onCreateOptionsMenu</span><span class="hljs-params" style="box-sizing: inherit;">(Menu menu)</span> </span>{
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu_main, menu);
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">if</span>(isYouWantToShowBadge)
menu.findItem(R.id.groups).setIcon(buildCounterDrawable(R.mipmap.icon_invited_users));
menu.findItem(R.id.panics).setIcon(buildCounterDrawable(R.mipmap.icon_panic_counts));
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">true</span>;
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> Drawable <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">buildCounterDrawable</span><span class="hljs-params" style="box-sizing: inherit;">(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> backgroundImageId)</span> </span>{
LayoutInflater inflater = LayoutInflater.from(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>);
View view = inflater.inflate(R.layout.view_menu_icon_badge, <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">null</span>);
view.setBackgroundResource(backgroundImageId);
view.measure(View.MeasureSpec.makeMeasureSpec(<span class="hljs-number" style="box-sizing: inherit; color: #986801;">0</span>, View.MeasureSpec.UNSPECIFIED), View.MeasureSpec.makeMeasureSpec(<span class="hljs-number" style="box-sizing: inherit; color: #986801;">0</span>, View.MeasureSpec.UNSPECIFIED));
view.layout(<span class="hljs-number" style="box-sizing: inherit; color: #986801;">0</span>, <span class="hljs-number" style="box-sizing: inherit; color: #986801;">0</span>, view.getMeasuredWidth(), view.getMeasuredHeight());
view.setDrawingCacheEnabled(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">true</span>);
view.setDrawingCacheQuality(View.DRAWING_CACHE_QUALITY_HIGH);
Bitmap bitmap = Bitmap.createBitmap(view.getDrawingCache());
view.setDrawingCacheEnabled(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">false</span>);
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> BitmapDrawable(getResources(), bitmap);
}
}
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">И вот тут мы в onCreateOptionsMenu() указываем что будем использовать как менюшку, дальше я для примера сделал как сделать иконку без пина, и с пином. Делаю проверку и отображаю иконки. Для установки пина мы используем метод buildCounterDrawable() который берет наш кастомный файл с разметкой, и указываем ему какую иконку использовать и что на нее накладывать точку и превращаем в битмап для отображения. </span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">В итоге у вас получится вот такая штука, если вы брали код который я предоставил.</span><br />
<div style="text-align: center;">
<img height="50" src="https://habrastorage.org/webt/vs/ix/ou/vsixoukswwzzh9evxekptf1g7bk.png" style="background-color: white; border-style: none; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px; margin: 0px; max-width: 100%; vertical-align: middle;" width="400" /></div>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<br />
<h3 style="-webkit-font-smoothing: antialiased; background-color: white; box-sizing: inherit; color: #222222; font-family: "Fira Sans", sans-serif; font-size: 20px; font-weight: 500; line-height: 28px; margin: 0px; padding: 0px;">
Индикатор на иконке в TabLayout</h3>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Для того что бы добавить нам цифры в таб, нам нужно взять таб и наложить на него кастомную вьюху. А в кастомном табе мы уже будем менять иконки, текст и т.д.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Для начала нам нужно создать все нужные вьюхи, а это кастомный вид таба, и заливка баджа. Начнем мы с заливки.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">badge_background.xml</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="xml hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;"><?xml version="1.0" encoding="utf-8"?></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">layer-list</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">xmlns:android</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"http://schemas.android.com/apk/res/android"</span> ></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">item</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">xmlns:android</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"http://schemas.android.com/apk/res/android"</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">shape</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:shape</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"oval"</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">solid</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:color</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@color/colorAccent"</span> /></span>
<span class="hljs-tag" style="box-sizing: inherit;"></<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">shape</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"></<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">item</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"></<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">layer-list</span>></span>
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Просто делаем круглую заливку что бы подложить под текст в кастомном табе. Дальше добавляем эту заливку в кастомный таб.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">view_tabs_with_badge.xml</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="xml hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;"><?xml version="1.0" encoding="utf-8"?></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">LinearLayout</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">xmlns:android</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"http://schemas.android.com/apk/res/android"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_width</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_height</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"wrap_content"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_centerInParent</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"true"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:gravity</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"center_vertical|center_horizontal"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:orientation</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"horizontal"</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">TextView</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:id</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@+id/title"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_width</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"wrap_content"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_height</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"wrap_content"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:text</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"TextView"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:textAllCaps</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"true"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:textColor</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@android:color/black"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:textSize</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"14sp"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:textStyle</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"bold"</span> /></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">TextView</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:id</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@+id/count"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_width</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"20dp"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_height</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"20dp"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_marginLeft</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"10dp"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:background</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@drawable/badge_background"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:gravity</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"center"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:text</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"1"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:textColor</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@color/colorPrimary"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:textSize</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"14sp"</span> /></span>
<span class="hljs-tag" style="box-sizing: inherit;"></<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">LinearLayout</span>></span>
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">И вот таким образом мы подготовили все для создания таба. Дальше нам нужно добавить в активити TabLayout и ViewPager. </span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">activity_tabs_main.xml</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="xml hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;"><?xml version="1.0" encoding="utf-8"?></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">LinearLayout</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">xmlns:android</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"http://schemas.android.com/apk/res/android"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">xmlns:app</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"http://schemas.android.com/apk/res-auto"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">xmlns:tools</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"http://schemas.android.com/tools"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_width</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_height</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:orientation</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"vertical"</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">android.support.design.widget.TabLayout</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:id</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@+id/tab_layout"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_width</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_height</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"wrap_content"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:background</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@android:color/white"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:elevation</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"1dp"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:minHeight</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"?attr/actionBarSize"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:theme</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@style/ThemeOverlay.AppCompat.Dark.ActionBar"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">app:tabIndicatorColor</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@color/colorAccent"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">app:tabSelectedTextColor</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@android:color/black"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">app:tabTextColor</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@android:color/black"</span> /></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">android.support.v4.view.ViewPager</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:id</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@+id/pager"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_width</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_height</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"fill_parent"</span> /></span>
<span class="hljs-tag" style="box-sizing: inherit;"></<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">LinearLayout</span>></span>
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Настроили красоту, что бы там цвет нам нужный был, что бы оно было нужного размера и цвета… дальше нам нужно создать адаптер для пейджинга ну и потом все это подключить в активити.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">PagerAdapter.java</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="java hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.support.v4.app.Fragment;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.support.v4.app.FragmentManager;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.support.v4.app.FragmentPagerAdapter;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> java.util.ArrayList;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> java.util.List;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-class" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">class</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">PagerAdapter</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">extends</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">FragmentPagerAdapter</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">final</span> List<Fragment> mFragmentList = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> ArrayList<>();
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">final</span> List<String> mFragmentTitleList = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> ArrayList<>();
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">PagerAdapter</span><span class="hljs-params" style="box-sizing: inherit;">(FragmentManager manager)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">super</span>(manager);
}
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> Fragment <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">getItem</span><span class="hljs-params" style="box-sizing: inherit;">(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> position)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> mFragmentList.get(position);
}
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">getCount</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> mFragmentList.size();
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">addFragment</span><span class="hljs-params" style="box-sizing: inherit;">(Fragment fragment, String title)</span> </span>{
mFragmentList.add(fragment);
mFragmentTitleList.add(title);
}
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> CharSequence <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">getPageTitle</span><span class="hljs-params" style="box-sizing: inherit;">(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> position)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> mFragmentTitleList.get(position);
}
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">getItemPosition</span><span class="hljs-params" style="box-sizing: inherit;">(Object object)</span></span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">super</span>.getItemPosition(object);
}
}
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">В общем, создаем дав списка, первый хранит список с фрагментами которые будем отображать, второй хранит тайтлы с названиями табов. В зависимости от позиции будем отображать нужный таб. Дальше создадим три фрагмента которые будем отображать в пейджере.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">Fragment1.java, Fragment2.java, Fragment3.java</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="java hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-class" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">class</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">Fragment1</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">extends</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">Fragment</span> </span>{
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> View <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onCreateView</span><span class="hljs-params" style="box-sizing: inherit;">(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)</span> </span>{
View rootView = inflater.inflate(R.layout.fragment_tab, container, <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">false</span>);
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> rootView;
}
}
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Создал число для вида, в них ничего не будет, просто пустые фрагменты. Совершенно одинаковые, меняется только название фрагмента. Ну и дальше объеденяем все в акивити. </span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">MainTabsActivity.java</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="java hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.os.Bundle;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.support.design.widget.TabLayout;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.support.v4.view.ViewPager;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.support.v7.app.AppCompatActivity;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.view.View;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.widget.TextView;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> com.project.dajver.tabsbadgeexample.adapter.PagerAdapter;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> com.project.dajver.tabsbadgeexample.section.Fragment1;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> com.project.dajver.tabsbadgeexample.section.Fragment2;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> com.project.dajver.tabsbadgeexample.section.Fragment3;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> java.util.ArrayList;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> butterknife.BindView;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> butterknife.ButterKnife;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-class" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">class</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">MainTabsActivity</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">extends</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">AppCompatActivity</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> ArrayList<String> tabTitle = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> ArrayList<>();
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span>[] unreadCount = {<span class="hljs-number" style="box-sizing: inherit; color: #986801;">0</span>, <span class="hljs-number" style="box-sizing: inherit; color: #986801;">0</span>, <span class="hljs-number" style="box-sizing: inherit; color: #986801;">0</span>};
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@BindView</span>(R.id.tab_layout)
TabLayout tabLayout;
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@BindView</span>(R.id.pager)
ViewPager viewPager;
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">protected</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onCreate</span><span class="hljs-params" style="box-sizing: inherit;">(Bundle savedInstanceState)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">super</span>.onCreate(savedInstanceState);
setContentView(R.layout.activity_tabs_main);
ButterKnife.bind(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>);
tabTitle.add(getString(R.string.title_my_friends_screen));
tabTitle.add(getString(R.string.title_my_groups_screen));
tabTitle.add(getString(R.string.title_my_invites_screen));
unreadCount[<span class="hljs-number" style="box-sizing: inherit; color: #986801;">1</span>] = <span class="hljs-number" style="box-sizing: inherit; color: #986801;">23</span>;
unreadCount[<span class="hljs-number" style="box-sizing: inherit; color: #986801;">2</span>] = <span class="hljs-number" style="box-sizing: inherit; color: #986801;">3</span>;
viewPager.setOffscreenPageLimit(<span class="hljs-number" style="box-sizing: inherit; color: #986801;">3</span>);
setupViewPager(viewPager);
tabLayout.setupWithViewPager(viewPager);
setupTabIcons();
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">setupViewPager</span><span class="hljs-params" style="box-sizing: inherit;">(ViewPager viewPager)</span> </span>{
PagerAdapter adapter = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> PagerAdapter(getSupportFragmentManager());
Fragment1 friendsTabFragment = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> Fragment1();
Fragment2 myGroupsTabFragment = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> Fragment2();
Fragment3 invitesTabFragment = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> Fragment3();
adapter.addFragment(friendsTabFragment, getString(R.string.title_my_friends_screen));
adapter.addFragment(myGroupsTabFragment, getString(R.string.title_my_groups_screen));
adapter.addFragment(invitesTabFragment, getString(R.string.title_my_invites_screen));
viewPager.setAdapter(adapter);
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">setupTabIcons</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">for</span>(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> i = <span class="hljs-number" style="box-sizing: inherit; color: #986801;">0</span>; i < tabTitle.size(); i++) {
View view = getLayoutInflater().inflate(R.layout.view_tabs_with_badge,<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">null</span>);
TextView textView = view.findViewById(R.id.title);
TextView countView = view.findViewById(R.id.count);
textView.setText(tabTitle.get(i));
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">if</span>(unreadCount[i] > <span class="hljs-number" style="box-sizing: inherit; color: #986801;">0</span>) {
countView.setVisibility(View.VISIBLE);
countView.setText(String.valueOf(unreadCount[i]));
} <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">else</span>
countView.setVisibility(View.GONE);
tabLayout.getTabAt(i).setCustomView(view);
}
}
}
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">И так, в onCreate() мы добавляем тайтлы табов, у нас их будет три, группы, друзья и приглашения. дальше задаем что в первом табе у нас не будет никаких баджей, а на остальных двух будут. </span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">В setupViewPager() мы создаем фрагменты которые будут привязаны к табам и отправляем это все в адаптер. С помощью setupTabIcons() мы создаем наши табы с иконками и в зависимости от того надо нам оно отображать бадж или нет мы делаем его видимым или невидимым и в итоге добавялем во вьюху.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">И в итоге должно получится что-то на подобии штуки как ниже</span><br />
<div style="text-align: center;">
<img height="108" src="https://habrastorage.org/webt/j8/hx/om/j8hxomrdwr6f34ffftkxggwfpbu.png" style="background-color: white; border-style: none; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px; margin: 0px; max-width: 100%; vertical-align: middle;" width="400" /></div>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Если у вас все получилось — поздравляю, вы тру кодер который смог!</span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;"><br /></span>
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Исходники разделены на два модуля, tabs и toolbar. Думаю разобраться будет не сложно что-где :)</span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;"><br /></span>
<span style="color: #222222; font-size: large;"><span style="background-color: white;"><b>Исходники:</b></span></span><br />
<span style="color: #222222; font-size: large;"><span style="background-color: white;"><b><a href="https://github.com/dajver/IconBadgeExample">GitHub</a></b></span></span></div>
dajverhttp://www.blogger.com/profile/09427222798699404442noreply@blogger.com0tag:blogger.com,1999:blog-5677605911484164185.post-11258079907482612062017-11-16T14:31:00.000+02:002017-11-16T17:16:22.278+02:00Разработка базы данных с помощью Room<div dir="ltr" style="text-align: left;" trbidi="on">
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjm9wpJoeNawcFLBmjn8ePslpoaLEwBnRjS7z2wCgxu7wc1Lsjdri9YWvbURUb8gpP6FvhypadxxjbVMbZEbQrP8rSYTAy09sZej7IETiVP33Nysd1nyOxrmcCS2SL6smzsBd6vkwK3TDU/s1600/1-iG7cPgugRcTueis4MlabCQ.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1194" data-original-width="1600" height="238" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjm9wpJoeNawcFLBmjn8ePslpoaLEwBnRjS7z2wCgxu7wc1Lsjdri9YWvbURUb8gpP6FvhypadxxjbVMbZEbQrP8rSYTAy09sZej7IETiVP33Nysd1nyOxrmcCS2SL6smzsBd6vkwK3TDU/s320/1-iG7cPgugRcTueis4MlabCQ.png" width="320" /></a></div>
<br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Все сталкиваются рано или поздно с созданием локальной базы данных в своих приложениях. Часто, после нескольких часов гугления у нас остается список из кучи ORM которые могут нам помочь с разработкой БД. Я уже писал про самостоятельную разработку БД, еще очень давно, с того времени много чего поменялось, мой уровень знаний вырос, и я сейчас бы не советовал использовать тот способ, так как я писал уже про работу с БД с помощью Realm который разы удобней и проще чем написание и поддержка базы на стандартных методах и классах андроида. Тем более Room является библиотекой которую сам Google советует использовать как БД.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Вот эти две статьи по базам данных. Первая и очень старая. Этот вариант предпочитают использовать только хардкорные трукодеры которые не признают библиотеки, и которым нравится прям контролировать все все. Второй вариант представляет собой библиотеку которая делает все за вас, а вам нужно просто создать модели по которым будет строится БД и дальше уже просто стучаться в БД на чтение, запись, апдейт или удаление данных.</span><br />
<br />
<ul style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px; margin: 0px 0px 0px 30px; padding: 0px;">
<li style="box-sizing: inherit; line-height: 1.6; padding: 0px 0px 9px;"><a href="http://dajver.blogspot.com/2013/01/android.html" style="background-color: transparent; box-sizing: inherit; color: #992298; text-decoration-line: none;">Работа с базой данных Android (31 января 2013 г.)</a></li>
<li style="box-sizing: inherit; line-height: 1.6; padding: 9px 0px 0px;"><a href="http://dajver.blogspot.com/2017/06/realm.html" style="background-color: transparent; box-sizing: inherit; color: #992298; text-decoration-line: none;">Разработка базы данных с помощью Realm (15 июня 2017 г.)</a></li>
</ul>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">А сегодня я расскажу про еще одну ORM которая помогает реализовывать базу данных, и при чем помогает это сделать красиво и без лишних движений. Начнем мы как всегда с настройки проекта, так как нам нужно подключить кучу библиотек без которых наша жизнь была бы скучна и грустна.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Приложение будет очень простое, оно будет уметь отображать данные в списке на главном экране, и уметь удалять из списка по одному элементу. И у нас будет отдельный экран для добавления данных в БД, в котором будут два поля и кнопка добавить. Вот и вся функциональность, но этого я думаю будет достаточно что бы понять основы.</span><br />
<a name='more'></a><br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Добавляем в app/build.gradle наши библиотеки. А еще по недавней традиции добавляем java 8 в проект, так будет красивее. </span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">app/build.gradle</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="java hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;">android {
...
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
dependencies {
<span class="hljs-function" style="box-sizing: inherit;">implementation <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">fileTree</span><span class="hljs-params" style="box-sizing: inherit;">(dir: <span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">'libs'</span>, include: [<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">'*.jar'</span>])</span>
implementation 'com.android.support:appcompat-v7:26.1.0'
implementation 'com.android.support:recyclerview-v7:26.1.+'
implementation 'com.jakewharton:butterknife:8.8.1'
annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'
implementation "android.arch.persistence.room:runtime:1.0.0"
annotationProcessor "android.arch.persistence.room:compiler:1.0.0"
}
</span></code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Как видно из списка dependencies, у нас подключен RecyclerView для отображения списка, Butter Knife для простого доступа к вьюхам, и сам Room для создания БД. Вот и все, у нас есть все что нам нужно для создания красоты. </span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Начнем мы с того что создадим модель которая будет иметь поля в которые мы будем сохранять данные. </span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">DataModel.java</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="java hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.arch.persistence.room.Entity;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.arch.persistence.room.PrimaryKey;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.support.annotation.NonNull;
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Entity</span>
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-class" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">class</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">DataModel</span> </span>{
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@NonNull</span>
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@PrimaryKey</span>
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> String title;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> String description;
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@NonNull</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> String <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">getTitle</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> title;
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">setTitle</span><span class="hljs-params" style="box-sizing: inherit;">(@NonNull String title)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>.title = title;
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> String <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">getDescription</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> description;
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">setDescription</span><span class="hljs-params" style="box-sizing: inherit;">(String description)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>.description = description;
}
}
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Вот такая моделька у нас будет. В ней у нас будет тайтл который в то же время будет у нас @PrimaryKey для сохранения связей между таблицами, но так как у нас таблица одна нам пока связывать ничего особо не нужно, и еще у нас будет поле описание. Так же у нас вверху над классом стоит аннотация @Entity, она значит для Room что этот класс будет использовать как таблица в БД.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Дальше нам нужно создать интерфейс Dao который будет расказывать Room что мы будем делать с нашей моделью (таблицей). Для этого мы создаем интерфейс и определяем в нем методы которые нам нужны для работы с БД, в моем случае это будет запись, удаление и чтение.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">DataDao.java</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="java hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.arch.persistence.room.Dao;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.arch.persistence.room.Delete;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.arch.persistence.room.Insert;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.arch.persistence.room.Query;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> com.project.dajver.roomdatabaseexample.db.model.DataModel;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> java.util.List;
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Dao</span>
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-class" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">interface</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">DataDao</span> </span>{
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Insert</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">insert</span><span class="hljs-params" style="box-sizing: inherit;">(DataModel dataModel)</span></span>;
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Delete</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">delete</span><span class="hljs-params" style="box-sizing: inherit;">(DataModel dataModel)</span></span>;
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Query</span>(<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"SELECT * FROM DataModel"</span>)
<span class="hljs-function" style="box-sizing: inherit;">List<DataModel> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">getAllData</span><span class="hljs-params" style="box-sizing: inherit;">()</span></span>;
<span class="hljs-comment" style="box-sizing: inherit; color: #a0a1a7; font-style: italic;">//пример запроса с выборкой</span>
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Query</span>(<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"SELECT * FROM DataModel WHERE title LIKE :title"</span>)
<span class="hljs-function" style="box-sizing: inherit;">List<DataModel> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">getByTitle</span><span class="hljs-params" style="box-sizing: inherit;">(String title)</span></span>;
}
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Как видно из этого интерфейса, мы определили этот интерфейс аннотацией @Dao, она объясняет Room что мы будем делать с таблицей, мы в нее можем записать данные, удалить их и получить список всех данных. Каждый метод мы инициализируем аннотациями которые указывают то или иное действие. @Insert — очевидно значит запись в БД. @Delete — очевидно удаление. и @Query() — у нас выполняет действия по выполнению SQL запросов к БД, если захотите закостамизировать какие-то реквесты, на пример поиск по БД, вам достаточно просто вписать SQL в эту аннотацию и в зависимости от параметров которые вы там укажите, Room вернет вам ваши данные из БД.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Дальше нам нужно создать расширение для нашего интерфейса БД, который будет хранить в себе абстрактный метод для обращения к интерфейсу, что бы мы могли вызвать наши методы по записи, удалению и получению данных.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">DatabaseHelper.java</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="java hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Database</span>(entities = { DataModel.class }, version = <span class="hljs-number" style="box-sizing: inherit; color: #986801;">1</span>, exportSchema = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">false</span>)
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">abstract</span> <span class="hljs-class" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">class</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">DatabaseHelper</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">extends</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">RoomDatabase</span> </span>{
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">abstract</span> DataDao <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">getDataDao</span><span class="hljs-params" style="box-sizing: inherit;">()</span></span>;
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">protected</span> SupportSQLiteOpenHelper <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">createOpenHelper</span><span class="hljs-params" style="box-sizing: inherit;">(DatabaseConfiguration config)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">null</span>;
}
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">protected</span> InvalidationTracker <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">createInvalidationTracker</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">null</span>;
}
}
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">В этом классе мы указали в аннотации @Database, что у нас будет использоваться класс DataModel как таблица в которой будут храниться данные. version = 1 — у нас значит версию базы данных, при обновлении БД нужно будет только увеличивать версию и никаких сложных действий больше делать не придется, все остальное Room сделает сам. exportSchema = false — я использовал для того что бы не было постоянных ворнингов что схема не может быть построена или сохраненна. По сути каждый раз когда вы создаете БД создается файл схемы БД в JSON, и каждый раз при обновлении БД оно создает ее бекап что бы можно было видеть что было в старой и что появилось в новой. Детальней можно прочесть </span><a href="https://stackoverflow.com/a/44645943/520349" style="background-color: white; box-sizing: inherit; color: #992298; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px; text-decoration-line: none;">тут на стеке</a><span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">, может кому-то эта функция понадобится.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Ну и собственно наш единственный абстрактный метод abstract DataDao getDataDao() который возвращает все методы по БД которые у нас созданны в интерфейсе Dao.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Теперь нам нужно создать инстанс БД в синглтоне, не создавать же нам его каждый раз. По этому я выбрал класс Application который создается во время первого запуска приложения, и живет все время пока приложение работает. В нем я создал инстанс Room, а точней инстанс нашего DatabaseHelper который мы создали ранее.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">App.java</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="java hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.app.Application;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.arch.persistence.room.Room;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> com.project.dajver.roomdatabaseexample.db.DatabaseHelper;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-class" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">class</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">App</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">extends</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">Application</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">static</span> App instance;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> DatabaseHelper db;
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">static</span> App <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">getInstance</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> instance;
}
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onCreate</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">super</span>.onCreate();
instance = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>;
db = Room.databaseBuilder(getApplicationContext(), DatabaseHelper.class, <span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"data-database"</span>)
.allowMainThreadQueries()
.build();
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> DatabaseHelper <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">getDatabaseInstance</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> db;
}
}
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Все что происходит вокруг этого класса я думаю можно не описывать, хочу только остановиться на методе onCreate() в котором у нас создается объект класса DatabaseHelper. А точнее мы создаем его экземпляр с помощью Room.databaseBuilder, и называем его каким-то своим произвольным названием которое вам будет хотеться его назвать в моем случае это data-database. Приставка database не обязательна, это просто для примера. Ну и allowMainThreadQueries() разрешает нам делать запросы сразу в UI потоке без лишних обработчиков.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Далее создадим адаптер в котором будем отображать данные из БД.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">SomeDataRecyclerAdapter.java</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="java hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.content.Context;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.support.v7.widget.RecyclerView;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.view.LayoutInflater;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.view.View;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.view.ViewGroup;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.widget.TextView;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> com.project.dajver.roomdatabaseexample.R;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> com.project.dajver.roomdatabaseexample.db.model.DataModel;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> java.util.ArrayList;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> java.util.List;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> butterknife.BindView;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> butterknife.ButterKnife;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-class" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">class</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">SomeDataRecyclerAdapter</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">extends</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">RecyclerView</span>.<span class="hljs-title" style="box-sizing: inherit; color: #c18401;">Adapter</span><<span class="hljs-title" style="box-sizing: inherit; color: #c18401;">RecyclerView</span>.<span class="hljs-title" style="box-sizing: inherit; color: #c18401;">ViewHolder</span>></span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> List<DataModel> dataModels = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> ArrayList<>();
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> OnDeleteListener onDeleteListener;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> Context context;
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">SomeDataRecyclerAdapter</span><span class="hljs-params" style="box-sizing: inherit;">(Context context, List<DataModel> dataModels)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>.context = context;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>.dataModels = dataModels;
}
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> RecyclerView.<span class="hljs-function" style="box-sizing: inherit;">ViewHolder <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onCreateViewHolder</span><span class="hljs-params" style="box-sizing: inherit;">(ViewGroup parent, <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> viewType)</span> </span>{
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_some_data, parent, <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">false</span>);
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> NewsViewHolder(view);
}
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onBindViewHolder</span><span class="hljs-params" style="box-sizing: inherit;">(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">final</span> RecyclerView.ViewHolder holder, <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">final</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> position)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">final</span> NewsViewHolder viewHolder = (NewsViewHolder) holder;
viewHolder.title.setText(dataModels.get(position).getTitle());
viewHolder.description.setText(dataModels.get(position).getDescription());
}
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">getItemCount</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> dataModels.size();
}
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-class" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">class</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">NewsViewHolder</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">extends</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">RecyclerView</span>.<span class="hljs-title" style="box-sizing: inherit; color: #c18401;">ViewHolder</span> </span>{
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@BindView</span>(R.id.title)
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> TextView title;
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@BindView</span>(R.id.description)
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> TextView description;
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@BindView</span>(R.id.delete)
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> TextView delete;
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">NewsViewHolder</span><span class="hljs-params" style="box-sizing: inherit;">(View itemView)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">super</span>(itemView);
ButterKnife.bind(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>, itemView);
delete.setOnClickListener(view -> {
onDeleteListener.onDelete(dataModels.get(getAdapterPosition()));
dataModels.remove(getAdapterPosition());
notifyItemRemoved(getAdapterPosition());
});
}
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">setOnDeleteListener</span><span class="hljs-params" style="box-sizing: inherit;">(OnDeleteListener onDeleteListener)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>.onDeleteListener = onDeleteListener;
}
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-class" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">interface</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">OnDeleteListener</span> </span>{
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onDelete</span><span class="hljs-params" style="box-sizing: inherit;">(DataModel dataModel)</span></span>;
}
}
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Вполне себе стандартный адаптер. В него мы передаем список с DataModel и дальше в onBindViewHolder биндим эти данные во вьюхи. Так же у нас есть колбек который возвращает клик по крестику и вовзращает этот колбек в активити для удаления айтема из списка. Я даже не знаю что тут еще описывать еще. По идее все уже должны быть знакомы с этим адаптером, это вроде как стандарт.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Ну и файл разметки для адаптера.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">item_some_data.xml</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="xml hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;"><?xml version="1.0" encoding="utf-8"?></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">LinearLayout</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">xmlns:android</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"http://schemas.android.com/apk/res/android"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_width</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_height</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"wrap_content"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:orientation</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"vertical"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:padding</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"10dp"</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">LinearLayout</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_width</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_height</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"wrap_content"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:gravity</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"center_vertical"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:orientation</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"horizontal"</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">LinearLayout</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_width</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_height</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"wrap_content"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_weight</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"0.1"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:orientation</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"vertical"</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">TextView</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:id</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@+id/title"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_width</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_height</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"wrap_content"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:text</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"TextView"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:textColor</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@android:color/black"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:textSize</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"18sp"</span> /></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">TextView</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:id</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@+id/description"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_width</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_height</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"wrap_content"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_marginTop</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"10dp"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:text</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"TextView"</span> /></span>
<span class="hljs-tag" style="box-sizing: inherit;"></<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">LinearLayout</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">TextView</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:id</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@+id/delete"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_width</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"wrap_content"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_height</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"wrap_content"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:padding</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"10dp"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:text</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"[X]"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:textColor</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@android:color/black"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:textSize</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"18sp"</span> /></span>
<span class="hljs-tag" style="box-sizing: inherit;"></<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">LinearLayout</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"></<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">LinearLayout</span>></span>
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">А теперь осталось написать активити с списком и активити добавления. Начнем мы с главного экрана со списком. </span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">MainActivity.java</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="java hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.content.Intent;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.os.Bundle;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.support.v7.app.AppCompatActivity;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.support.v7.widget.LinearLayoutManager;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.support.v7.widget.RecyclerView;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.view.Menu;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.view.MenuItem;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> com.project.dajver.roomdatabaseexample.App;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> com.project.dajver.roomdatabaseexample.R;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> com.project.dajver.roomdatabaseexample.db.DatabaseHelper;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> com.project.dajver.roomdatabaseexample.db.model.DataModel;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> com.project.dajver.roomdatabaseexample.ui.AddDataActivity;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> com.project.dajver.roomdatabaseexample.ui.main.adapter.SomeDataRecyclerAdapter;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> butterknife.BindView;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> butterknife.ButterKnife;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-class" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">class</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">MainActivity</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">extends</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">AppCompatActivity</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">implements</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">SomeDataRecyclerAdapter</span>.<span class="hljs-title" style="box-sizing: inherit; color: #c18401;">OnDeleteListener</span> </span>{
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@BindView</span>(R.id.recyclerView)
RecyclerView recyclerView;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> DatabaseHelper databaseHelper;
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">protected</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onCreate</span><span class="hljs-params" style="box-sizing: inherit;">(Bundle savedInstanceState)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">super</span>.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>);
recyclerView.setLayoutManager(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> LinearLayoutManager(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>, LinearLayoutManager.VERTICAL,<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">false</span>));
databaseHelper = App.getInstance().getDatabaseInstance();
}
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">boolean</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onCreateOptionsMenu</span><span class="hljs-params" style="box-sizing: inherit;">(Menu menu)</span> </span>{
getMenuInflater().inflate(R.menu.menu_add_button, menu);
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">true</span>;
}
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">boolean</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onOptionsItemSelected</span><span class="hljs-params" style="box-sizing: inherit;">(MenuItem item)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">switch</span> (item.getItemId()) {
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">case</span> R.id.action_add: {
startActivity(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> Intent(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>, AddDataActivity.class));
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">break</span>;
}
}
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">false</span>;
}
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">protected</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onResume</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">super</span>.onResume();
SomeDataRecyclerAdapter recyclerAdapter = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> SomeDataRecyclerAdapter(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>, databaseHelper.getDataDao().getAllData());
recyclerAdapter.setOnDeleteListener(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>);
recyclerView.setAdapter(recyclerAdapter);
}
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onDelete</span><span class="hljs-params" style="box-sizing: inherit;">(DataModel dataModel)</span> </span>{
databaseHelper.getDataDao().delete(dataModel);
}
}
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">В onCreate() мы создали инстанс DatabaseHelper что бы можно было получать данные из БД и удалять их, и указали RecyclerView какой LayoutManager ему использовать. В onCreateOptionsMenu() и onOptionsItemSelected() мы делаем менюшку в тулбаре. В onResume() создаем адаптер, и каждый раз когда мы удем возвращаться с экрана добавления у нас будет обновленный адаптер с внесенными туда данными. Ну и onDelete() который по клику удаляет айтем из списка и БД.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Разметка активити и файл с пунктом меню для тулбара будет выглядеть так:</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">activity_main_xml</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="xml hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;"><?xml version="1.0" encoding="utf-8"?></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">LinearLayout</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">xmlns:android</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"http://schemas.android.com/apk/res/android"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">xmlns:app</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"http://schemas.android.com/apk/res-auto"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">xmlns:tools</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"http://schemas.android.com/tools"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_width</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_height</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">tools:context</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"com.project.dajver.roomdatabaseexample.ui.main.MainActivity"</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">android.support.v7.widget.RecyclerView</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:id</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@+id/recyclerView"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_width</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_height</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"match_parent"</span> /></span>
<span class="hljs-tag" style="box-sizing: inherit;"></<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">LinearLayout</span>></span>
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">menu_add_button.xml</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="xml hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;"><?xml version="1.0" encoding="utf-8"?></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">menu</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">xmlns:android</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"http://schemas.android.com/apk/res/android"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">xmlns:app</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"http://schemas.android.com/apk/res-auto"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">xmlns:tools</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"http://schemas.android.com/tools"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">tools:context</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">".activity.MainActivity"</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">item</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:id</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@+id/action_add"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:title</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"Add"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">app:showAsAction</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"always"</span>/></span>
<span class="hljs-tag" style="box-sizing: inherit;"></<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">menu</span>></span></code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Как видно из кода сверху у нас все тривиально. Список в мейн активити, и кнопка в меню которая видна всегда по умолчанию.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Дальше давайте сделаем экран добавления. В нем у нас будет как я говорил ранее — два поля и кнопка для добавления. После добавления экран закрывается.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">AddDataActivity.java</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="java hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.os.Bundle;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.support.v7.app.AppCompatActivity;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.widget.EditText;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> com.project.dajver.roomdatabaseexample.App;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> com.project.dajver.roomdatabaseexample.R;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> com.project.dajver.roomdatabaseexample.db.DatabaseHelper;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> com.project.dajver.roomdatabaseexample.db.model.DataModel;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> butterknife.BindView;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> butterknife.ButterKnife;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> butterknife.OnClick;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-class" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">class</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">AddDataActivity</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">extends</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">AppCompatActivity</span> </span>{
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@BindView</span>(R.id.title)
EditText title;
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@BindView</span>(R.id.description)
EditText description;
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">protected</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onCreate</span><span class="hljs-params" style="box-sizing: inherit;">(Bundle savedInstanceState)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">super</span>.onCreate(savedInstanceState);
setContentView(R.layout.activity_add);
ButterKnife.bind(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>);
}
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@OnClick</span>(R.id.save)
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onSaveClick</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
DatabaseHelper databaseHelper = App.getInstance().getDatabaseInstance();
DataModel model = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> DataModel();
model.setTitle(title.getText().toString());
model.setDescription(description.getText().toString());
databaseHelper.getDataDao().insert(model);
finish();
}
}
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Единственное что нас тут интересует это onSaveClick(), в нем мы создаем инстанс DatabaseHelper, а дальше заполняем нашу модель DataModel, и передаем этот объект на запись в insert. И завершаем активити. </span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Разметка для класса добавления.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">activity_add.xml</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="xml hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;"><?xml version="1.0" encoding="utf-8"?></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">LinearLayout</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">xmlns:android</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"http://schemas.android.com/apk/res/android"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_width</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_height</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:orientation</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"vertical"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:padding</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"10dp"</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">EditText</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:id</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@+id/title"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_width</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_height</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"wrap_content"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_marginTop</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"10dp"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:ems</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"10"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:hint</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"Title"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:inputType</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"textPersonName"</span> /></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">EditText</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:id</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@+id/description"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_width</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_height</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"wrap_content"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_marginTop</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"10dp"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:ems</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"10"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:hint</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"Description"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:inputType</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"textPersonName"</span> /></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">Button</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:id</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@+id/save"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_width</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_height</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"wrap_content"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_marginTop</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"10dp"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:onClick</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"onSaveClick"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:text</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"Save"</span> /></span>
<span class="hljs-tag" style="box-sizing: inherit;"></<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">LinearLayout</span>></span></code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Осталось не забыть добавить активити в манифест, и начать компиляцию. </span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;"><br /></span>
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Ну и это вроде бы все что нужно для создания небольшого приложения с базой данных. По сути теперь после того как вы все это собрали в кучу, у вас должно запустится приложение с пустым экраном, и кнопкой вверху на тулбаре ADD, после нажатия на которую вы сможете перейти на экран добавления, и после добавления увидите все что вы ввели в списке на главном экране.</span><br />
<div>
<b><br /></b></div>
<div>
<span style="color: #222222; font-size: large;"><span style="background-color: white;"><b>Исходники:</b></span></span><br />
<span style="color: #222222; font-size: large;"><span style="background-color: white;"><b><a href="https://github.com/dajver/RoomDatabaseExample">GitHub</a></b></span></span></div>
</div>
dajverhttp://www.blogger.com/profile/09427222798699404442noreply@blogger.com0tag:blogger.com,1999:blog-5677605911484164185.post-37192833562324528862017-11-14T22:37:00.001+02:002017-11-20T13:18:49.597+02:00Пишем код красиво с Rx Android <div dir="ltr" style="text-align: left;" trbidi="on">
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhm-xbEnskP_anK8vVPiLjgKvJFraphYHC8Gz7aNQr8rOLq8pIqvzblibhpFB5b9DfyiXHkRPsAvONh1H9qIzPC58uKskYoyJ_jQq8bJPOoc2kEqm2wLSuGr_TNwVFS8K0C75PsQRYgwJg/s1600/RX-Android.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="720" data-original-width="1280" height="180" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhm-xbEnskP_anK8vVPiLjgKvJFraphYHC8Gz7aNQr8rOLq8pIqvzblibhpFB5b9DfyiXHkRPsAvONh1H9qIzPC58uKskYoyJ_jQq8bJPOoc2kEqm2wLSuGr_TNwVFS8K0C75PsQRYgwJg/s320/RX-Android.png" width="320" /></a></div>
<br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Давно хотел рассказать про RX но никак не выходило, то времени не хватало, то желания небыло, и так куча причин была… А тут выдалось свободное время, и желание тоже появилось, в общем как-то планеты сошлись все в одну линию и пришло осознание бытия, и что пора написать что-то новое. </span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">В интернете куча статей о том как писать с помощью Rx, я сам по ним пытался учиться использовать его, много статей было прочитанно, но лишь одна статья меня реально поразила своей логичностью и порядком изложения информации, после которой у меня открылся третий глаз и я начал слышать голоса объясняющие основы Rx. </span><a href="https://android.jlelse.eu/reactive-programming-for-android-d55bdbb438b4" style="background-color: white; box-sizing: inherit; color: #992298; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px; text-decoration-line: none;">Вот эта статья.</a><span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Всем кто не знаком с Rx начинать с нее, даже не знание английского не помеха, Google Translate в помощь, статья очень понятно и логично расписывает работу с Rx. Прям ну ооочень хорошо. Остальные статьи как по мне шлак.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Попался мне проект один, который был написан на Rx, я как нубас впал в ступор и начал истерить что это вообще какая-то не понятная хрень и в растроенных чувствах начал разбираться в ней. В итоге понял что эта непонятная хрень довольно таки удобная хрень, дак еще и полезная, так как она обсорбирует в себя кучу ошибок, и разных плюшек типа работы в UI треде или объеденение нескольких списков в один после запроса. </span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">В этой статье я хочу рассказать про несколько вариантов использования Rx в проекте, в одном случае я приведу прям вот живой пример использования этой штуки, а в других случаях пройдусь объяснив как это можно реализовать у себя в проекте. Я лично использую Rx для спокойной и удобной работы в UI треде, как минимум не надо создавать там разные AsyncTask'и и писать кучу колбеков, достаточно написать один класс в котором будут нужные методы, а дальше просто вызывать этот класс в нужных классах, и получать нужные данные. </span><br />
<a name='more'></a><br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Начнем мы с того что разберем что такое Observable и Subscriber. Это два основных класса которые обеспечивают нас как программистов основными функциями Rx. Observable — у нас класс который хранит в себе данные, а Subscriber — класс передающий данные из Observable. Ну то есть Observable у нас хранит данные, а Subscriber — возвращает все что имеет в себе Observable. Как то так. В общем дальше на примерах будет понятней.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Стандартный вид Observable который все обычно используют это Observable, где Т — это любой объект который может быть возвращаен, пусть то будет Object, String или ArrayList. То есть Observable может вернуть буквально любой вид данных. </span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Давайте перейдем к практике. Вот у нас есть какая-то функция которая возвращает нам какой-то ArrayList, нам нужно его получить через Observable и передать в MainActivity. Что нам для этого нужно. Создать какой-то метод котоый будет возвращать Observable<ArrayList> и дальше вернуть этот список в наш метод.</span><br />
<br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="java hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> Observable<ArrayList<String>> getString() {
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> Observable.create(observableEmitter -> {
ArrayList<String> articlesModels = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> ArrayList<>();
articlesModels.add(<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"one"</span>);
articlesModels.add(<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"two"</span>);
articlesModels.add(<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"three"</span>);
observableEmitter.onNext(articlesModels);
});
}
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Как видно из кода, мы создали Observable.create, который передает какой-то observableEmitter, это объект самого ObservableEmitter<ArrayList> который возвращает текущее состояние потока, и работает в то же время колбеком для нас. С помощью его мы можем вызывать такие методы как:</span><br />
<br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="java hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;">observableEmitter.onNext();
observableEmitter.onError();
observableEmitter.onComplete();</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Из их названий я так думаю понятно что они занчат. onNext() вызывается когда выполнилась ваша функция, и он возвращает в Subscriber, то что вы передаете в него. onError() соответственно возвращает ошибку которую вы в него передадите, если ничего не передадите, то соответственно он ничего и не выведет. onComplete() вызывается когда все действия завершены и поток закрывается.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Дальше для того что бы в нашей MainActivity получить эти данные с помощью Subscriber, нам нужно создать подписчика, то есть Subscriber вызвав наш метод и дальше в методах будет возвращаться состояние вашего потока. В нашем случае просто выведется то, что я передал в предыдущем методе, без ошибок и остального.</span><br />
<br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="java hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;">getString()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> Observer<ArrayList<String>>() {
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onSubscribe</span><span class="hljs-params" style="box-sizing: inherit;">(Disposable d)</span> </span>{ }
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onNext</span><span class="hljs-params" style="box-sizing: inherit;">(ArrayList<String> strings)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">for</span>(String str : strings)
Log.e(<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"strings"</span>, str);
}
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onError</span><span class="hljs-params" style="box-sizing: inherit;">(Throwable e)</span> </span>{
e.printStackTrace();
}
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onComplete</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{ }
});</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Это в принципе основной функционал который считается самым популярным в RX. Есть еще методы just, first, last, rand, from, они все нужны, но в редких случаях когда у вас идет работа с локальным списком, когда вы передаете список в Observable и вам нужно сделать какие-то манипуляции с ним внутри Observable. Тогда да, но я тут все это размазывал не из-за этих методов, так что их я оставлю на потом. Возможно в будущем расскажу о них… </span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">А сейчас я расскажу как я парсил сайт с помощью JSOUP и RxAndroid. Это оказалось довольно просто, даже как-то подозрительно.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Для примера я взял сайт </span><a href="https://www.instructables.com/technology/" style="background-color: white; box-sizing: inherit; color: #992298; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px; text-decoration-line: none;">instructables.com.</a><span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;"> Там довольно простая верстка, и просто можно достать нужные названия классов для парсинга. В примере я всего лишь достану список статей из главной страницы об технологиях.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Начнем мы с того что создадим проект, и в нем у нас будут MainActivity.java и разметка activity_main.xml. Нам нужно будет подключить пару библиотек, и java 8 для работы ретролямбды, что бы не подключать библиотеку. Данный проект писался в Android Studio 3, они уже умеет в ретролямбду без ретролябмды, то есть фишки java 8 доступны без лишних библиотек, это кстати очень удобно, так как раньше это был страшный геморой, пока подключишь ее, свихнешься.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Библиотеки которые нам понадобятся:</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">app/build.gradle</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="java hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;">dependencies {
<span class="hljs-function" style="box-sizing: inherit;">implementation <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">fileTree</span><span class="hljs-params" style="box-sizing: inherit;">(dir: <span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">'libs'</span>, include: [<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">'*.jar'</span>])</span>
implementation 'com.android.support:appcompat-v7:26.1.0'
implementation 'com.android.support:recyclerview-v7:26.1.+'
implementation 'io.reactivex.rxjava2:rxandroid:2.0.1'
implementation 'io.reactivex.rxjava2:rxjava:2.1.5'
implementation 'com.jakewharton:butterknife:8.8.1'
annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'
implementation 'org.jsoup:jsoup:1.11.1'
implementation 'com.squareup.picasso:picasso:2.5.2'
}
</span></code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Вроде бы для такого маленького проекта не нужно особо много библиотек, но у меня их довольно много, я буду создавать списки с помощью RecyclerView, буду использовать Rx, буду паристь страницы с помощью JSOUP и буду искать вюхи с помощью ButterKnife, а еще как же без Picasso, мне же надо с помощью чего-то отображать картинки…</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">А еще нам нужно добавить в тот же app/build.gradle использование java 8. </span><br />
<br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="java hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;">android {
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Таким образом мы говорим студии что у нас можно сокращать код и делать что-то на подобии -> в место длинного и не удобного new View.OnClickListener() { private void onClick }. Но это опять же по желанию, мне нравятся эти сокращения, может кому-то больше нравится длинные но понятные колбеки, без этих непонятных сокращений.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">В общем с настройкой gradle мы справились, это уже великолепно. Далее нужно создать интерфейс который будет у нас хранить все методы которые нам нужны для работу. Так и красивей получается и удобней. У нас там будет один метод, но это ведь не важно, за то красиво! </span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">IRepository.java </span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="java hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> com.project.dajver.rxandroidecample.api.model.ArticlesModel;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> java.util.ArrayList;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> io.reactivex.Observable;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-class" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">interface</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">IRepository</span> </span>{
Observable<ArrayList<ArticlesModel>> getArticles(String url);
}</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">В общем создали мы интерфейс, Observable должен будет возвращать нам ArrayList, и это офигенно. Но что же такое ArticlesModel, а это просто модель в которой у нас хранится название и картинка статьи.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">ArticlesModel.java</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="java hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-class" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">class</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">ArticlesModel</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> String name;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> String imageUrl;
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> String <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">getName</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> name;
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">setName</span><span class="hljs-params" style="box-sizing: inherit;">(String name)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>.name = name;
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> String <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">getImageUrl</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> imageUrl;
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">setImageUrl</span><span class="hljs-params" style="box-sizing: inherit;">(String imageUrl)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>.imageUrl = imageUrl;
}
}</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Вот такая вот структура. Пока что просто? Просто, вот и замечательно, дальше нам нужно создать имплементацию нашего интерфейса Repository. Это очень просто, создаем класс любой, и имплементируем в него наш интерфейс, и там сразу создасться методы которые есть в нашем интерфейсе для дальнейшей реализации.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">RepositoryImpl.java</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="java hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> com.project.dajver.rxandroidecample.api.model.ArticlesModel;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> org.jsoup.Jsoup;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> org.jsoup.nodes.Document;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> org.jsoup.select.Elements;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> java.io.IOException;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> java.util.ArrayList;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> io.reactivex.Observable;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-class" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">class</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">RepositoryImpl</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">implements</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">IRepository</span> </span>{
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> Observable<ArrayList<ArticlesModel>> getArticles(String urlLink) {
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> Observable.create(observableEmitter -> {
ArrayList<ArticlesModel> articlesModels = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> ArrayList<>();
Document doc;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">try</span> {
doc = Jsoup.connect(urlLink).get();
Elements titleElement = doc.getElementsByClass(<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"title"</span>);
Elements imageElement = doc.getElementsByClass(<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"cover-image"</span>);
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">for</span>(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> i = <span class="hljs-number" style="box-sizing: inherit; color: #986801;">0</span>; i < titleElement.size(); i++) {
Elements imgsrc = imageElement.get(i).select(<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"img"</span>);
String style = imgsrc.attr(<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"src"</span>);
Elements ahref = titleElement.get(i).select(<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"a"</span>);
String titleText = ahref.text();
ArticlesModel model = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> ArticlesModel();
model.setName(titleText);
model.setImageUrl(style);
articlesModels.add(model);
}
observableEmitter.onNext(articlesModels);
} <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">catch</span> (IOException e) {
observableEmitter.onError(e);
} <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">finally</span> {
observableEmitter.onComplete();
}
});
}
}
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Что же мы тут имеем? А то что у нас создался наш метод getArticles() который у нас возвращает Observable<ArrayList>, и дальше у нас идет реализация Observable.create(), как я писал ранее. Тут у нас идет реализация парсинга сайта по ссылке, которую мы передаем в метод. Дальше Observable.create() у нас Rx заканчивается и начинается JSOUP, с его помощью мы находим нужные нам параметры на странице и парсим их доставая название статей и ссылки на картинки. Распихиваем это все по своим местам в ArticlesModel и сетим эти данные в список. А по окончанию, сетим этот список в observableEmitter.onNext().</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Если у нас появятся какие то ошибки, то мы добавили в catch метод onError() который принимает ексепшн и отдает его в сабскрайбера. Ну и в конце в finnlay когда уже все действия у нас заканчиваются мы вызываем onComplete(), что бы убирать прогрессбар на пример, или что-то прятать по окончанию загрузки.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Давайте создадим еще адаптер, что бы в конце статьи уже собрать все в кучу и получить какой-то красивый результат. Адаптер у нас будет стандартный, по этому я на нем не буду задерживать внимания. Обычный RecyclerView.Adapter который отображает текст и картинку.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">ArticlesRecyclerAdapter.java</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="java hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.content.Context;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.support.v7.widget.RecyclerView;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.view.LayoutInflater;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.view.View;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.view.ViewGroup;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.widget.ImageView;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.widget.TextView;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> com.project.dajver.rxandroidecample.R;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> com.project.dajver.rxandroidecample.api.model.ArticlesModel;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> com.squareup.picasso.Picasso;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> java.util.ArrayList;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> java.util.List;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> butterknife.BindView;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> butterknife.ButterKnife;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-class" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">class</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">ArticlesRecyclerAdapter</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">extends</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">RecyclerView</span>.<span class="hljs-title" style="box-sizing: inherit; color: #c18401;">Adapter</span><<span class="hljs-title" style="box-sizing: inherit; color: #c18401;">RecyclerView</span>.<span class="hljs-title" style="box-sizing: inherit; color: #c18401;">ViewHolder</span>></span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> List<ArticlesModel> newsModels = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> ArrayList<>();
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> Context context;
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">ArticlesRecyclerAdapter</span><span class="hljs-params" style="box-sizing: inherit;">(Context context, List<ArticlesModel> newsModels)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>.context = context;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>.newsModels = newsModels;
}
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> RecyclerView.<span class="hljs-function" style="box-sizing: inherit;">ViewHolder <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onCreateViewHolder</span><span class="hljs-params" style="box-sizing: inherit;">(ViewGroup parent, <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> viewType)</span> </span>{
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_aticle, parent, <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">false</span>);
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> NewsViewHolder(view);
}
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onBindViewHolder</span><span class="hljs-params" style="box-sizing: inherit;">(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">final</span> RecyclerView.ViewHolder holder, <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">final</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> position)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">final</span> NewsViewHolder viewHolder = (NewsViewHolder) holder;
viewHolder.title.setText(newsModels.get(position).getName());
Picasso.with(context).load(newsModels.get(position).getImageUrl()).into(viewHolder.image);
}
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">getItemCount</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> newsModels.size();
}
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-class" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">class</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">NewsViewHolder</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">extends</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">RecyclerView</span>.<span class="hljs-title" style="box-sizing: inherit; color: #c18401;">ViewHolder</span> </span>{
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@BindView</span>(R.id.title)
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> TextView title;
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@BindView</span>(R.id.image)
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> ImageView image;
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">NewsViewHolder</span><span class="hljs-params" style="box-sizing: inherit;">(View itemView)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">super</span>(itemView);
ButterKnife.bind(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>, itemView);
}
}
}</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Как я и говорил все тривиально просто. Создали адаптер который принимает в конструкторе ArrayList и дальше сетит данные из списка в вьюхи. </span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">И не забываем конечно же за разметочку для адаптера.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">item_article.xml</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="xml hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;"><?xml version="1.0" encoding="utf-8"?></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">LinearLayout</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">xmlns:android</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"http://schemas.android.com/apk/res/android"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">xmlns:app</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"http://schemas.android.com/apk/res-auto"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_width</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_height</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"wrap_content"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:gravity</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"center_vertical"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:orientation</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"horizontal"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:padding</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"10dp"</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">ImageView</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:id</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@+id/image"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_width</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"100dp"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_height</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"100dp"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:scaleType</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"fitCenter"</span> /></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">TextView</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:id</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@+id/title"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_width</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"wrap_content"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_height</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"wrap_content"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_marginLeft</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"10dp"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:text</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"TextView"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:textColor</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@android:color/black"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:textSize</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"18sp"</span> /></span>
<span class="hljs-tag" style="box-sizing: inherit;"></<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">LinearLayout</span>></span></code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">А что же делать дальше скажете вы? Да все просто, дальше мы открываем наш MainActivity, и прямо в onCreate() пишем вызов этого метода с определенными параметрами, которые я описывал выше. </span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">MainActivity.java</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="java hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.os.Bundle;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.support.v7.app.AppCompatActivity;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.support.v7.widget.DividerItemDecoration;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.support.v7.widget.LinearLayoutManager;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.support.v7.widget.RecyclerView;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> com.project.dajver.rxandroidecample.adapter.ArticlesRecyclerAdapter;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> com.project.dajver.rxandroidecample.api.RepositoryImpl;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> com.project.dajver.rxandroidecample.api.model.ArticlesModel;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> java.util.ArrayList;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> butterknife.BindView;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> butterknife.ButterKnife;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> io.reactivex.Observer;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> io.reactivex.android.schedulers.AndroidSchedulers;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> io.reactivex.disposables.Disposable;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> io.reactivex.schedulers.Schedulers;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-class" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">class</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">MainActivity</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">extends</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">AppCompatActivity</span> </span>{
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@BindView</span>(R.id.recyclerView)
RecyclerView recyclerView;
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">protected</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onCreate</span><span class="hljs-params" style="box-sizing: inherit;">(Bundle savedInstanceState)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">super</span>.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>);
recyclerView.setLayoutManager(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> LinearLayoutManager(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>, LinearLayoutManager.VERTICAL, <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">false</span>));
recyclerView.addItemDecoration(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> DividerItemDecoration(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>, DividerItemDecoration.VERTICAL));
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> RepositoryImpl().getArticles(<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"https://www.instructables.com/technology/"</span>)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> Observer<ArrayList<ArticlesModel>>() {
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onSubscribe</span><span class="hljs-params" style="box-sizing: inherit;">(Disposable d)</span> </span>{ }
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onNext</span><span class="hljs-params" style="box-sizing: inherit;">(ArrayList<ArticlesModel> articlesModels)</span> </span>{
ArticlesRecyclerAdapter articlesRecyclerAdapter = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> ArticlesRecyclerAdapter(MainActivity.<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>, articlesModels);
recyclerView.setAdapter(articlesRecyclerAdapter);
}
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onError</span><span class="hljs-params" style="box-sizing: inherit;">(Throwable e)</span> </span>{
e.printStackTrace();
}
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onComplete</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{ }
});
}
}</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Находим RecyclerView на нашей активити, задаем ему параметры, что бы он использовал LinearLayoutManager для отображения, и DividerItemDecoration для разделения айтемов друг от друга. Дальше вызываем наш RepositoryImpl() который вызывает наш метод, передаем в него ссылку откуда парсить наши статьи. </span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Метод subscribeOn(Schedulers.io()) — говорит о том что поток в котором будет выполняться функция будет задан Schedulers'ом.</span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Метод observeOn(AndroidSchedulers.mainThread()) — очевидно говорит что потом мы создаем поверх нашего UI треда. Но как бы мы не хотели повлиять на главный поток, он все равно не будет заблокирован пока действие не закончится, то что нам как раз и нужно, так как JSOUP требует выполнение действий в отдельном потоке.</span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Ну и конечно же subscribe() который возвращает нам наш Observer<ArrayList>, который мы и хотим получить в итоге. </span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Дальше в методе onNext() мы получаем наш ArrayList, и выводим то что у нас в нем есть в адаптер. Если же у нас появтяся какие-то ошибки по ходу действия Observable — все ошибки вернутся в onError().</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Осталось только создать RecyclerView в разметке. Кто не знает как вот пример.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">activity_main.xml</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="xml hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;"><?xml version="1.0" encoding="utf-8"?></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">LinearLayout</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">xmlns:android</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"http://schemas.android.com/apk/res/android"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">xmlns:tools</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"http://schemas.android.com/tools"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_width</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_height</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"match_parent"</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">android.support.v7.widget.RecyclerView</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:id</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@+id/recyclerView"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_width</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_height</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"wrap_content"</span> /></span>
<span class="hljs-tag" style="box-sizing: inherit;"></<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">LinearLayout</span>></span>
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">И не забываем что у нас приложение все таки работает с интернетом, по этому ему нужно разрешить работу с интернетом в манифесте.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">AndroidManifest.xml</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="xml hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"> <span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">uses-permission</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:name</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"android.permission.INTERNET"</span> /></span></code></pre>
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">И вот после этого всего, у вас по идее должно все скомпилироваться и работать как часы, без падений и ексепшинов. Как часы. </span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;"><br /></span>
<br />
<div>
<span style="color: #222222; font-size: large;"><span style="background-color: white;"><b>Исходники:</b></span></span><br />
<span style="color: #222222; font-size: large;"><span style="background-color: white;"><b><a href="https://github.com/dajver/RXAndroidExample">GitHub</a></b></span></span></div>
<br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;"><b>PS:</b></span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;"><br /></span>
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Rx еще часто используют для комбайна данных из запросов Retrofit на пример. Это довольно интересная тема, так как это очень спасает от костылей которые будут вручную эти данные добавлять и будут в ключат ьв себя кучу ошибок типа смешивания данных и путаницу в айдишниках, а так у нас допустим есть два запроса, как это было сказанно в статье с медиума что я выше дал, для получения фотографии и данных пользователя, и нам нужно эти данные объеденить в одну кучу что бы потом передать куда-нибудь в адаптер.</span><span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;"> </span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Если в кратце. Мы создаем интерфейс для работы с ретрофитом, как я описывал это в </span><a href="http://dajver.blogspot.com/2017/05/retrofit.html" style="background-color: white; box-sizing: inherit; color: #992298; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px; text-decoration-line: none;">статье про работу с Retrofit</a><span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">.</span><br />
<br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="java hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@GET</span>(<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"/user/{id}/photo"</span>)
<span class="hljs-function" style="box-sizing: inherit;">Observable<Photo> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">getUserPhoto</span><span class="hljs-params" style="box-sizing: inherit;">(@Path(<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"id"</span>)</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> id)</span>;
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@GET</span>(<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"/photo/{id}/metadata"</span>)
<span class="hljs-function" style="box-sizing: inherit;">Observable<Metadata> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">getPhotoMetadata</span><span class="hljs-params" style="box-sizing: inherit;">(@Path(<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"id"</span>)</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> id)</span>;</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">И у нас как бы есть два запроса, которые мы дальше объеденяем в простую конструкцию</span><br />
<br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="java hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;">Observable.zip(
service.getUserPhoto(id),
service.getPhotoMetadata(id),
(photo, metadata) -> createPhotoWithData(photo, metadata))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(photoWithData -> showPhoto(photoWithData));</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Где Observable.zip() метод который объеденяет наши два объекта service.getUserPhoto(id) и service.getPhotoMetadata(id). Дальше у нас идет колбек который возвращае (photo, metadata) и мы их объъеденяем в методе createPhotoWithData() который принимает их. Указываем работу в отдельном потоке, но при этом в UI, и дальше выводим то что у нас получилось в итоге в subscribe(), в метод showPhoto() который принимает photoWithData.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">В общем если вам так не понятно то объясню на другом примере. Возможно так будет более понятно. Вот у нас есть два метода которые возвращают разные данные в списках.</span><br />
<br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="java hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> Observable<ArrayList<String>> getUserPhoto() {
ArrayList<String> strings = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> ArrayList<>();
strings.add(<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"one"</span>);
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> Observable.fromArray(strings);
}
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> Observable<ArrayList<String>> getUserMetadata() {
ArrayList<String> strings = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> ArrayList<>();
strings.add(<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"two"</span>);
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> Observable.fromArray(strings);
}</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Первый у нас возвращает слово one. Второй возвращает слово two. И преобразовываем мы это все в Observable что бы можно было его скормить для парсинга. Все очень просто, а дальше у нас уже знакомая конструкция сбора данных в одну кучу:</span><br />
<br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="java hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;">Observable.zip(
getUserPhoto(),
getUserMetadata(),
(strings, strings2) -> {
ArrayList<String> stringsList = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> ArrayList<>();
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">for</span>(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> i = <span class="hljs-number" style="box-sizing: inherit; color: #986801;">0</span>; i < strings.size(); i++) {
stringsList.add(strings.get(i) + <span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">" | "</span> + strings2.get(i));
}
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> stringsList;
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(photoWithData -> {
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">for</span>(String s : photoWithData)
Log.e(<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"tag"</span>, s);
});</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Передаем в Observable.zip() наши два списка, дальше объеденяем их, выполняем это мы все в отдельном UI потоке, и потом в subscribe() выводим в лог, то что у нас получилось в итоге.</span><br />
<br />
<div>
<span style="color: #222222; font-size: large;"><span style="background-color: white;"><b>Исходники:</b></span></span><br />
<span style="color: #222222; font-size: large;"><span style="background-color: white;"><b><a href="https://gist.github.com/dajver/377506743dfc2342496e6feb6cbb86e5">GitHubGist</a></b></span></span></div>
</div>
dajverhttp://www.blogger.com/profile/09427222798699404442noreply@blogger.com1tag:blogger.com,1999:blog-5677605911484164185.post-63606667099704114092017-08-22T01:49:00.003+03:002017-08-22T01:51:23.472+03:00Пример работы с Dagger 2 в связке с Retrofit<div dir="ltr" style="text-align: left;" trbidi="on">
<br />
<div style="text-align: center;">
<img height="224" src="https://habrastorage.org/web/e6f/b25/e49/e6fb25e49c734f1ba0f2f8bdb5d6c43f.jpg" style="background-color: white; border-style: none; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px; height: auto; margin: 0px; max-width: 100%; vertical-align: middle;" width="400" /></div>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Написание кода меня очень увлекает и я люблю это, люблю писать всякие ништячки — программки, утилитки и т.д. Мне это доставляет удовольствие. Но иногда меня очень сильно бесит большое количество объявлений новых объектов типа </span><code style="background-color: white; box-sizing: inherit; color: #222222; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px;">Object object = new Object();</code><span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">где Object это какой-то класс объект в котором хранятся данные или еще что-то на подобии.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Как и ButterKnife, я стараюсь везде пихать и Dagger 2 который умеет красиво облегчать код и по красоте убирать лишние объявления создания новых объектов каждый раз когда нам нужно их создавать. </span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">По этой библиотеке есть очень много статей на хабре — </span><a href="https://habrahabr.ru/post/279125/" style="background-color: white; box-sizing: inherit; color: #487284; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;">раз</a><span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">, </span><a href="https://habrahabr.ru/post/279641/" style="background-color: white; box-sizing: inherit; color: #487284; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;">два</a><span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">, </span><a href="https://habrahabr.ru/post/320676/" style="background-color: white; box-sizing: inherit; color: #487284; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;">три</a><span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">, </span><a href="https://habrahabr.ru/post/307434/" style="background-color: white; box-sizing: inherit; color: #487284; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;">четыре</a><span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">, </span><a href="https://habrahabr.ru/post/334710/" style="background-color: white; box-sizing: inherit; color: #487284; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;">пять</a><span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">. По ней есть куча статей в интернете в общем — </span><a href="https://google.github.io/dagger/" style="background-color: white; box-sizing: inherit; color: #487284; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;">раз</a><span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">, </span><a href="https://guides.codepath.com/android/Dependency-Injection-with-Dagger-2" style="background-color: white; box-sizing: inherit; color: #487284; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;">два</a><span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">, </span><a href="https://medium.com/@iammert/new-android-injector-with-dagger-2-part-1-8baa60152abe" style="background-color: white; box-sizing: inherit; color: #487284; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;">три</a><span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">, но я приведу пример того как я вижу и как мне проще подключать эту библиотеку, возможно моя статья окажется лучше чем статьи те которые я нашел в интернете, так как я сходу не смог понять что да как делают в них в свое время. </span><br />
<a href="https://www.blogger.com/null" name="habracut" style="background-color: white; box-sizing: inherit; color: #548eaa; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px; text-decoration-line: underline;"></a><br />
<a name='more'></a><br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Основную базовую информацию что это, и как это можно почерпнуть из ссылок выше, там в красках описывается что такое Dagger 2, зачем он нужен, для чего его используют, кто его используют и как, там есть куча примеров как люди изгаляются и делают свой код лучше и сложнее с точки зрения новичка. Я же расскажу то как я использую его и это как по мне достаточно для того что бы заинтересовать использовать эту библиотеку. Она как минимум сокращает код, и добавляет удобность использования нужных объектов в программе. Но иногда Dagger 2 умеет выдавать кучу ошибок из-за какой-то случайно добавленной аннотации, а ошибок оно показывает такое ощущение что проект вообще написан одним местом… Но со временем привыкаешь к этому и уже не обращаешь внимания, так как по сути все проблемы в этих ошибках описываются и их очень легко решить, тем более они повторяются.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Приложение мы будем делать такое как мы уже делали в статье </span><a href="http://dajver.blogspot.com/2017/06/blog-post.html" style="background-color: white; box-sizing: inherit; color: #487284; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;">«Создаем бесконечный список с помощью RecyclerView»</a><span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">, по сути у нас тут будет код из этой статьи, почти, обернутый в обертку Dagger'a без пагинации что бы небыло лишнего кода, а то его и так дохрена из-за ретрофита будет.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">В общем для начала нам нужно подключить библиотеки для работы с Retrofit, OkHttp, RecyclerView, Dagger 2 и ButterKnife. В общем в этом проекте у нас будет дохера либ которые мы будем использовать, но тут мы уже вроде как опытные и использовали эти библиотеки все, по этому можем себе это позволить.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Вот так будет выглядеть gradle файл с зависимостями.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">app/build.gradle</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="java hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;">apply plugin: <span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">'com.android.application'</span>
android {
compileSdkVersion <span class="hljs-number" style="box-sizing: inherit; color: #986801;">25</span>
buildToolsVersion <span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"25.0.2"</span>
defaultConfig {
applicationId <span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"com.project.dajver.dagger2testexample"</span>
minSdkVersion <span class="hljs-number" style="box-sizing: inherit; color: #986801;">15</span>
targetSdkVersion <span class="hljs-number" style="box-sizing: inherit; color: #986801;">25</span>
versionCode <span class="hljs-number" style="box-sizing: inherit; color: #986801;">1</span>
versionName <span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"1.0"</span>
testInstrumentationRunner <span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"android.support.test.runner.AndroidJUnitRunner"</span>
}
buildTypes {
release {
<span class="hljs-function" style="box-sizing: inherit;">minifyEnabled <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">false</span>
proguardFiles <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">getDefaultProguardFile</span><span class="hljs-params" style="box-sizing: inherit;">(<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">'proguard-android.txt'</span>)</span>, 'proguard-rules.pro'
}
}
}
dependencies </span>{
<span class="hljs-function" style="box-sizing: inherit;">compile <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">fileTree</span><span class="hljs-params" style="box-sizing: inherit;">(dir: <span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">'libs'</span>, include: [<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">'*.jar'</span>])</span>
compile 'com.android.support:appcompat-v7:25.3.1'
compile 'com.google.dagger:dagger:2.11'
compile 'com.google.dagger:dagger-android:2.11'
annotationProcessor 'com.google.dagger:dagger-android-processor:2.11'
annotationProcessor 'com.google.dagger:dagger-compiler:2.11'
compile 'com.android.support:recyclerview-v7:25.3.1'
compile 'com.jakewharton:butterknife:8.8.1'
annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'
compile 'com.squareup.retrofit2:retrofit:2.0.1'
compile 'com.squareup.retrofit2:converter-gson:2.0.1'
compile 'com.squareup.okhttp3:logging-interceptor:3.2.0'
compile 'com.squareup.retrofit2:converter-scalars:2.0.1'
}
</span></code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Вот тут мы подключили кучу в общем библиотек я думаю для всех кто читает мои статьи это знакомый набор кроме даггера, и картина особо знакомая так как без подключения библиотек ни один проект не начнется :), я лично с этого всегда начинаю.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Дальше нам нужно добавить пермишен для доступа в интернет в AndroidManifest.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">AndroidManifest.xml</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="xml hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;"><?xml version="1.0" encoding="utf-8"?></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">manifest</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">xmlns:android</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"http://schemas.android.com/apk/res/android"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">package</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"com.project.dajver.dagger2testexample"</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">uses-permission</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:name</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"android.permission.INTERNET"</span>/></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">application</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:name</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">".App"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:allowBackup</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"true"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:icon</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@mipmap/ic_launcher"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:label</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@string/app_name"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:roundIcon</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@mipmap/ic_launcher_round"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:supportsRtl</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"true"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:theme</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@style/AppTheme"</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">activity</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:name</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">".MainActivity"</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">intent-filter</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">action</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:name</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"android.intent.action.MAIN"</span> /></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">category</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:name</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"android.intent.category.LAUNCHER"</span> /></span>
<span class="hljs-tag" style="box-sizing: inherit;"></<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">intent-filter</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"></<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">activity</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">activity</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:name</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">".SecondActivity"</span> /></span>
<span class="hljs-tag" style="box-sizing: inherit;"></<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">application</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"></<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">manifest</span>></span>
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Тут мы добавили пермишен для доступа в интернет и добавили файл App который у нас является оберткой для взаимодействия даггера с жизненным циклом приложения. Этот файл мы создадим чуть позже когда у нас будет компонент и модуль для синхронизации зависимостей.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">С первой частью мы справились, у нас подключились все нужные библиотеки и подтянулись все нужные файлы. Дальше нам нужно начать создавать магию.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Мы должны создать интерфейс с аннотацией @Compoent, в котором у нас будет объявленны активити которые мы будем использовать для взаимодействия, ну то есть активити в которых мы будем использовать Dagger 2, и будет объявление собственно модуля управляющего инъекциями в проекте.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">AppComponent.java</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="java hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> com.project.dajver.dagger2testexample.App;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> com.project.dajver.dagger2testexample.MainActivity;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> com.project.dajver.dagger2testexample.SecondActivity;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> com.project.dajver.dagger2testexample.modules.AppModule;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> javax.inject.Singleton;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> dagger.Component;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> dagger.android.AndroidInjector;
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Singleton</span>
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Component</span>(modules = { AppModule.class })
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-class" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">interface</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">AppComponent</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">extends</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">AndroidInjector</span><<span class="hljs-title" style="box-sizing: inherit; color: #c18401;">App</span>> </span>{
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">inject</span><span class="hljs-params" style="box-sizing: inherit;">(MainActivity mainActivity)</span></span>;
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">inject</span><span class="hljs-params" style="box-sizing: inherit;">(SecondActivity secondActivity)</span></span>;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">final</span> <span class="hljs-class" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">class</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">Initializer</span> </span>{
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">Initializer</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{ }
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">static</span> AppComponent <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">init</span><span class="hljs-params" style="box-sizing: inherit;">(App app)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> DaggerAppComponent.builder()
.appModule(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> AppModule(app))
.build();
}
}
}
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Вот тут видно как мы создали интерфейс, ему мы подключили модуль который мы создадим дальше, он нам нужен для управления инъекций и хранения данных. Внутри интерфейса мы добавили в инъекции две активити которые у нас будут использова Dagger. </span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Еще ниже мы создали класс Initializer который нам нужен для инициализации синглтона на весь жизненный цикл программы для Dagger'a, и в методе init проинициализировали наш модуль. Хочу заметить что у нас над @Component</span><span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;"> есть аннотация @Singlton — он нам нужен для того что бы Dagger понял что этот интерфейс нам не пересоздавать каждый раз когда мы переходим между активити, ну в общем вы поняли, типичное поведение для синглтона — раз и на всю жизнь.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">AppModule.java</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="java hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.app.Application;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> com.project.dajver.dagger2testexample.App;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> com.project.dajver.dagger2testexample.api.model.imp.FetchedDataPresenterImpl;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> javax.inject.Singleton;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> dagger.Module;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> dagger.Provides;
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Module</span>
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-class" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">class</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">AppModule</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> App app;
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">AppModule</span><span class="hljs-params" style="box-sizing: inherit;">(App application)</span> </span>{
app = application;
}
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Provides</span>
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Singleton</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">protected</span> Application <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">provideApplication</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> app;
}
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Provides</span>
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Singleton</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">protected</span> FetchedDataPresenterImpl <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">provideFetchedData</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> FetchedDataPresenterImpl();
}
}
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Этот класс нам нужен для сохранение инстанса данных, для сохранения context'a в приложении что бы мы не теряли данные при переходе между экранами и т.д. Хочу заметить аннотацию @Module</span><span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;"> — она указывает на то что этот класс мы будем использовать как модуль в котором будет храниться вся хрень касательно нашего приложения.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">В начале класса мы создали конструктор с инстансом класса App, мы его передает для сохранения контекста. Дальше мы создаем метод provideApplication() который собственно хранит наш context в приложении, и не пересоздает его каждый раз при переходах. А еще ниже у нас метод provideFetchedData() который хранит инстанс нашего класса с данными который мы создадим позже, в этом классе у нас будут хранитья данные с запроса к GitHub API.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">App.java</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="java hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.app.Application;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> com.project.dajver.dagger2testexample.components.AppComponent;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-class" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">class</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">App</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">extends</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">Application</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">static</span> AppComponent appComponent;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">static</span> App app;
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onCreate</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">super</span>.onCreate();
app = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>;
buildComponentGraph();
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">static</span> AppComponent <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">component</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> appComponent;
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">static</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">buildComponentGraph</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
appComponent = AppComponent.Initializer.init(app);
}
}
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">В этом классе мы объеденяем наш класс компонент и наш модуль, по сути тут мы создаем объект нашего модуля в компоненте с интансом контекста из Application класса.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">В общем что мы тут видим. В onCreate() мы создали инстанс нашего Application класса, и запускаем метод buildComponentGraph() который создает наш AppComponent. Это мы делаем для того что бы дальше в наших Activity могли писать вот такую хрень</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="java hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;">App.component().inject(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>);</code></pre>
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">, для того что бы Dagger понимал что в этом классе у нас будут работать инъекции и доступ к сохраненным данным в синглтоне. Дальше желательно сбилдить проект что бы Dagger создал все нужные компоненты и классы для связи всего этого в одну кучу.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Теперь когда у нас есть вот эта конструкция мы можем начать писать смело везде где мы хотим аннотацию @Inject</span><span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;"> и у нас будет создаваться нужные нам объекты классов без каких либо дополнительных new Object().</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">API.java</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="java hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> com.project.dajver.dagger2testexample.api.model.GitHubModel;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> retrofit2.Call;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> retrofit2.http.GET;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> retrofit2.http.Query;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-class" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">interface</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">API</span> </span>{
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@GET</span>(<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"search/repositories"</span>)
<span class="hljs-function" style="box-sizing: inherit;">Call<GitHubModel> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">getSearchedRepos</span><span class="hljs-params" style="box-sizing: inherit;">(@Query(<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"q"</span>)</span> String q,
@<span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">Query</span><span class="hljs-params" style="box-sizing: inherit;">(<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"page"</span>)</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> page,
@<span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">Query</span><span class="hljs-params" style="box-sizing: inherit;">(<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"per_page"</span>)</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> perPage)</span>;
}
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">В общем создали мы значит интерфейс, стандартный для работы с Retrofit, в нем прописали адрес куда будем стучаться и параметры которые будем слать. Подетальней про работу с ретрофит можно почитать </span><a href="http://dajver.blogspot.com/2017/05/retrofit.html" style="background-color: white; box-sizing: inherit; color: #487284; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;">тут</a><span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">, я особо расписывать детали не буду ибо делал это милион раз уже.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Так же у нас тут не хватает пары классов которые будут парсить респонс с сервера.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">GitHubModel.java</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="java hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> com.google.gson.annotations.Expose;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> com.google.gson.annotations.SerializedName;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> java.util.ArrayList;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> java.util.List;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-class" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">class</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">GitHubModel</span> </span>{
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@SerializedName</span>(<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"items"</span>)
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Expose</span>
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> List<GitHubItemModel> items = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> ArrayList<>();
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> List<GitHubItemModel> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">getItems</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> items;
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">setItems</span><span class="hljs-params" style="box-sizing: inherit;">(List<GitHubItemModel> items)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>.items = items;
}
}</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">GitHubItemModel.java</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="java hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> com.google.gson.annotations.Expose;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> com.google.gson.annotations.SerializedName;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-class" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">class</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">GitHubItemModel</span> </span>{
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@SerializedName</span>(<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"id"</span>)
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Expose</span>
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> Integer id;
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@SerializedName</span>(<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"name"</span>)
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Expose</span>
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> String name;
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@SerializedName</span>(<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"description"</span>)
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Expose</span>
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> String description;
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> Integer <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">getId</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> id;
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">setId</span><span class="hljs-params" style="box-sizing: inherit;">(Integer id)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>.id = id;
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> String <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">getName</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> name;
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">setName</span><span class="hljs-params" style="box-sizing: inherit;">(String name)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>.name = name;
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> String <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">getDescription</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> description;
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">setDescription</span><span class="hljs-params" style="box-sizing: inherit;">(String description)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>.description = description;
}
}
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Возвращать эти два класса нам будут список в котором будет айди, описание и название репозиториия. Этого нам хватит для примера, на деле конечно это API возвращает кучу инфы о репозитории. Дальше создадим клиент для доступа к запросам.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">RestClient.java</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="java hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> javax.inject.Inject;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> retrofit2.Retrofit;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> retrofit2.converter.gson.GsonConverterFactory;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> retrofit2.converter.scalars.ScalarsConverterFactory;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-class" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">class</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">RestClient</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">static</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">final</span> String BASE_URL = <span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"https://api.github.com/"</span>;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">final</span> API service;
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Inject</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">RestClient</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
Retrofit retrofit = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(ScalarsConverterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.build();
service = retrofit.create(API.class);
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> API <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">getService</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> service;
}
}
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Тут мы указали в BASE_URL ссылку на базовый адрес куда мы будем обращаться для получения данных с сервера. В конструкторе проинициализировали Retrofit и наш интерфейс с параметрами, и дальше ниже создали метод getService() который возвращает нам наш сервис.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Еще нам нужно создать два класса. Один — интерфейс который будет иметь три метода, а второй класс будет имплементацией этого интерфейса, в нем мы будем описывать работу этих методов.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">IFetchData.java</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="java hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> com.project.dajver.dagger2testexample.api.model.GitHubItemModel;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> com.project.dajver.dagger2testexample.api.model.GitHubModel;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> java.util.List;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-class" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">interface</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">IFetchedData</span> </span>{
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">setGitHubData</span><span class="hljs-params" style="box-sizing: inherit;">(GitHubModel data)</span></span>;
<span class="hljs-function" style="box-sizing: inherit;">List<GitHubItemModel> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">getAllData</span><span class="hljs-params" style="box-sizing: inherit;">()</span></span>;
<span class="hljs-function" style="box-sizing: inherit;">GitHubItemModel <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">getGitHubData</span><span class="hljs-params" style="box-sizing: inherit;">(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> position)</span></span>;
}
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Первый метод у нас будет сетить данные в GitHubModel, а остальные два будут возвращать нам или все данные или одну пачку по позиции из списка. Это у нас чисто интерфейс, дальше последует имплементация его и описание их функций.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Для того что бы мы могли использовать @Inject</span><span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;"> в наших активити, нам нужно всегда прописывать над конструктором класса который мы хотим использовать аннотацию @Inject</span><span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">, что бы Dagger понимал что этот класс заинъекчен уже и что бы он мог его использовать. </span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">FetchedDataPresenterImpl.java</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="java hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> com.project.dajver.dagger2testexample.api.model.GitHubItemModel;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> com.project.dajver.dagger2testexample.api.model.GitHubModel;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> java.util.List;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> javax.inject.Inject;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-class" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">class</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">FetchedDataPresenterImpl</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">implements</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">IFetchedData</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> GitHubModel gitHubModel;
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Inject</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">FetchedDataPresenterImpl</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{ }
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">setGitHubData</span><span class="hljs-params" style="box-sizing: inherit;">(GitHubModel data)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>.gitHubModel = data;
}
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> List<GitHubItemModel> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">getAllData</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> gitHubModel.getItems();
}
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> GitHubItemModel <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">getGitHubData</span><span class="hljs-params" style="box-sizing: inherit;">(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> position)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> gitHubModel.getItems().get(position);
}
}
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Как говорил выше, для того что бы мы могли заинъектить класс в активити нам нужно в конструкторе класса всегда указывать аннотацию @Inject</span><span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">. Ну и как я говорил выше, этот класс имплементация по этому тут мы описываем запись данных в GitHubModel и потом выем этих данных из него же по средством созданных из интерфейса методов.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Дальше нам нужно создать адаптер для работы с RecyclerView, в него засетим данные с нашего респонса и отобразим красоту.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">RecycleListAdapter.java</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="java hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.support.v7.widget.RecyclerView;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.view.LayoutInflater;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.view.View;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.view.ViewGroup;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.widget.TextView;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> com.project.dajver.dagger2testexample.R;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> com.project.dajver.dagger2testexample.api.model.GitHubItemModel;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> java.util.ArrayList;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> java.util.List;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> javax.inject.Inject;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> butterknife.BindView;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> butterknife.ButterKnife;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-class" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">class</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">RecycleListAdapter</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">extends</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">RecyclerView</span>.<span class="hljs-title" style="box-sizing: inherit; color: #c18401;">Adapter</span><<span class="hljs-title" style="box-sizing: inherit; color: #c18401;">RecycleListAdapter</span>.<span class="hljs-title" style="box-sizing: inherit; color: #c18401;">ViewHolder</span>></span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> List<GitHubItemModel> searchModels = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> ArrayList<>();
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> OnItemClickListener onItemClickListener;
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Inject</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">RecycleListAdapter</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{ }
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">addAll</span><span class="hljs-params" style="box-sizing: inherit;">(List<GitHubItemModel> searchModels)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>.searchModels = searchModels;
}
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> RecycleListAdapter.<span class="hljs-function" style="box-sizing: inherit;">ViewHolder <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onCreateViewHolder</span><span class="hljs-params" style="box-sizing: inherit;">(ViewGroup parent, <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> viewType)</span> </span>{
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_music, parent, <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">false</span>);
RecycleListAdapter.ViewHolder pvh = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> RecycleListAdapter.ViewHolder(v);
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> pvh;
}
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onBindViewHolder</span><span class="hljs-params" style="box-sizing: inherit;">(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">final</span> RecycleListAdapter.ViewHolder holder, <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">final</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> position)</span> </span>{
holder.title.setText(searchModels.get(position).getName());
}
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">getItemCount</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> searchModels.size();
}
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-class" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">class</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">ViewHolder</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">extends</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">RecyclerView</span>.<span class="hljs-title" style="box-sizing: inherit; color: #c18401;">ViewHolder</span> </span>{
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@BindView</span>(R.id.textView)
TextView title;
ViewHolder(View itemView) {
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">super</span>(itemView);
ButterKnife.bind(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>, itemView);
itemView.setOnClickListener(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> View.OnClickListener() {
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onClick</span><span class="hljs-params" style="box-sizing: inherit;">(View view)</span> </span>{
onItemClickListener.onItemClick(getAdapterPosition());
}
});
}
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">setOnItemClickListener</span><span class="hljs-params" style="box-sizing: inherit;">(OnItemClickListener onItemClickListener)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>.onItemClickListener = onItemClickListener;
}
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-class" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">interface</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">OnItemClickListener</span> </span>{
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onItemClick</span><span class="hljs-params" style="box-sizing: inherit;">(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> position)</span></span>;
}
}
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Вот такой адаптер, если в кратце то в методе addAll() мы добавляем данные в адаптер. В методе onCreateViewHolder() мы проинициализировали леяут с которым будем работать. В onBindViewHolder() мы засетапили данные из списка в текствью. Создали вью холдер и интерфейс который по клику кидает колбек в активити. Как-то так.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">В активити мы все это объеденим до кучи и получим рабочий код. Надеюсь до теперешного момента все понятно…</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">MainActivity.java</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="java hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.content.Intent;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.os.Bundle;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.support.v7.app.AppCompatActivity;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.support.v7.widget.DividerItemDecoration;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.support.v7.widget.LinearLayoutManager;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.support.v7.widget.RecyclerView;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> com.project.dajver.dagger2testexample.adapter.RecycleListAdapter;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> com.project.dajver.dagger2testexample.api.RestClient;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> com.project.dajver.dagger2testexample.api.model.GitHubModel;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> com.project.dajver.dagger2testexample.api.model.imp.FetchedDataPresenterImpl;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> javax.inject.Inject;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> butterknife.BindView;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> butterknife.ButterKnife;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> retrofit2.Call;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> retrofit2.Callback;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> retrofit2.Response;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">static</span> com.project.dajver.dagger2testexample.SecondActivity.EXTRA_POSITION;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-class" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">class</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">MainActivity</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">extends</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">AppCompatActivity</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">implements</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">Callback</span><<span class="hljs-title" style="box-sizing: inherit; color: #c18401;">GitHubModel</span>>,
<span class="hljs-title" style="box-sizing: inherit; color: #c18401;">RecycleListAdapter</span>.<span class="hljs-title" style="box-sizing: inherit; color: #c18401;">OnItemClickListener</span> </span>{
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@BindView</span>(R.id.recyclerView)
RecyclerView recyclerView;
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Inject</span>
RecycleListAdapter recycleListAdapter;
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Inject</span>
RestClient restClient;
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Inject</span>
FetchedDataPresenterImpl fetchedData;
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">protected</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onCreate</span><span class="hljs-params" style="box-sizing: inherit;">(Bundle savedInstanceState)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">super</span>.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>);
App.component().inject(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>);
recycleViewSetup(recyclerView);
restClient.getService().getSearchedRepos(<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"retrofit"</span>, <span class="hljs-number" style="box-sizing: inherit; color: #986801;">0</span>, <span class="hljs-number" style="box-sizing: inherit; color: #986801;">100</span>).enqueue(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>);
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">recycleViewSetup</span><span class="hljs-params" style="box-sizing: inherit;">(RecyclerView recyclerView)</span> </span>{
recyclerView.setHasFixedSize(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">true</span>);
LinearLayoutManager linearLayoutManager = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> LinearLayoutManager(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>);
linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
recyclerView.setLayoutManager(linearLayoutManager);
recyclerView.addItemDecoration(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> DividerItemDecoration(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>, DividerItemDecoration.VERTICAL));
}
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onResponse</span><span class="hljs-params" style="box-sizing: inherit;">(Call<GitHubModel> call, Response<GitHubModel> response)</span> </span>{
GitHubModel githubModel = response.body() != <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">null</span> ? response.body() : <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> GitHubModel();
fetchedData.setGitHubData(githubModel);
recycleListAdapter.addAll(fetchedData.getAllData());
recycleListAdapter.setOnItemClickListener(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>);
recyclerView.setAdapter(recycleListAdapter);
}
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onFailure</span><span class="hljs-params" style="box-sizing: inherit;">(Call<GitHubModel> call, Throwable t)</span> </span>{
t.printStackTrace();
}
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onItemClick</span><span class="hljs-params" style="box-sizing: inherit;">(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> position)</span> </span>{
Intent intent = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> Intent(MainActivity.<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>, SecondActivity.class);
intent.putExtra(EXTRA_POSITION, position);
startActivity(intent);
}
}
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">В этой активити мы заинъектили все наши нужные классы, теперь их инстанс создастся и не надо ничего создавать дополнительно, просто добавить аннотацию @Inject</span><span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;"> к названию класса.</span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Дальше в onCreate() мы прописали что мы будем использовать в этой активити ButterKnife и Dagger с помощью вызова ниже который мы создали в классе App. Так же мы тут вызываем recycleViewSetup() в который передаем RecyclerView что бы стилизовать дизайн этого списка. И делаем запрос на сервер.</span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Ниже у нас колбек ретрофита onResponse() который возвращает нам GitHubModel который мы передаем дальше в FetchedDataPresenterImpl, что бы потом можно было его использовать в других классах, и потом сетим эти данные в адаптер.</span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">onFailure() у нас выводит ошибку в лог.</span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">onItemClick() — по клику на айтем у нас идет переход на следующую активити, в которой мы будем выводить детали этого айтема по позиции в списке.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">SecondActivity.java</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="java hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.os.Bundle;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.support.v7.app.AppCompatActivity;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.widget.TextView;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> com.project.dajver.dagger2testexample.api.model.imp.FetchedDataPresenterImpl;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> javax.inject.Inject;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> butterknife.BindView;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> butterknife.ButterKnife;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-class" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">class</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">SecondActivity</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">extends</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">AppCompatActivity</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">static</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">final</span> String EXTRA_POSITION = <span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"position"</span>;
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@BindView</span>(R.id.text)
TextView text;
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Inject</span>
FetchedDataPresenterImpl fetchedData;
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">protected</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onCreate</span><span class="hljs-params" style="box-sizing: inherit;">(Bundle savedInstanceState)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">super</span>.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
ButterKnife.bind(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>);
App.component().inject(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>);
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> position = getIntent().getIntExtra(EXTRA_POSITION, <span class="hljs-number" style="box-sizing: inherit; color: #986801;">0</span>);
text.setText(<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"Name: "</span> + fetchedData.getGitHubData(position).getName() +
<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"\nDescription: "</span> + fetchedData.getGitHubData(position).getDescription());
}
}
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Ну а во втором классе мы принимаем позицию и по ней с помощью этой позиции мы достаем из FetchedDataPresenterImpl нужные нам данные. Тут как и в предыдущей активити мы прописали что будем использовать ButterKnife и Dagger который у нас проинициализирован в классе App. В общем вы должны запомнить что везде где хотите использовать Dagger вам нужно прописывать зависимость от него в виде</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="java hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;">App.component().inject(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>);</code></pre>
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">и в AppComponent добпалят инъекции к нужным экранам.</span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;"><br /></span>
<br />
<h4 style="background-color: white; color: #666666; font-family: "trebuchet ms", trebuchet, verdana, sans-serif; font-size: 13.2px; margin: 0px; position: relative;">
<b><span style="font-size: xx-small;"><span style="font-family: "verdana" , sans-serif; font-size: medium; line-height: 22.4px;">Исходники:</span></span></b></h4>
<h4 style="background-color: white; color: #666666; font-family: "trebuchet ms", trebuchet, verdana, sans-serif; font-size: 13.2px; margin: 0px; position: relative;">
<b><span style="font-size: medium;"><a href="https://github.com/dajver/Dagger2-Retrofit2-Example" style="border: 0px; color: #990099; font-family: verdana, sans-serif; line-height: 22.4px; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline;">GitHub</a></span></b></h4>
</div>
dajverhttp://www.blogger.com/profile/09427222798699404442noreply@blogger.com2tag:blogger.com,1999:blog-5677605911484164185.post-91312916291696284232017-08-20T16:56:00.001+03:002017-08-22T01:52:01.635+03:00Пишем socket эхо сервер и клиент<div dir="ltr" style="text-align: left;" trbidi="on">
<br />
<div style="text-align: center;">
<img height="192" src="https://habrastorage.org/web/408/dbe/be2/408dbebe266343feb5ab63869cd3ebbb.png" style="background-color: white; border-style: none; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px; height: auto; margin: 0px; max-width: 100%; vertical-align: middle;" width="320" /></div>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Давно не приходилось работать с сокетами, а когда приходилось как-то небыло особо сложных задач которые бы выходили за пределы того что нельзя было нагуглить. Сегодня в статье я хочу расказать про элементарнейшее из работы с сокетами, сегодня я раскажу про получение эха с сервера каждый раз когда мы отправляем туда данные. Я написал небольшой скрипт который возвращает эхо нам на запрос, и написал небольшую программку которая отправляет сообщение соккету. Дальше если захотите, можно будет сделать уже чат по этому же принципу или же какую-то работу приложения через сокеты в real-time. </span><br />
<a href="https://www.blogger.com/null" name="habracut" style="background-color: white; box-sizing: inherit; color: #548eaa; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px; text-decoration-line: underline;"></a><br />
<a name='more'></a><br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Для начала мы начнем с написания сервера. Он у нас будет написан на NodeJS и хоститься будет на Heroku. Для начала нам нужно зарегистрироваться на heroku, сделать это можно </span><a href="https://signup.heroku.com/login" style="background-color: white; box-sizing: inherit; color: #487284; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;">тут</a><span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">. Дальше после регистрации вам откроется страница помощи, на которой вам будет предложено создать первый проект в этом сервисе, если же вы случайно пропустили его то вот детальная инструкция </span><a href="https://devcenter.heroku.com/articles/getting-started-with-nodejs#introduction" style="background-color: white; box-sizing: inherit; color: #487284; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;">как настроить heroku для работы с NodeJS</a><span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">. Вся работа с heroku, заливка, деплой и т.д. происходит один в один как работа с git. Вы создаете репозиторий на heroku и потом заливаете туда ваши файлы, и сразу после заливки оно на автомате начинает деплоить то что вы залили.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Так же вам нужно настроить NodeJS на компьютере, так как перед заливкой на сервер нужно проверить код продеплоив его у себя на локальной машине, проверить рабочий ли он и работает ли он верно. Скачать его можно на официальном сайте </span><a href="https://nodejs.org/uk/" style="background-color: white; box-sizing: inherit; color: #487284; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;">тут</a><span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">. Там же есть документация на русском языке как с ним работать, вся работа работа происходит через консоль с помощью пары команд.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">После инсталяции и настройки всего этого добра давайте начнем педалить. Если вы прошли туториал после регистрации, у вас должны были остаться файлы package.json, index.js и index.html. Нам они нужны, в них мы будем писать наши команды и код. Для начала давайте рассмотрим index.js и index.html. Эти два файла у нас являются мозгом и лицом нашего сервера, в index.js мы будем принимать какое-то сообщение от клиента, и отправлять ответ ему же в виде эха — то есть то же сообщение что мы прислали. В index.html я хотел выводить то, что нам присылает сервер, но потом передумал ибо это надо сильно заморачиваться и писать много лишнего кода для рассинхронизации сокетов которые принимает сервер… По этому я оставил только эхо которое будет возвращаться обратно клиенту.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">index.js</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="hljs zephir" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">var</span> WebSocketServer = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">require</span>(<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">'ws'</span>).Server
, http = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">require</span>(<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">'http'</span>)
, express = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">require</span>(<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">'express'</span>)
, app = express()
, port = process.env.PORT || <span class="hljs-number" style="box-sizing: inherit; color: #986801;">5000</span>;
app.<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">use</span>(express.<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">static</span>(__dirname + <span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">'/'</span>));
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">var</span> server = http.createServer(app);
server.listen(port);
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">var</span> wss = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> WebSocketServer({server: server});
wss.on(<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">'connection'</span>, <span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">function</span><span class="hljs-params" style="box-sizing: inherit;">(ws)</span> </span>{
ws.on(<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">'message'</span>, <span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">function</span><span class="hljs-params" style="box-sizing: inherit;">(message)</span> </span>{
ws.send(<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"Server received: "</span> + message, <span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">function</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{ });
});
ws.on(<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">'close'</span>, <span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">function</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
console.log(<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">'websocket connection close'</span>);
});
});
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Что же у нас тут написано? Ну для начала мы подключили библиотеку ws что расшифровывается как web socket, а нужен он нам для работы с сокетами, очевидно. Дальше мы подключили библиотеку http и express для того что бы наше приложение умело работать с http и express для создания слушателя определенного порта, в нашем случае это порт 5000. </span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Ниже мы создали сервер который будет обеспечивать нам эхо и прописали наш порт который мы будем прослушивать для получения сообщений. Ниже создаем сокет и указываем какой сервер будем слушать, в нашем случае это наш heroku.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Дальше идет метод on в котором мы указываем параметер который говорит что нам делать по ws.on('connection'), я прописал в нем что мы должны принимать сообщения с помощью ws.on('message') — если они есть, и отправляем эхо обратно с приставкой «Server received:», и ws.on('close') — если мы закрыли страницу или вышли из приложения, мы отключаем в нем все наши таймеры и так далее.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Дальше дело за мордой, у нас она будет простая, но если сильно захочется можно в нее что угодно подключить, хоть целый сайт сверстать.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">index.html</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="html hljs xml" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">html</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">body</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">h1</span>></span>It's just stub for Socket Example<span class="hljs-tag" style="box-sizing: inherit;"></<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">h1</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"></<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">body</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"></<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">html</span>></span>
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Тут все тривиально, думаю даже не стоит объяснять, просто выводим текст на странице.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Ну и дальше нас интересует package.json в котором у нас указывается что компилировать, где, с какой версией и т.д. Это такой, своеобразный файл настроек сервера для компиляции.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">package.json</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="hljs json" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;">{
"<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">name</span>": <span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"socketio"</span>,
"<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">version</span>": <span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"1.0.0"</span>,
"<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">description</span>": <span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">""</span>,
"<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">main</span>": <span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"index.js"</span>,
"<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">scripts</span>": {
"<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">test</span>": <span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"echo \"Error: no test specified\" && exit 1"</span>,
"<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">start</span>" : <span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"node index.js"</span>
},
"<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">author</span>": <span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"inampaki"</span>,
"<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">license</span>": <span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"ISC"</span>,
"<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">dependencies</span>": {
"<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">express</span>": <span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"^4.13.3"</span>,
"<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">express-ws</span>": <span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"^0.2.6"</span>,
"<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">socket.io</span>": <span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"^1.3.7"</span>
}
}
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Подключаем socketio для работы с сокетами, указываем версию и какой файл нам компилировать этой библиотекой. </span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Дальше загружаем это все на хероку.</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="hljs sql" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;">git add .
git <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">commit</span> -<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">m</span> <span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">'some comment to commit here'</span>
git push heroku <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">master</span>
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Дальше вы должны увидеть долгую и длинную простыню команд которые будут деплоить ваш код на сервере, и в итоге это все должно кончится и вы должны увидеть что-то на подобии такого.</span><br />
<div style="text-align: center;">
<img height="419" src="https://habrastorage.org/web/b9a/8e2/bd2/b9a8e2bd281141b6bcd50f2ef13ff014.png" style="background-color: white; border-style: none; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px; height: auto; margin: 0px; max-width: 100%; vertical-align: middle;" width="640" /></div>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">После этого всего написав в командной строке </span><code style="background-color: white; box-sizing: inherit; color: #222222; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px;">heroku open</code><span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">, вы должны увидеть надпись «It's just stub for Socket Example» которая у нас была прописана в index.html. Если же этого нету значит где-то какая-то ошибка, подеплойте код на компютере, с помощью команды </span><code style="background-color: white; box-sizing: inherit; color: #222222; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px;">node index.js</code><span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">, оно покажет вам ошибки или же скомпилирует и запустит сервер.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Дальше нам нужно написать программу, она у нас будет очень простой — один экран на нем одно поле для ввода и кнопка для отправки сообщений, и ниже текстовое поле которое будет выводить эхо с сервера.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">После создания проекта нам нужно подключить несколько библиотек, первая по старинке это ButterKnife, я как вы поняли везде ее пихаю, а вторая SocketIO которая помогает работать с сокетами.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">app/build.gradle</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="java hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;">apply plugin: <span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">'com.android.application'</span>
android {
compileSdkVersion <span class="hljs-number" style="box-sizing: inherit; color: #986801;">23</span>
buildToolsVersion <span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">'25.0.0'</span>
defaultConfig {
applicationId <span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"test.socket.app"</span>
minSdkVersion <span class="hljs-number" style="box-sizing: inherit; color: #986801;">15</span>
targetSdkVersion <span class="hljs-number" style="box-sizing: inherit; color: #986801;">23</span>
versionCode <span class="hljs-number" style="box-sizing: inherit; color: #986801;">1</span>
versionName <span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"1.0"</span>
}
buildTypes {
release {
<span class="hljs-function" style="box-sizing: inherit;">minifyEnabled <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">false</span>
proguardFiles <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">getDefaultProguardFile</span><span class="hljs-params" style="box-sizing: inherit;">(<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">'proguard-android.txt'</span>)</span>, 'proguard-rules.pro'
}
}
}
dependencies </span>{
<span class="hljs-function" style="box-sizing: inherit;">compile <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">fileTree</span><span class="hljs-params" style="box-sizing: inherit;">(dir: <span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">'libs'</span>, include: [<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">'*.jar'</span>])</span>
compile 'com.android.support:appcompat-v7:23.1.0'
compile 'com.jakewharton:butterknife:8.8.1'
annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'
compile 'com.github.nkzawa:socket.io-client:0.3.0'
}
</span></code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Вот такая фигня. Библиотеки мы подключили, теперь еще надо добавить в манифест пермишен для доступа в интернет.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">AndroidManifest.xml</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="xml hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;"><?xml version="1.0" encoding="utf-8"?></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">manifest</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">xmlns:android</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"http://schemas.android.com/apk/res/android"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">package</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"test.socket.app"</span> ></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">uses-permission</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:name</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"android.permission.INTERNET"</span> /></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">uses-permission</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:name</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"android.permission.ACCESS_NETWORK_STATE"</span> /></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">application</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:allowBackup</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"true"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:icon</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@mipmap/ic_launcher"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:label</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@string/app_name"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:supportsRtl</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"true"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:theme</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@style/AppTheme"</span> ></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">activity</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:name</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">".MainActivity"</span> ></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">intent-filter</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">action</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:name</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"android.intent.action.MAIN"</span> /></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">category</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:name</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"android.intent.category.LAUNCHER"</span> /></span>
<span class="hljs-tag" style="box-sizing: inherit;"></<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">intent-filter</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"></<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">activity</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"></<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">application</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"></<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">manifest</span>></span>
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Тут как видно мы добавили два пермишена, первый для доступа в интернет, а второй на проверку доступа к сети в интернет.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Дальше давайте рассмотрим разметку нашей activity_main.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">activity_main.xml</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="xml hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;"><?xml version="1.0" encoding="utf-8"?></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">RelativeLayout</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">xmlns:android</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"http://schemas.android.com/apk/res/android"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">xmlns:tools</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"http://schemas.android.com/tools"</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_width</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_height</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"match_parent"</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:paddingLeft</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@dimen/activity_horizontal_margin"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:paddingRight</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@dimen/activity_horizontal_margin"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:paddingTop</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@dimen/activity_vertical_margin"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:paddingBottom</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@dimen/activity_vertical_margin"</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">tools:context</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">".MainActivity"</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">Button</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:id</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@+id/button"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_width</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"wrap_content"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_height</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"wrap_content"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_centerHorizontal</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"true"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_centerVertical</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"true"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:onClick</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"onSendClick"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:text</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"send"</span> /></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">TextView</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_width</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"wrap_content"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_height</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"wrap_content"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:textAppearance</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"?android:attr/textAppearanceLarge"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:text</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"Large Text"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:id</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@+id/textView"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_below</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@+id/button"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_centerHorizontal</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"true"</span> /></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">EditText</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_width</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_height</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"wrap_content"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:id</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@+id/editText"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_above</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@+id/button"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_centerHorizontal</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"true"</span> /></span>
<span class="hljs-tag" style="box-sizing: inherit;"></<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">RelativeLayout</span>></span>
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Как я и писал выше, у нас тут будет три элемента, edittext, textview и кнопка. Далее опишем их работу этих элементов в нашей активити.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px; font-weight: bolder;">MainActivity.java</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="java hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.os.Build;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.os.Bundle;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.support.v7.app.AppCompatActivity;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.util.Log;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.widget.EditText;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.widget.TextView;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> org.java_websocket.client.WebSocketClient;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> org.java_websocket.handshake.ServerHandshake;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> java.net.URI;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> java.net.URISyntaxException;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> butterknife.BindView;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> butterknife.ButterKnife;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> butterknife.OnClick;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-class" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">class</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">MainActivity</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">extends</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">AppCompatActivity</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">static</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">final</span> String HOST = <span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"ws://stark-caverns-76076.herokuapp.com"</span>;
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@BindView</span>(R.id.editText)
EditText editText;
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@BindView</span>(R.id.textView)
TextView textView;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> WebSocketClient mWebSocketClient;
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">protected</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onCreate</span><span class="hljs-params" style="box-sizing: inherit;">(Bundle savedInstanceState)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">super</span>.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>);
connectWebSocket();
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">connectWebSocket</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">try</span> {
URI uri = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> URI(HOST);
mWebSocketClient = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> WebSocketClient(uri) {
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onOpen</span><span class="hljs-params" style="box-sizing: inherit;">(ServerHandshake serverHandshake)</span> </span>{
mWebSocketClient.send(<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"Connecting from "</span> + Build.MANUFACTURER + <span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">" "</span> + Build.MODEL);
}
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onMessage</span><span class="hljs-params" style="box-sizing: inherit;">(String s)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">final</span> String message = s;
runOnUiThread(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> Runnable() {
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">run</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
textView.setText(message);
}
});
}
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onClose</span><span class="hljs-params" style="box-sizing: inherit;">(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> i, String s, <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">boolean</span> b)</span> </span>{
Log.i(<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"Websocket"</span>, <span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"Connection Closed "</span> + s);
}
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onError</span><span class="hljs-params" style="box-sizing: inherit;">(Exception e)</span> </span>{
e.printStackTrace();
}
};
mWebSocketClient.connect();
} <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">catch</span> (URISyntaxException e) {
e.printStackTrace();
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span>;
}
}
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@OnClick</span>(R.id.button)
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onSendClick</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">if</span>(!mWebSocketClient.getConnection().isClosed()) {
mWebSocketClient.send(editText.getText().toString());
editText.setText(<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">""</span>);
} <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">else</span> {
connectWebSocket();
}
}
}
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">И что же мы тут имеем. Для начала мы указываем хост к которому будем подключаться для отправки сообщений и получения эха, он у нас вот такой — ws://stark-caverns-76076.herokuapp.com, я его менять в дальнейшем не буду, так что он будет я так думаю вечный, пока хероку не отключит нас.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">В onCreate() мы проинициализировали layout, указали что запускаем сокет с помощью метода connectWebSocket(), в нем мы создали путь к которому будем стучаться, дальше создаем объект класса WebSocket и указываем путь, а дальше создаем колбеки которые будут нам возвращать какие-то состояния. </span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">В методе onOpen() по открытию сокета мы отправляем серверу что за девайс подключился и что за система у него. </span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">В onMessage() мы принимаем сообщения с сервера и отображаем в textView. </span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">В onClose() мы просто закрываем все что у нас открыто касательно сокетов.</span><br />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Ну и onError() возвращает ошибки сервера.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Дальше мы вызываем метод подключения к серверу, и воаля, у нас есть все для подключения к серверу. Осталось написать метод отправки сообщений, а он у нас ниже в клике по кнопке — onSendClick(). </span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, Arial, sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "arial" , sans-serif; font-size: 16px;">Вот собственно и все что нам нужно для написания приложения с сокетами. Дальше остается только реализовывать то что желает душа, что на сервере что на клиенте. Основной код готов к употреблению.</span><br />
<br />
<div>
<h4 style="background-color: white; color: #666666; font-family: "trebuchet ms", trebuchet, verdana, sans-serif; font-size: 13.2px; margin: 0px; position: relative;">
<b><span style="font-size: xx-small;"><span style="font-family: "verdana" , sans-serif; font-size: medium; line-height: 22.4px;">Исходники:</span></span></b></h4>
<h4 style="background-color: white; color: #666666; font-family: "trebuchet ms", trebuchet, verdana, sans-serif; font-size: 13.2px; margin: 0px; position: relative;">
<b><span style="font-size: medium;"><a href="https://github.com/dajver/WorkingSocketsExample" style="border: 0px; color: #990099; font-family: verdana, sans-serif; line-height: 22.4px; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline;">GitHub</a></span></b></h4>
</div>
</div>
dajverhttp://www.blogger.com/profile/09427222798699404442noreply@blogger.com0tag:blogger.com,1999:blog-5677605911484164185.post-32542295368234612302017-08-15T16:21:00.003+03:002017-08-15T16:38:30.019+03:00Пример написания большой пульсирующей кнопки<div dir="ltr" style="text-align: left;" trbidi="on">
<span style="background-color: white; color: #222222; font-family: , , "segoe ui" , "roboto" , "oxygen" , "ubuntu" , "cantarell" , "fira sans" , "droid sans" , "helvetica neue" , sans-serif; font-size: 16px;">Бывает, заказчики хотят чего-то уникального, чего нету у других, в основном это касается или каких-то кнопок или текствьюх или чего-то стандартного в не стандартной оболочке. Вот и мне как-то довелось с таким встретиться. Заказчик захотел что бы кнопка пульсировала для привлечения внимания и имела ripple эффект во время клика, в принципе ничего такое, это уже есть реализованное в множественном виде, но именно так как он хотел я не нашел, да и тогда когда я это делал еще небыло особо делать популярно такие кнопки в приложениях.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; font-size: 16px;" />
<div style="text-align: center;">
<img src="https://habrastorage.org/web/c36/eab/1ba/c36eab1ba2894d3195607ced1cc06b2d.gif" style="background-color: white; border-style: none; box-sizing: inherit; color: #222222; font-size: 16px; height: auto; margin: 0px; max-width: 100%; vertical-align: middle;" /></div>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "segoe ui" , "roboto" , "oxygen" , "ubuntu" , "cantarell" , "fira sans" , "droid sans" , "helvetica neue" , sans-serif; font-size: 16px;">У меня уже были наработки в этой сфере, я делал когда то кнопку у которой волны расходились как на воде по периметру круглой кнопки. Но это было не совсем то, по этому пришлось немного вспомнить математику и покрутить извилинами.</span><br />
<a href="https://www.blogger.com/null" name="habracut" style="background-color: white; box-sizing: inherit; color: #548eaa; font-family: -apple-system, system-ui, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; font-size: 16px; text-decoration-line: underline;"></a><br />
<a name='more'></a><br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "segoe ui" , "roboto" , "oxygen" , "ubuntu" , "cantarell" , "fira sans" , "droid sans" , "helvetica neue" , sans-serif; font-size: 16px;">Кнопка будет состоять у нас из двух вьюх — PulsingButtonBackground и PulsingButtonTextView и одной объеденяющей эти две вьюхи вьюхой — PulsingButtonView, ее мы будем использовать как кнопку собственно в активити.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "segoe ui" , "roboto" , "oxygen" , "ubuntu" , "cantarell" , "fira sans" , "droid sans" , "helvetica neue" , sans-serif; font-size: 16px;">По традиции будем использовать ButterKnife в проекте, так что советую добавить две строчки </span><a href="http://jakewharton.github.io/butterknife/" style="background-color: white; box-sizing: inherit; color: #487284; font-family: -apple-system, system-ui, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; font-size: 16px;">как написано тут в секции Download</a><span style="background-color: white; color: #222222; font-family: , , "segoe ui" , "roboto" , "oxygen" , "ubuntu" , "cantarell" , "fira sans" , "droid sans" , "helvetica neue" , sans-serif; font-size: 16px;"> в app/build.gradle в секцию dependencies, у меня она выглядит вот так:</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "segoe ui" , "roboto" , "oxygen" , "ubuntu" , "cantarell" , "fira sans" , "droid sans" , "helvetica neue" , sans-serif; font-size: 16px; font-weight: bolder;">app/build.gradle</span><br />
<br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="java hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;">dependencies {
<span class="hljs-function" style="box-sizing: inherit;">compile <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">fileTree</span><span class="hljs-params" style="box-sizing: inherit;">(dir: <span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">'libs'</span>, include: [<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">'*.jar'</span>])</span>
compile 'com.android.support:appcompat-v7:25.3.1'
compile 'com.jakewharton:butterknife:8.8.1'
annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'
}</span></code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "segoe ui" , "roboto" , "oxygen" , "ubuntu" , "cantarell" , "fira sans" , "droid sans" , "helvetica neue" , sans-serif; font-size: 16px;">Дальше мы начнем с фона, то есть с PulsingButtonBackground в которой у нас будет код пульсирования самой кнопки, тоненького фона как на фоне, и еще после нажатия у нас будет появляться ripple эффект.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "segoe ui" , "roboto" , "oxygen" , "ubuntu" , "cantarell" , "fira sans" , "droid sans" , "helvetica neue" , sans-serif; font-size: 16px; font-weight: bolder;">PulsingButtonBackground.java</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="java hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.animation.Animator;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.animation.AnimatorListenerAdapter;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.animation.AnimatorSet;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.animation.ValueAnimator;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.content.Context;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.graphics.Canvas;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.graphics.Color;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.graphics.Paint;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.os.Handler;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.support.annotation.NonNull;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.util.AttributeSet;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.view.MotionEvent;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.view.View;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.view.animation.DecelerateInterpolator;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> com.project.dajver.pulsingbutton.R;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-class" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">class</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">PulsingButtonBackground</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">extends</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">View</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> Paint solidPaint;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> Paint strokePaint;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> Paint ripplePaint;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">float</span> solidMultiplier;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">float</span> strokeMultiplier;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">float</span> duration = <span class="hljs-number" style="box-sizing: inherit; color: #986801;">150</span>;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> frameRate = <span class="hljs-number" style="box-sizing: inherit; color: #986801;">15</span>;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">float</span> speed = <span class="hljs-number" style="box-sizing: inherit; color: #986801;">1</span>;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">float</span> rippleRadius = <span class="hljs-number" style="box-sizing: inherit; color: #986801;">0</span>;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">float</span> endRippleRadius = <span class="hljs-number" style="box-sizing: inherit; color: #986801;">0</span>;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">float</span> rippleX = <span class="hljs-number" style="box-sizing: inherit; color: #986801;">0</span>;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">float</span> rippleY = <span class="hljs-number" style="box-sizing: inherit; color: #986801;">0</span>;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> width = <span class="hljs-number" style="box-sizing: inherit; color: #986801;">0</span>;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> height = <span class="hljs-number" style="box-sizing: inherit; color: #986801;">0</span>;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> touchAction;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> Handler handler = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> Handler();
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">PulsingButtonBackground</span><span class="hljs-params" style="box-sizing: inherit;">(Context context)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">super</span>(context);
initialize();
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">PulsingButtonBackground</span><span class="hljs-params" style="box-sizing: inherit;">(Context context, AttributeSet attrs)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">super</span>(context, attrs);
initialize();
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">PulsingButtonBackground</span><span class="hljs-params" style="box-sizing: inherit;">(Context context, AttributeSet attrs, <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> defStyleAttr)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">super</span>(context, attrs, defStyleAttr);
initialize();
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">initialize</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
solidPaint = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> Paint();
solidPaint.setColor(getResources().getColor(R.color.colorPrimary));
solidPaint.setAntiAlias(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">true</span>);
strokePaint = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> Paint();
strokePaint.setColor(getResources().getColor(R.color.colorPrimary));
strokePaint.setStyle(Paint.Style.STROKE);
strokePaint.setStrokeWidth(getResources().getDimension(R.dimen.ring_width));
strokePaint.setAntiAlias(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">true</span>);
ripplePaint = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> Paint();
ripplePaint.setColor(Color.WHITE);
ripplePaint.setAlpha(<span class="hljs-number" style="box-sizing: inherit; color: #986801;">51</span>);
ripplePaint.setAntiAlias(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">true</span>);
resetAnimatedValues();
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> Animator <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">getAnimator</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
AnimatorSet animatorSet = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> AnimatorSet();
animatorSet.playTogether(getSolidAnimator(), getStrokeAnimator(), getStrokeAlphaAnimator(), getRefreshAnimator());
animatorSet.addListener(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> AnimatorListenerAdapter() {
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onAnimationStart</span><span class="hljs-params" style="box-sizing: inherit;">(Animator animation)</span> </span>{
resetAnimatedValues();
}
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onAnimationCancel</span><span class="hljs-params" style="box-sizing: inherit;">(Animator animation)</span> </span>{
resetAnimatedValues();
invalidate();
}
});
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> animatorSet;
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">resetAnimatedValues</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
solidMultiplier = <span class="hljs-number" style="box-sizing: inherit; color: #986801;">1.0f</span>;
strokeMultiplier = <span class="hljs-number" style="box-sizing: inherit; color: #986801;">1.0f</span>;
strokePaint.setAlpha(<span class="hljs-number" style="box-sizing: inherit; color: #986801;">0</span>);
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> Animator <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">getSolidAnimator</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
ValueAnimator solidShrink = ValueAnimator.ofFloat(<span class="hljs-number" style="box-sizing: inherit; color: #986801;">1.0f</span>, <span class="hljs-number" style="box-sizing: inherit; color: #986801;">0.96f</span>).setDuration(<span class="hljs-number" style="box-sizing: inherit; color: #986801;">250</span>);
solidShrink.addUpdateListener(mSolidUpdateListener);
ValueAnimator solidGrow = ValueAnimator.ofFloat(<span class="hljs-number" style="box-sizing: inherit; color: #986801;">0.96f</span>, <span class="hljs-number" style="box-sizing: inherit; color: #986801;">1.0f</span>).setDuration(<span class="hljs-number" style="box-sizing: inherit; color: #986801;">450</span>);
solidGrow.addUpdateListener(mSolidUpdateListener);
solidGrow.setInterpolator(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> DecelerateInterpolator());
AnimatorSet solidAnimation = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> AnimatorSet();
solidAnimation.playSequentially(solidShrink, solidGrow);
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> solidAnimation;
}
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> ValueAnimator.AnimatorUpdateListener mSolidUpdateListener = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> ValueAnimator.AnimatorUpdateListener() {
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onAnimationUpdate</span><span class="hljs-params" style="box-sizing: inherit;">(ValueAnimator valueAnimator)</span> </span>{
solidMultiplier = (<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">float</span>) valueAnimator.getAnimatedValue();
}
};
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> Animator <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">getStrokeAnimator</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
ValueAnimator strokeGrow = ValueAnimator.ofFloat(<span class="hljs-number" style="box-sizing: inherit; color: #986801;">0.80f</span>, <span class="hljs-number" style="box-sizing: inherit; color: #986801;">1.1f</span>).setDuration(<span class="hljs-number" style="box-sizing: inherit; color: #986801;">800</span>);
strokeGrow.addUpdateListener(mStrokeUpdateListener);
strokeGrow.setInterpolator(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> DecelerateInterpolator());
strokeGrow.setStartDelay(<span class="hljs-number" style="box-sizing: inherit; color: #986801;">250</span>);
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> strokeGrow;
}
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> ValueAnimator.AnimatorUpdateListener mStrokeUpdateListener = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> ValueAnimator.AnimatorUpdateListener() {
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onAnimationUpdate</span><span class="hljs-params" style="box-sizing: inherit;">(ValueAnimator valueAnimator)</span> </span>{
strokeMultiplier = (<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">float</span>) valueAnimator.getAnimatedValue();
}
};
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> Animator <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">getStrokeAlphaAnimator</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
ValueAnimator alphaAnimator = ValueAnimator.ofInt(<span class="hljs-number" style="box-sizing: inherit; color: #986801;">255</span>, <span class="hljs-number" style="box-sizing: inherit; color: #986801;">0</span>).setDuration(<span class="hljs-number" style="box-sizing: inherit; color: #986801;">650</span>);
alphaAnimator.addUpdateListener(mStrokeAlphaUpdateListener);
alphaAnimator.addListener(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> AnimatorListenerAdapter() {
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onAnimationStart</span><span class="hljs-params" style="box-sizing: inherit;">(Animator animation)</span> </span>{
strokePaint.setAlpha(<span class="hljs-number" style="box-sizing: inherit; color: #986801;">255</span>);
}
});
alphaAnimator.setStartDelay(<span class="hljs-number" style="box-sizing: inherit; color: #986801;">500</span>);
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> alphaAnimator;
}
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> ValueAnimator.AnimatorUpdateListener mStrokeAlphaUpdateListener = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> ValueAnimator.AnimatorUpdateListener() {
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onAnimationUpdate</span><span class="hljs-params" style="box-sizing: inherit;">(ValueAnimator valueAnimator)</span> </span>{
strokePaint.setAlpha((<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span>) valueAnimator.getAnimatedValue());
}
};
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> Animator <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">getRefreshAnimator</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
ValueAnimator refreshAnimator = ValueAnimator.ofFloat(<span class="hljs-number" style="box-sizing: inherit; color: #986801;">0.0f</span>, <span class="hljs-number" style="box-sizing: inherit; color: #986801;">1.0f</span>).setDuration(<span class="hljs-number" style="box-sizing: inherit; color: #986801;">1200</span>);
refreshAnimator.addUpdateListener(mRefreshUpdateListener);
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> refreshAnimator;
}
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> ValueAnimator.AnimatorUpdateListener mRefreshUpdateListener = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> ValueAnimator.AnimatorUpdateListener() {
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onAnimationUpdate</span><span class="hljs-params" style="box-sizing: inherit;">(ValueAnimator valueAnimator)</span> </span>{
invalidate();
}
};
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">protected</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onDraw</span><span class="hljs-params" style="box-sizing: inherit;">(Canvas canvas)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> width = canvas.getWidth();
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">float</span> halfWidth = width / <span class="hljs-number" style="box-sizing: inherit; color: #986801;">2.0f</span>;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">float</span> solidHalfWidth = halfWidth * solidMultiplier;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">float</span> strokeHalfWidth = halfWidth * strokeMultiplier;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> height = canvas.getHeight();
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">float</span> halfHeight = height / <span class="hljs-number" style="box-sizing: inherit; color: #986801;">2.0f</span>;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">float</span> solidHalfHeight = halfHeight * solidMultiplier;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">float</span> strokeHalfHeight = halfHeight * strokeMultiplier;
canvas.drawARGB(<span class="hljs-number" style="box-sizing: inherit; color: #986801;">0</span>, <span class="hljs-number" style="box-sizing: inherit; color: #986801;">0</span>, <span class="hljs-number" style="box-sizing: inherit; color: #986801;">0</span>, <span class="hljs-number" style="box-sizing: inherit; color: #986801;">0</span>);
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">double</span> strokeRadius = <span class="hljs-number" style="box-sizing: inherit; color: #986801;">0.515</span> * Math.sqrt(strokeHalfWidth * strokeHalfWidth + strokeHalfHeight * strokeHalfHeight);
canvas.drawCircle(halfWidth, halfHeight, (<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">float</span>) strokeRadius, strokePaint);
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">double</span> solidRadius = <span class="hljs-number" style="box-sizing: inherit; color: #986801;">0.5</span> * Math.sqrt(solidHalfWidth * solidHalfWidth + solidHalfHeight * solidHalfHeight);
canvas.drawCircle(halfWidth, halfHeight, (<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">float</span>) solidRadius, solidPaint);
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">if</span>(rippleRadius > <span class="hljs-number" style="box-sizing: inherit; color: #986801;">0</span> && rippleRadius < endRippleRadius) {
canvas.drawCircle(rippleX, rippleY, rippleRadius, ripplePaint);
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">if</span>(touchAction == MotionEvent.ACTION_UP) {
invalidate();
}
}
}
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">boolean</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onTouchEvent</span><span class="hljs-params" style="box-sizing: inherit;">(@NonNull MotionEvent event)</span> </span>{
rippleX = event.getX();
rippleY = event.getY();
touchAction = event.getAction();
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">switch</span>(event.getAction()) {
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">case</span> MotionEvent.ACTION_UP: {
getParent().requestDisallowInterceptTouchEvent(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">false</span>);
rippleRadius = <span class="hljs-number" style="box-sizing: inherit; color: #986801;">1</span>;
endRippleRadius = Math.max(Math.max(Math.max(width - rippleX, rippleX), rippleY), height - rippleY);
speed = endRippleRadius / duration * frameRate;
handler.postDelayed(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> Runnable() {
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">run</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">if</span>(rippleRadius < endRippleRadius) {
rippleRadius += speed;
ripplePaint.setAlpha(<span class="hljs-number" style="box-sizing: inherit; color: #986801;">90</span> - (<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span>) (rippleRadius / endRippleRadius * <span class="hljs-number" style="box-sizing: inherit; color: #986801;">90</span>));
handler.postDelayed(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>, frameRate);
}
}
}, frameRate);
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">break</span>;
}
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">case</span> MotionEvent.ACTION_CANCEL: {
getParent().requestDisallowInterceptTouchEvent(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">false</span>);
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">break</span>;
}
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">case</span> MotionEvent.ACTION_DOWN: {
getParent().requestDisallowInterceptTouchEvent(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">true</span>);
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">true</span>;
}
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">case</span> MotionEvent.ACTION_MOVE: {
rippleRadius = <span class="hljs-number" style="box-sizing: inherit; color: #986801;">0</span>;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">if</span>(rippleX < <span class="hljs-number" style="box-sizing: inherit; color: #986801;">0</span> || rippleX > width || rippleY < <span class="hljs-number" style="box-sizing: inherit; color: #986801;">0</span> || rippleY > height) {
getParent().requestDisallowInterceptTouchEvent(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">false</span>);
touchAction = MotionEvent.ACTION_CANCEL;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">break</span>;
} <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">else</span> {
invalidate();
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">true</span>;
}
}
}
invalidate();
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">false</span>;
}
}
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "segoe ui" , "roboto" , "oxygen" , "ubuntu" , "cantarell" , "fira sans" , "droid sans" , "helvetica neue" , sans-serif; font-size: 16px;">И так что же у нас тут по порядку.</span><br />
<span style="background-color: white; color: #222222; font-family: , , "segoe ui" , "roboto" , "oxygen" , "ubuntu" , "cantarell" , "fira sans" , "droid sans" , "helvetica neue" , sans-serif; font-size: 16px;">В шапке класса мы задали кучу переменных, переменные которые являются объектами Paint у нас будут использоваться для задавания стиля той или иной части кнопки. Переменные solidMultiplier и strokeMultiplier мы будем использовать для создания эффекта движения кнопки, слоя с тонкими гранями и слоя с основной кнопкой. Все остальные переменные мы будем использовать для создания ripple эффекта, а это скорость, радиус и т.д. Еще чуть ниже мы проинициализировали Handler, он нам понадобится для создания анимации нажатия на кнопку и ripple эффекта.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "segoe ui" , "roboto" , "oxygen" , "ubuntu" , "cantarell" , "fira sans" , "droid sans" , "helvetica neue" , sans-serif; font-size: 16px;">Дальше у нас идут конструкторы в которых мы вызываем метод инициализации наши Paint переменных, задаем толщину линий, цвет, прозрачность и тип.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "segoe ui" , "roboto" , "oxygen" , "ubuntu" , "cantarell" , "fira sans" , "droid sans" , "helvetica neue" , sans-serif; font-size: 16px;">Дальше у нас идет метод getAnimator() который создает объект AnimatorSet с колбеком который вызывает метод который «обнуляет» все параметры, это мы делаем для того что бы у нас анимация циклилась и проигрывалась бесконечно.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "segoe ui" , "roboto" , "oxygen" , "ubuntu" , "cantarell" , "fira sans" , "droid sans" , "helvetica neue" , sans-serif; font-size: 16px;">Ниже идет метод resetAnimatedValues() который мы вызываем для обнуления анимации что бы она начинала играть с начала.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "segoe ui" , "roboto" , "oxygen" , "ubuntu" , "cantarell" , "fira sans" , "droid sans" , "helvetica neue" , sans-serif; font-size: 16px;">Еще ниже идет метод getSolidAnimator() который мы используем для создания анимации для главного круга который у нас является кнопкой с залитым фоном. В нем мы задаем продолжительность проигрывания анимации, колбеки в которых у нас обновляется анимация и т.д.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "segoe ui" , "roboto" , "oxygen" , "ubuntu" , "cantarell" , "fira sans" , "droid sans" , "helvetica neue" , sans-serif; font-size: 16px;">Чуть ниже у нас идет лисенер в котором мы обновляем анимацию с нужной продолжительностью которую мы задали в методе вышел.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "segoe ui" , "roboto" , "oxygen" , "ubuntu" , "cantarell" , "fira sans" , "droid sans" , "helvetica neue" , sans-serif; font-size: 16px;">То же самое у нас в методах getStrokeAnimator(), getStrokeAlphaAnimator() и getRefreshAnimator и с их колбеками, они повторяют почти те же самые функции просто немного с разными параметрами.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "segoe ui" , "roboto" , "oxygen" , "ubuntu" , "cantarell" , "fira sans" , "droid sans" , "helvetica neue" , sans-serif; font-size: 16px;">А вот дальше начинается интересное, у нас есть метод onDraw() который мы используем для отрисовки всех элементов. В начале этого класса мы проводим нетривиальные математические операции для выведения нужных нам параметров для рисования кнопки и обводки для нее, плюс тут же мы просчитываем пульс анимации умножая halfWidth на strokeMultiplier для получения высоты нашего круга который будет обрамлять наш основной круг кнопки.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "segoe ui" , "roboto" , "oxygen" , "ubuntu" , "cantarell" , "fira sans" , "droid sans" , "helvetica neue" , sans-serif; font-size: 16px;">Дальше мы расчитываем радиус нашего круга судя из высоты и ширины обрамляющей вьюхи. И создаем круг. Так же делаем еще раз чуть ниже только для цельного круга. А еще ниже у нас идет проверка на отрисовку ripple эффекта. Эта проверка нам нужна для того что бы наш экран чистился когда нажатие было окончено и радиус был достигнут своего предела.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "segoe ui" , "roboto" , "oxygen" , "ubuntu" , "cantarell" , "fira sans" , "droid sans" , "helvetica neue" , sans-serif; font-size: 16px;">А в самом низу класса идет метод onTouchEvent(). В нем мы отслеживаем нажатия на вьюхе и в зависимости от нажатия рисуем наш ripple эффект на ней. </span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "segoe ui" , "roboto" , "oxygen" , "ubuntu" , "cantarell" , "fira sans" , "droid sans" , "helvetica neue" , sans-serif; font-size: 16px;">Еще у нас тут используется один параметер для установки ширины слоя обводки. Так вот он у нас находится в файле dimens. </span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "segoe ui" , "roboto" , "oxygen" , "ubuntu" , "cantarell" , "fira sans" , "droid sans" , "helvetica neue" , sans-serif; font-size: 16px; font-weight: bolder;">dimens.xml</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="xml hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">dimen</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">name</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"ring_width"</span>></span>2dp<span class="hljs-tag" style="box-sizing: inherit;"></<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">dimen</span>></span></code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "segoe ui" , "roboto" , "oxygen" , "ubuntu" , "cantarell" , "fira sans" , "droid sans" , "helvetica neue" , sans-serif; font-size: 16px;">С этим классом мы закончили, теперь давайте рассмотрим класс PulsingButtonTextView который мы будем использовать для отображения текста на кнопке.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "segoe ui" , "roboto" , "oxygen" , "ubuntu" , "cantarell" , "fira sans" , "droid sans" , "helvetica neue" , sans-serif; font-size: 16px; font-weight: bolder;">PulsingButtonTextView.java</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="java hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.animation.Animator;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.animation.AnimatorListenerAdapter;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.animation.AnimatorSet;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.animation.ValueAnimator;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.content.Context;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.util.AttributeSet;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-class" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">class</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">PulsingButtonTextView</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">extends</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">android</span>.<span class="hljs-title" style="box-sizing: inherit; color: #c18401;">support</span>.<span class="hljs-title" style="box-sizing: inherit; color: #c18401;">v7</span>.<span class="hljs-title" style="box-sizing: inherit; color: #c18401;">widget</span>.<span class="hljs-title" style="box-sizing: inherit; color: #c18401;">AppCompatTextView</span> </span>{
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">PulsingButtonTextView</span><span class="hljs-params" style="box-sizing: inherit;">(Context context)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">super</span>(context);
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">PulsingButtonTextView</span><span class="hljs-params" style="box-sizing: inherit;">(Context context, AttributeSet attrs)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">super</span>(context, attrs);
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">PulsingButtonTextView</span><span class="hljs-params" style="box-sizing: inherit;">(Context context, AttributeSet attrs, <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> defStyleAttr)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">super</span>(context, attrs, defStyleAttr);
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> Animator <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">getAnimator</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
AnimatorSet animatorSet = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> AnimatorSet();
animatorSet.playTogether(getTextAnimator(), getRefreshAnimator());
animatorSet.addListener(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> AnimatorListenerAdapter() {
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onAnimationStart</span><span class="hljs-params" style="box-sizing: inherit;">(Animator animation)</span> </span>{
setScaleX(<span class="hljs-number" style="box-sizing: inherit; color: #986801;">1.0f</span>);
setScaleY(<span class="hljs-number" style="box-sizing: inherit; color: #986801;">1.0f</span>);
}
});
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> animatorSet;
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> Animator <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">getTextAnimator</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
ValueAnimator solidShrink = ValueAnimator.ofFloat(<span class="hljs-number" style="box-sizing: inherit; color: #986801;">1.0f</span>, <span class="hljs-number" style="box-sizing: inherit; color: #986801;">0.96f</span>).setDuration(<span class="hljs-number" style="box-sizing: inherit; color: #986801;">250</span>);
solidShrink.addUpdateListener(mTextAnimatorUpdateListener);
ValueAnimator solidGrow = ValueAnimator.ofFloat(<span class="hljs-number" style="box-sizing: inherit; color: #986801;">0.96f</span>, <span class="hljs-number" style="box-sizing: inherit; color: #986801;">1.0f</span>).setDuration(<span class="hljs-number" style="box-sizing: inherit; color: #986801;">450</span>);
solidGrow.addUpdateListener(mTextAnimatorUpdateListener);
AnimatorSet solidAnimation = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> AnimatorSet();
solidAnimation.playSequentially(solidShrink, solidGrow);
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> solidAnimation;
}
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> ValueAnimator.AnimatorUpdateListener mTextAnimatorUpdateListener = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> ValueAnimator.AnimatorUpdateListener() {
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onAnimationUpdate</span><span class="hljs-params" style="box-sizing: inherit;">(ValueAnimator valueAnimator)</span> </span>{
setScaleX((<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">float</span>) valueAnimator.getAnimatedValue());
setScaleY((<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">float</span>) valueAnimator.getAnimatedValue());
}
};
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> Animator <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">getRefreshAnimator</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
ValueAnimator refreshAnimator = ValueAnimator.ofFloat(<span class="hljs-number" style="box-sizing: inherit; color: #986801;">0.0f</span>, <span class="hljs-number" style="box-sizing: inherit; color: #986801;">1.0f</span>).setDuration(<span class="hljs-number" style="box-sizing: inherit; color: #986801;">1200</span>);
refreshAnimator.addUpdateListener(mRefreshUpdateListener);
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> refreshAnimator;
}
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> ValueAnimator.AnimatorUpdateListener mRefreshUpdateListener = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> ValueAnimator.AnimatorUpdateListener() {
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onAnimationUpdate</span><span class="hljs-params" style="box-sizing: inherit;">(ValueAnimator valueAnimator)</span> </span>{
invalidate();
}
};
}</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "segoe ui" , "roboto" , "oxygen" , "ubuntu" , "cantarell" , "fira sans" , "droid sans" , "helvetica neue" , sans-serif; font-size: 16px;">В этом классе мы делаем простую манипуляцию. У нас как и в предыдущем классе есть метод getAnimator() который мы используем для создания эффекта пульсации. Тут мы этот эффект применяем к всей вьюхе текста которая у нас есть.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "segoe ui" , "roboto" , "oxygen" , "ubuntu" , "cantarell" , "fira sans" , "droid sans" , "helvetica neue" , sans-serif; font-size: 16px;">В методе getTextAnimator() мы задаем продолжительность пулсирования текста и задаем колбек который обновляет нашу анимацию вместе с тем что увеличивает и уменьшает размер текста на определенные шаги.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "segoe ui" , "roboto" , "oxygen" , "ubuntu" , "cantarell" , "fira sans" , "droid sans" , "helvetica neue" , sans-serif; font-size: 16px;">Далее нам нужно объеденить эта два класса в одном что бы мы могли использовать его как кнопку. Это мы будем делать в классе PulsingButtonView. Но для начала нам нужно сделать верстку этой вьюхи, в ней нас будут подключаться два класса которые мы подключили выше.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "segoe ui" , "roboto" , "oxygen" , "ubuntu" , "cantarell" , "fira sans" , "droid sans" , "helvetica neue" , sans-serif; font-size: 16px; font-weight: bolder;">view_pulsing_button.xml</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="xml hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;"><?xml version="1.0" encoding="utf-8"?></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">FrameLayout</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">xmlns:android</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"http://schemas.android.com/apk/res/android"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:id</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@+id/pulsing_button"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_width</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@dimen/pulsing_button_width"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_height</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@dimen/pulsing_button_height"</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">com.project.dajver.pulsingbutton.view.PulsingButtonBackground</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:id</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@+id/pulsing_background"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_width</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_height</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"match_parent"</span>/></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">com.project.dajver.pulsingbutton.view.PulsingButtonTextView</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:id</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@+id/pulsing_text"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_width</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_height</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:gravity</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"center"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:text</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@string/click_me"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:textAllCaps</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"false"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:textColor</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@android:color/white"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:textSize</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"24sp"</span>/></span>
<span class="hljs-tag" style="box-sizing: inherit;"></<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">FrameLayout</span>></span></code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "segoe ui" , "roboto" , "oxygen" , "ubuntu" , "cantarell" , "fira sans" , "droid sans" , "helvetica neue" , sans-serif; font-size: 16px;">Вот что я собственно и говорил, мы будем использовать оба наши класса в одном, положив текстовый поверх фона кнопки.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "segoe ui" , "roboto" , "oxygen" , "ubuntu" , "cantarell" , "fira sans" , "droid sans" , "helvetica neue" , sans-serif; font-size: 16px;">Еще нам не хватает два dimens. Для установки высоты и ширины вьюхи.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "segoe ui" , "roboto" , "oxygen" , "ubuntu" , "cantarell" , "fira sans" , "droid sans" , "helvetica neue" , sans-serif; font-size: 16px; font-weight: bolder;">dimens.xml</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="xml hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"> <span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">dimen</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">name</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"pulsing_button_width"</span>></span>300dp<span class="hljs-tag" style="box-sizing: inherit;"></<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">dimen</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">dimen</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">name</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"pulsing_button_height"</span>></span>300dp<span class="hljs-tag" style="box-sizing: inherit;"></<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">dimen</span>></span></code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "segoe ui" , "roboto" , "oxygen" , "ubuntu" , "cantarell" , "fira sans" , "droid sans" , "helvetica neue" , sans-serif; font-size: 16px; font-weight: bolder;">PulsingButtonView.java</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="java hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.animation.Animator;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.animation.AnimatorListenerAdapter;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.animation.AnimatorSet;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.content.Context;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.util.AttributeSet;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.view.LayoutInflater;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.widget.FrameLayout;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> com.project.dajver.pulsingbutton.R;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> butterknife.BindView;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> butterknife.ButterKnife;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> butterknife.OnClick;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-class" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">class</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">PulsingButtonView</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">extends</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">FrameLayout</span> </span>{
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@BindView</span>(R.id.pulsing_background)
PulsingButtonBackground pulsingButtonBackground;
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@BindView</span>(R.id.pulsing_text)
PulsingButtonTextView pulsingButtonTextView;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> Animator animator;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> OnPulseButtonClickListener onPulseButtonClick;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">boolean</span> animationEnabled = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">true</span>;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">boolean</span> alreadyAnimating;
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">PulsingButtonView</span><span class="hljs-params" style="box-sizing: inherit;">(Context context)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">super</span>(context);
initialize();
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">PulsingButtonView</span><span class="hljs-params" style="box-sizing: inherit;">(Context context, AttributeSet attrs)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">super</span>(context, attrs);
initialize();
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">PulsingButtonView</span><span class="hljs-params" style="box-sizing: inherit;">(Context context, AttributeSet attrs, <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> defStyleAttr)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">super</span>(context, attrs, defStyleAttr);
initialize();
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">initialize</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
LayoutInflater.from(getContext()).inflate(R.layout.view_pulsing_button, <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>);
ButterKnife.bind(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>);
}
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">protected</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onAttachedToWindow</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">super</span>.onAttachedToWindow();
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">if</span> (getVisibility() == VISIBLE) {
startAnimation();
}
}
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">protected</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onDetachedFromWindow</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
cancelAnimation();
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">super</span>.onDetachedFromWindow();
}
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">setVisibility</span><span class="hljs-params" style="box-sizing: inherit;">(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> visibility)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">if</span> (getVisibility() != visibility) {
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">super</span>.setVisibility(visibility);
updateAnimation();
}
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">updateAnimation</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">if</span> (getVisibility() == VISIBLE && animationEnabled) {
startAnimation();
} <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">else</span> {
cancelAnimation();
}
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">cancelAnimation</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">if</span> (animator != <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">null</span>) {
alreadyAnimating = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">false</span>;
animator.cancel();
animator = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">null</span>;
}
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">startAnimation</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">if</span> (alreadyAnimating) {
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span>;
}
alreadyAnimating = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">true</span>;
AnimatorSet animatorSet = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> AnimatorSet();
animatorSet.playTogether(pulsingButtonBackground.getAnimator(), pulsingButtonTextView.getAnimator());
animatorSet.addListener(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> AnimatorListenerAdapter() {
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onAnimationEnd</span><span class="hljs-params" style="box-sizing: inherit;">(Animator animation)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">if</span> (alreadyAnimating) {
alreadyAnimating = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">false</span>;
updateAnimation();
}
}
});
animatorSet.start();
animator = animatorSet;
}
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@OnClick</span>(R.id.pulsing_button)
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onClickThis</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
onPulseButtonClick.onPulseButtonClick();
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">setOnPulseButtonClick</span><span class="hljs-params" style="box-sizing: inherit;">(OnPulseButtonClickListener onPulseButtonClick)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>.onPulseButtonClick = onPulseButtonClick;
}
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-class" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">interface</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">OnPulseButtonClickListener</span> </span>{
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onPulseButtonClick</span><span class="hljs-params" style="box-sizing: inherit;">()</span></span>;
}
}</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "segoe ui" , "roboto" , "oxygen" , "ubuntu" , "cantarell" , "fira sans" , "droid sans" , "helvetica neue" , sans-serif; font-size: 16px;">В конструкторе мы инициализируем наш леяут который мы будем использовать как родительский и ButterKnife для того что-бы мы могли использовать биндиг с этой библиотеки.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "segoe ui" , "roboto" , "oxygen" , "ubuntu" , "cantarell" , "fira sans" , "droid sans" , "helvetica neue" , sans-serif; font-size: 16px;">Дальше у нас идет несколько методов onAttachedToWindow() и onDetachedFromWindow() для включения и выключения анимации в зависимости от того когда вьюха на экране и когда нет.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "segoe ui" , "roboto" , "oxygen" , "ubuntu" , "cantarell" , "fira sans" , "droid sans" , "helvetica neue" , sans-serif; font-size: 16px;">Метод setVisibility() для того что бы когда мы делаем вьюху невидимой мы выключаем ее анимацию что бы она не жрала память.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "segoe ui" , "roboto" , "oxygen" , "ubuntu" , "cantarell" , "fira sans" , "droid sans" , "helvetica neue" , sans-serif; font-size: 16px;">Метод updateAnimation() мы используем как раз для того что я написал чуть выше, если вьюха в пределах видимости на экране — она у нас играет анимацию, если же нет — тогда мы стопим ее.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "segoe ui" , "roboto" , "oxygen" , "ubuntu" , "cantarell" , "fira sans" , "droid sans" , "helvetica neue" , sans-serif; font-size: 16px;">cancelAnimation() и startAnimation() у нас очевидно для старта и остановки анимации.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "segoe ui" , "roboto" , "oxygen" , "ubuntu" , "cantarell" , "fira sans" , "droid sans" , "helvetica neue" , sans-serif; font-size: 16px;">Метод onClickThis() у нас отслеживает клик по кнопку и шлет колбек в активити. Ну и ниже у нас сеттер для колбека и сам интерфейс его же.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "segoe ui" , "roboto" , "oxygen" , "ubuntu" , "cantarell" , "fira sans" , "droid sans" , "helvetica neue" , sans-serif; font-size: 16px;">Теперь нам осталось только подключить это все в нашей активити и любоваться красотой.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "segoe ui" , "roboto" , "oxygen" , "ubuntu" , "cantarell" , "fira sans" , "droid sans" , "helvetica neue" , sans-serif; font-size: 16px; font-weight: bolder;">activity_main.xml </span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="xml hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;"><?xml version="1.0" encoding="utf-8"?></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">LinearLayout</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">xmlns:android</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"http://schemas.android.com/apk/res/android"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">xmlns:app</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"http://schemas.android.com/apk/res-auto"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">xmlns:tools</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"http://schemas.android.com/tools"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_width</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_height</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:gravity</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"center_vertical|center_horizontal"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:background</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@android:color/white"</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">com.project.dajver.pulsingbutton.view.PulsingButtonView</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:id</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@+id/pulsing_button"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_width</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"wrap_content"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_height</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"wrap_content"</span> /></span>
<span class="hljs-tag" style="box-sizing: inherit;"></<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">LinearLayout</span>></span></code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "segoe ui" , "roboto" , "oxygen" , "ubuntu" , "cantarell" , "fira sans" , "droid sans" , "helvetica neue" , sans-serif; font-size: 16px;">Здесь просто прописываем что будем использовать нашу кнопку. И дальше в нашей MainActivity сетим колбек на клик, что бы отслеживать его.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "segoe ui" , "roboto" , "oxygen" , "ubuntu" , "cantarell" , "fira sans" , "droid sans" , "helvetica neue" , sans-serif; font-size: 16px; font-weight: bolder;">MainActivity.java</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="java hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.os.Bundle;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.support.v7.app.AppCompatActivity;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.widget.Toast;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> com.project.dajver.pulsingbutton.view.PulsingButtonView;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> butterknife.BindView;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> butterknife.ButterKnife;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-class" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">class</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">MainActivity</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">extends</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">AppCompatActivity</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">implements</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">PulsingButtonView</span>.<span class="hljs-title" style="box-sizing: inherit; color: #c18401;">OnPulseButtonClickListener</span> </span>{
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@BindView</span>(R.id.pulsing_button)
PulsingButtonView pulsingButtonView;
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">protected</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onCreate</span><span class="hljs-params" style="box-sizing: inherit;">(Bundle savedInstanceState)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">super</span>.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>);
pulsingButtonView.setOnPulseButtonClick(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>);
}
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onPulseButtonClick</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
Toast.makeText(getApplicationContext(), getString(R.string.button_clicked), Toast.LENGTH_LONG).show();
}
}
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "segoe ui" , "roboto" , "oxygen" , "ubuntu" , "cantarell" , "fira sans" , "droid sans" , "helvetica neue" , sans-serif; font-size: 16px;">В onCreate() прописываем леяут, ButterKnife и указываем что будем использовать лисенер клика по кнопке. onPulseButtonClick() же метод который является колбеком в который возвращается клик.</span><br />
<span style="background-color: white; color: #222222; font-family: , , "segoe ui" , "roboto" , "oxygen" , "ubuntu" , "cantarell" , "fira sans" , "droid sans" , "helvetica neue" , sans-serif; font-size: 16px;"><br /></span>
<br />
<h4 style="background-color: white; color: #666666; font-family: "trebuchet ms", trebuchet, verdana, sans-serif; font-size: 13.2px; margin: 0px; position: relative;">
<b><span style="font-size: xx-small;"><span style="font-family: "verdana" , sans-serif; font-size: medium; line-height: 22.4px;">Исходники:</span></span></b></h4>
<h4 style="background-color: white; color: #666666; font-family: "trebuchet ms", trebuchet, verdana, sans-serif; font-size: 13.2px; margin: 0px; position: relative;">
<b><span style="font-size: medium;"><a href="https://github.com/dajver/PulseButtonView" style="border: 0px; color: #990099; font-family: verdana, sans-serif; line-height: 22.4px; margin: 0px; outline: 0px; padding: 0px; text-decoration-line: none; vertical-align: baseline;">GitHub</a></span></b></h4>
</div>
dajverhttp://www.blogger.com/profile/09427222798699404442noreply@blogger.com0tag:blogger.com,1999:blog-5677605911484164185.post-82412041238356386702017-08-08T22:24:00.002+03:002017-08-15T17:20:41.823+03:00Пагинация для локального ArrayList <div dir="ltr" style="text-align: left;" trbidi="on">
<div class="separator" style="clear: both; text-align: left;">
<span style="background-color: white; color: #222222; font-family: , , "segoe ui" , "roboto" , "oxygen" , "ubuntu" , "cantarell" , "fira sans" , "droid sans" , "helvetica neue" , sans-serif; font-size: 16px;">Недавно понадобилось делать пагинацию подручными способами, пришлось выкручиваться как только можно, так что сегодня я поделюсь своим опытом создания пагинации из локального списка. Это в принципе совсем не сложно и вполне можно самому додуматься как такое сделать, но в интернете я не нашел статей, так что думаю кому-то да пригодится.</span></div>
<div class="separator" style="clear: both; text-align: left;">
<span style="background-color: white; font-family: "verdana" , sans-serif;"><br /></span></div>
<div class="separator" style="clear: both; text-align: center;">
<span style="font-size: xx-small;"><iframe allowfullscreen="" class="YOUTUBE-iframe-video" data-thumbnail-src="https://i.ytimg.com/vi/j5EWMw8L1_8/0.jpg" frameborder="0" height="266" src="https://www.youtube.com/embed/j5EWMw8L1_8?feature=player_embedded" width="320"></iframe></span></div>
<span style="font-size: xx-small;"><br /></span><span style="background-color: white; color: #222222; font-family: , , "segoe ui" , "roboto" , "oxygen" , "ubuntu" , "cantarell" , "fira sans" , "droid sans" , "helvetica neue" , sans-serif; font-size: 16px;">Вот так вот будет выглядеть наша пагинация, она работает так потому что я специально сделал задержку перед загрузкой и кажется что данные подгружаются откуда-то с удаленного сервера, а на деле оно все хранится локально у нас в списке. Если же убрать эту задержку данные просто будут загружаться так быстро как вы приближаетесь к его концу.</span><br />
<a name='more'></a><br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "segoe ui" , "roboto" , "oxygen" , "ubuntu" , "cantarell" , "fira sans" , "droid sans" , "helvetica neue" , sans-serif; font-size: 16px;">Для начала хочу сказать что в этом проекте я использовал уже возможно знакомый для вас код, так как я взял его из одной своей статьи:<a href="https://dajver.blogspot.com/2017/05/retrofit.html"> Работа с Retrofit</a>. Оттуда я взял собственно код запроса, частично код адаптера и модели для респонса. И просто разбил этот список который нам возвращает апи на несколько частей. В приложении я сделал так что бы оно загружало по 10 итемов каждый раз когда мы скролим в низ. То есть мы дошли до низа списка, и делаем «запрос» на получение еще 10 из списка и так пока у нас не закончатся итемы.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "segoe ui" , "roboto" , "oxygen" , "ubuntu" , "cantarell" , "fira sans" , "droid sans" , "helvetica neue" , sans-serif; font-size: 16px;">Давайте начнем. По старинке для начала настроим наш проект для работы, нам нужно добавить библиотеки и настроить манифест для работы с интернетом. </span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "segoe ui" , "roboto" , "oxygen" , "ubuntu" , "cantarell" , "fira sans" , "droid sans" , "helvetica neue" , sans-serif; font-size: 16px; font-weight: bolder;">app/build.gradle</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="java hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;">apply plugin: <span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">'com.android.application'</span>
android {
compileSdkVersion <span class="hljs-number" style="box-sizing: inherit; color: #986801;">25</span>
buildToolsVersion <span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"25.0.2"</span>
defaultConfig {
applicationId <span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"com.project.dajver.listpaginationexample"</span>
minSdkVersion <span class="hljs-number" style="box-sizing: inherit; color: #986801;">15</span>
targetSdkVersion <span class="hljs-number" style="box-sizing: inherit; color: #986801;">25</span>
versionCode <span class="hljs-number" style="box-sizing: inherit; color: #986801;">1</span>
versionName <span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"1.0"</span>
testInstrumentationRunner <span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"android.support.test.runner.AndroidJUnitRunner"</span>
}
buildTypes {
release {
<span class="hljs-function" style="box-sizing: inherit;">minifyEnabled <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">false</span>
proguardFiles <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">getDefaultProguardFile</span><span class="hljs-params" style="box-sizing: inherit;">(<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">'proguard-android.txt'</span>)</span>, 'proguard-rules.pro'
}
}
}
dependencies </span>{
<span class="hljs-function" style="box-sizing: inherit;">compile <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">fileTree</span><span class="hljs-params" style="box-sizing: inherit;">(dir: <span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">'libs'</span>, include: [<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">'*.jar'</span>])</span>
compile 'com.android.support:appcompat-v7:25.3.1'
compile 'com.jakewharton:butterknife:8.8.0'
annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.0'
compile 'com.squareup.retrofit2:retrofit:2.0.1'
compile 'com.squareup.retrofit2:converter-gson:2.0.1'
compile 'com.squareup.okhttp3:logging-interceptor:3.2.0'
compile 'com.squareup.retrofit2:converter-scalars:2.0.1'
compile 'com.android.support:recyclerview-v7:25.0.+'
}</span></code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "segoe ui" , "roboto" , "oxygen" , "ubuntu" , "cantarell" , "fira sans" , "droid sans" , "helvetica neue" , sans-serif; font-size: 16px;">У нас в проекте будет две основных библиотеки — это Retrofit и ButterKnife, первая нам нужна для создания реквестов на апи, вторая для упрощенного подключения вьюх к активитям. А еще у нас будет одна библиотека RecyclerView для списка.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "segoe ui" , "roboto" , "oxygen" , "ubuntu" , "cantarell" , "fira sans" , "droid sans" , "helvetica neue" , sans-serif; font-size: 16px;">Далее давайте настроим манифест. В нем нам всего лишь надо прописать пермишен доступа в интернет.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "segoe ui" , "roboto" , "oxygen" , "ubuntu" , "cantarell" , "fira sans" , "droid sans" , "helvetica neue" , sans-serif; font-size: 16px; font-weight: bolder;">AndroidManifest.xml</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="xml hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;"><?xml version="1.0" encoding="utf-8"?></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">manifest</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">xmlns:android</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"http://schemas.android.com/apk/res/android"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">package</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"com.project.dajver.listpaginationexample"</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">uses-permission</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:name</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"android.permission.INTERNET"</span> /></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">application</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:allowBackup</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"true"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:icon</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@mipmap/ic_launcher"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:label</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@string/app_name"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:roundIcon</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@mipmap/ic_launcher_round"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:supportsRtl</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"true"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:theme</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@style/AppTheme"</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">activity</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:name</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">".MainActivity"</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">intent-filter</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">action</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:name</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"android.intent.action.MAIN"</span> /></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">category</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:name</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"android.intent.category.LAUNCHER"</span> /></span>
<span class="hljs-tag" style="box-sizing: inherit;"></<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">intent-filter</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"></<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">activity</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"></<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">application</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"></<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">manifest</span>></span></code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "segoe ui" , "roboto" , "oxygen" , "ubuntu" , "cantarell" , "fira sans" , "droid sans" , "helvetica neue" , sans-serif; font-size: 16px;">Ну, а дальше давайте приступим к кодингу. С начала напишем всю работу с апи, оно у нас стандартное как и весь код с ретрофитом. У нас есть интерфейс в котором у нас все реквесты к апи, класс который описывает эти запросы и модель которая принимает респонс с сервера и парсит ее.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "segoe ui" , "roboto" , "oxygen" , "ubuntu" , "cantarell" , "fira sans" , "droid sans" , "helvetica neue" , sans-serif; font-size: 16px;">Для начала давайте создадим модель. В ней у нас будет всего лишь один ArrayList который будет в себе хранить все данные которые возвращаются нам с сервера.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "segoe ui" , "roboto" , "oxygen" , "ubuntu" , "cantarell" , "fira sans" , "droid sans" , "helvetica neue" , sans-serif; font-size: 16px; font-weight: bolder;">SearchModel.java</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="java hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> com.google.gson.annotations.Expose;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> com.google.gson.annotations.SerializedName;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> java.util.ArrayList;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> java.util.List;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-class" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">class</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">SearchModel</span> </span>{
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@SerializedName</span>(<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"list"</span>)
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Expose</span>
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> List<List<String>> list = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> ArrayList<>();
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> List<List<String>> getList() {
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> list;
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">setList</span><span class="hljs-params" style="box-sizing: inherit;">(List<List<String>> list)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>.list = list;
}
}
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "segoe ui" , "roboto" , "oxygen" , "ubuntu" , "cantarell" , "fira sans" , "droid sans" , "helvetica neue" , sans-serif; font-size: 16px;">Вот такой вот класс. Нам нужен всего лишь этот класс, его нам будет достаточно для парсинга данных.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "segoe ui" , "roboto" , "oxygen" , "ubuntu" , "cantarell" , "fira sans" , "droid sans" , "helvetica neue" , sans-serif; font-size: 16px;">Дальше нам нужно описать интерфейс запросов. У нас он короткий, всего один запрос который мы будем вызывать далее.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "segoe ui" , "roboto" , "oxygen" , "ubuntu" , "cantarell" , "fira sans" , "droid sans" , "helvetica neue" , sans-serif; font-size: 16px;"><b>API.java</b></span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="java hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> com.project.dajver.listpaginationexample.api.model.SearchModel;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> retrofit2.Call;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> retrofit2.http.GET;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> retrofit2.http.Query;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-class" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">interface</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">API</span> </span>{
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@GET</span>(<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"api.php?method=search"</span>)
<span class="hljs-function" style="box-sizing: inherit;">Call<SearchModel> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">searchAudio</span><span class="hljs-params" style="box-sizing: inherit;">(@Query(<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"q"</span>)</span> String query, @<span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">Query</span><span class="hljs-params" style="box-sizing: inherit;">(<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"key"</span>)</span> String key)</span>;
}
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "segoe ui" , "roboto" , "oxygen" , "ubuntu" , "cantarell" , "fira sans" , "droid sans" , "helvetica neue" , sans-serif; font-size: 16px;">Тут как видно мы делаем get запрос на какой-то адрес и дальше в коде указываем что принимать мы будем SearchModel, а отправлять название песни которую мы ищем и ключ который нам выдали для работы с апи сайт с которого я взял это АПИ.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "segoe ui" , "roboto" , "oxygen" , "ubuntu" , "cantarell" , "fira sans" , "droid sans" , "helvetica neue" , sans-serif; font-size: 16px;">Дальше нам нужно написать сервис который будет создавать запросы с нашего интерфейса, так сказать будет описывать работу нашего интерфейса.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "segoe ui" , "roboto" , "oxygen" , "ubuntu" , "cantarell" , "fira sans" , "droid sans" , "helvetica neue" , sans-serif; font-size: 16px;"><b>RestClient.java</b></span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="java hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> com.google.gson.Gson;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> okhttp3.OkHttpClient;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> okhttp3.logging.HttpLoggingInterceptor;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> retrofit2.Retrofit;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> retrofit2.converter.gson.GsonConverterFactory;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> retrofit2.converter.scalars.ScalarsConverterFactory;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-class" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">class</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">RestClient</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">static</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">final</span> String BASE_URL = <span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"http://api.xn--41a.ws/"</span>;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">static</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">final</span> String API_KEY = <span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"711b23b60ff8da0c3aa2451ab3a6beb9"</span>;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">static</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">final</span> RestClient instance = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> RestClient();
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">static</span> API <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">instance</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> instance.service;
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">static</span> Gson <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">gson</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> Gson();
}
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">final</span> API service;
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">RestClient</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
Retrofit retrofit = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> Retrofit.Builder()
.baseUrl(BASE_URL)
.client(logLevel())
.addConverterFactory(ScalarsConverterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.build();
service = retrofit.create(API.class);
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">static</span> OkHttpClient <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">logLevel</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
HttpLoggingInterceptor interceptor = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient client = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> OkHttpClient.Builder()
.addInterceptor(interceptor)
.build();
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> client;
}
}
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "segoe ui" , "roboto" , "oxygen" , "ubuntu" , "cantarell" , "fira sans" , "droid sans" , "helvetica neue" , sans-serif; font-size: 16px;">Собственно тут мы в константах описали адрес сайта к которому будем обращаться за АПИ, указали ключ который мы будем использовать как токен и дальше мы создаем статический инстанс нашего класса что бы нам проще было обращаться к паблик методам этого класса. Далее в конструкторе инициализируем ретрофит, подключаем к нему фабрики для конверта данных и указываем какой класс будем использовать для создания запросов.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "segoe ui" , "roboto" , "oxygen" , "ubuntu" , "cantarell" , "fira sans" , "droid sans" , "helvetica neue" , sans-serif; font-size: 16px;">Ниже в методе logLevel() мы говорим что мы хотим видеть все логи которые есть во время запросов и когда запрос прекращает свою работу.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "segoe ui" , "roboto" , "oxygen" , "ubuntu" , "cantarell" , "fira sans" , "droid sans" , "helvetica neue" , sans-serif; font-size: 16px;">Дальше нам нужно создать адаптер который мы будем использовать для отображения списка песен. </span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "segoe ui" , "roboto" , "oxygen" , "ubuntu" , "cantarell" , "fira sans" , "droid sans" , "helvetica neue" , sans-serif; font-size: 16px; font-weight: bolder;">MusicRecyclerAdapter.java</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="java hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.support.v7.widget.RecyclerView;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.view.LayoutInflater;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.view.View;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.view.ViewGroup;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.widget.TextView;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> com.project.dajver.listpaginationexample.R;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> java.util.ArrayList;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> java.util.List;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> butterknife.BindView;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> butterknife.ButterKnife;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-class" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">class</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">MusicRecyclerAdapter</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">extends</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">RecyclerView</span>.<span class="hljs-title" style="box-sizing: inherit; color: #c18401;">Adapter</span><<span class="hljs-title" style="box-sizing: inherit; color: #c18401;">MusicRecyclerAdapter</span>.<span class="hljs-title" style="box-sizing: inherit; color: #c18401;">ViewHolder</span>></span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> List<List<String>> searchModels = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> ArrayList<>();
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">add</span><span class="hljs-params" style="box-sizing: inherit;">(List<String> string)</span> </span>{
searchModels.add(string);
notifyDataSetChanged();
}
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> MusicRecyclerAdapter.<span class="hljs-function" style="box-sizing: inherit;">ViewHolder <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onCreateViewHolder</span><span class="hljs-params" style="box-sizing: inherit;">(ViewGroup parent, <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> viewType)</span> </span>{
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_music, parent, <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">false</span>);
MusicRecyclerAdapter.ViewHolder pvh = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> MusicRecyclerAdapter.ViewHolder(v);
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> pvh;
}
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onBindViewHolder</span><span class="hljs-params" style="box-sizing: inherit;">(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">final</span> MusicRecyclerAdapter.ViewHolder holder, <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">final</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> position)</span> </span>{
holder.title.setText(searchModels.get(position).get(<span class="hljs-number" style="box-sizing: inherit; color: #986801;">4</span>) + <span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">" - "</span> + searchModels.get(position).get(<span class="hljs-number" style="box-sizing: inherit; color: #986801;">3</span>));
}
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">getItemCount</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> searchModels.size();
}
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-class" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">class</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">ViewHolder</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">extends</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">RecyclerView</span>.<span class="hljs-title" style="box-sizing: inherit; color: #c18401;">ViewHolder</span> </span>{
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@BindView</span>(R.id.textView)
TextView title;
ViewHolder(View itemView) {
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">super</span>(itemView);
ButterKnife.bind(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>, itemView);
}
}
}
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "segoe ui" , "roboto" , "oxygen" , "ubuntu" , "cantarell" , "fira sans" , "droid sans" , "helvetica neue" , sans-serif; font-size: 16px;">В целом стандартный адаптер, единственное что интересное это метод add(), он у нас для сетта данных в адаптер, в него мы передаем List и как бы потом в onBindViewHolder() мы его парсим по позиции так как этот список имеет статичное количество параметров и он содержит в себе по определенным полям определенные данные которые нам интересны. Собственно по id 4 и id 3 мы получаем имя исполнителя и название песни.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "segoe ui" , "roboto" , "oxygen" , "ubuntu" , "cantarell" , "fira sans" , "droid sans" , "helvetica neue" , sans-serif; font-size: 16px;">Вот так будет выглядеть отдельный айтем для адаптера.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "segoe ui" , "roboto" , "oxygen" , "ubuntu" , "cantarell" , "fira sans" , "droid sans" , "helvetica neue" , sans-serif; font-size: 16px; font-weight: bolder;">item_music.xml</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="xml hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;"><?xml version="1.0" encoding="utf-8"?></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">LinearLayout</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">xmlns:android</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"http://schemas.android.com/apk/res/android"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_width</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_height</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"wrap_content"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:orientation</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"vertical"</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">TextView</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:id</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@+id/textView"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_width</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_height</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"wrap_content"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:padding</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"15dp"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:text</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"TextView"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:textSize</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"18sp"</span> /></span>
<span class="hljs-tag" style="box-sizing: inherit;"></<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">LinearLayout</span>></span>
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "segoe ui" , "roboto" , "oxygen" , "ubuntu" , "cantarell" , "fira sans" , "droid sans" , "helvetica neue" , sans-serif; font-size: 16px;">Еще нам не хватает одного класса который будет добавлять айтемы с задержкой. Его мы реализовали как AsyncTask в котором будем делать задержку на 3 секунды и потом возващать колбек в активити.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "segoe ui" , "roboto" , "oxygen" , "ubuntu" , "cantarell" , "fira sans" , "droid sans" , "helvetica neue" , sans-serif; font-size: 16px; font-weight: bolder;">AddItemsTask.java</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="java hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.os.AsyncTask;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> java.util.concurrent.TimeUnit;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-class" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">class</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">AddItemsTask</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">extends</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">AsyncTask</span><<span class="hljs-title" style="box-sizing: inherit; color: #c18401;">Void</span>, <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">Void</span>, <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">Void</span>> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> OnAddItemListener addItemToAdapter;
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">AddItemsTask</span><span class="hljs-params" style="box-sizing: inherit;">(OnAddItemListener addItemToAdapter)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>.addItemToAdapter = addItemToAdapter;
}
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">protected</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onPreExecute</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">super</span>.onPreExecute();
addItemToAdapter.onStartTask();
}
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">protected</span> Void <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">doInBackground</span><span class="hljs-params" style="box-sizing: inherit;">(Void... params)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">try</span> {
TimeUnit.SECONDS.sleep(<span class="hljs-number" style="box-sizing: inherit; color: #986801;">3</span>);
} <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">catch</span> (InterruptedException e) {
e.printStackTrace();
}
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">return</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">null</span>;
}
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">protected</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onPostExecute</span><span class="hljs-params" style="box-sizing: inherit;">(Void result)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">super</span>.onPostExecute(result);
addItemToAdapter.onFinishTask();
}
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-class" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">interface</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">OnAddItemListener</span> </span>{
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onStartTask</span><span class="hljs-params" style="box-sizing: inherit;">()</span></span>;
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onFinishTask</span><span class="hljs-params" style="box-sizing: inherit;">()</span></span>;
}
}</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "segoe ui" , "roboto" , "oxygen" , "ubuntu" , "cantarell" , "fira sans" , "droid sans" , "helvetica neue" , sans-serif; font-size: 16px;">Вполне себе стандартный код как по мне, в onPreExecute() мы вызываем колбек который возвращает в активити колбек и у нас будет стартовать прогрес диалог который будет показывать что данные загружаются. Дальше в методе doInBackground() мы делаем задержку на 3 секунды, и в onPostExecute() мы вызываем колбек который добавляет данные в адаптер и прячет прогрес диалог.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "segoe ui" , "roboto" , "oxygen" , "ubuntu" , "cantarell" , "fira sans" , "droid sans" , "helvetica neue" , sans-serif; font-size: 16px;">Дак, адаптер и класс который загружает данные у нас есть, теперь нужно соеденить все кусочки в одно целое в нашей активити. В ней мы проинициализируем все нужные классы, подключим все методы, запустим адаптер и сделаем запрос на сервер для получения музыки.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "segoe ui" , "roboto" , "oxygen" , "ubuntu" , "cantarell" , "fira sans" , "droid sans" , "helvetica neue" , sans-serif; font-size: 16px; font-weight: bolder;">MainActivity.java</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="java hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.os.Bundle;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.support.v7.app.AppCompatActivity;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.support.v7.widget.DividerItemDecoration;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.support.v7.widget.LinearLayoutManager;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.support.v7.widget.RecyclerView;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.support.v7.widget.RecyclerView.OnScrollListener;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.view.View;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> android.widget.ProgressBar;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> com.project.dajver.listpaginationexample.adapter.MusicRecyclerAdapter;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> com.project.dajver.listpaginationexample.api.RestClient;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> com.project.dajver.listpaginationexample.api.model.SearchModel;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> com.project.dajver.listpaginationexample.task.AddItemsTask;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> java.util.List;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> butterknife.BindView;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> butterknife.ButterKnife;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> retrofit2.Call;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> retrofit2.Callback;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">import</span> retrofit2.Response;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-class" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">class</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">MainActivity</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">extends</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">AppCompatActivity</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">implements</span> <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">Callback</span><<span class="hljs-title" style="box-sizing: inherit; color: #c18401;">SearchModel</span>>, <span class="hljs-title" style="box-sizing: inherit; color: #c18401;">AddItemsTask</span>.<span class="hljs-title" style="box-sizing: inherit; color: #c18401;">OnAddItemListener</span> </span>{
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@BindView</span>(R.id.recycleView)
RecyclerView recycleView;
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@BindView</span>(R.id.progressBar)
ProgressBar progressBar;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> NUM_ITEMS_PAGE = <span class="hljs-number" style="box-sizing: inherit; color: #986801;">10</span>;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> MusicRecyclerAdapter musicRecyclerAdapter;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> List<List<String>> listList;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> paginationCounter = <span class="hljs-number" style="box-sizing: inherit; color: #986801;">0</span>;
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">protected</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onCreate</span><span class="hljs-params" style="box-sizing: inherit;">(Bundle savedInstanceState)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">super</span>.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>);
recycleViewSetup(recycleView);
musicRecyclerAdapter = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> MusicRecyclerAdapter();
recycleView.setAdapter(musicRecyclerAdapter);
recycleView.addOnScrollListener(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> OnScrollListener() {
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onScrolled</span><span class="hljs-params" style="box-sizing: inherit;">(RecyclerView recyclerView, <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> dx, <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> dy)</span> </span>{
LinearLayoutManager layoutManager = LinearLayoutManager.class.cast(recyclerView.getLayoutManager());
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> totalItemCount = layoutManager.getItemCount();
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> lastVisible = layoutManager.findLastVisibleItemPosition();
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">boolean</span> endHasBeenReached = lastVisible + <span class="hljs-number" style="box-sizing: inherit; color: #986801;">5</span> >= totalItemCount;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">if</span> (totalItemCount > <span class="hljs-number" style="box-sizing: inherit; color: #986801;">0</span> && endHasBeenReached) {
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> AddItemsTask(MainActivity.<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>).execute();
}
}
});
RestClient.instance().searchAudio(<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"Armin"</span>, RestClient.API_KEY).enqueue(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>);
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">recycleViewSetup</span><span class="hljs-params" style="box-sizing: inherit;">(RecyclerView recyclerView)</span> </span>{
recyclerView.setHasFixedSize(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">true</span>);
LinearLayoutManager linearLayoutManager = <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> LinearLayoutManager(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>);
linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
recyclerView.setLayoutManager(linearLayoutManager);
recyclerView.addItemDecoration(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">new</span> DividerItemDecoration(<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>, DividerItemDecoration.VERTICAL));
}
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onResponse</span><span class="hljs-params" style="box-sizing: inherit;">(Call<SearchModel> call, Response<SearchModel> response)</span> </span>{
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">this</span>.listList = response.body().getList();
addItemToAdapter();
}
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onFailure</span><span class="hljs-params" style="box-sizing: inherit;">(Call<SearchModel> call, Throwable t)</span> </span>{
t.printStackTrace();
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">private</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">addItemToAdapter</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
paginationCounter += NUM_ITEMS_PAGE;
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">for</span> (<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">int</span> i = paginationCounter - NUM_ITEMS_PAGE; i < paginationCounter; i++) {
progressBar.setVisibility(View.VISIBLE);
<span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">if</span> (i < listList.size() && listList.get(i) != <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">null</span>)
musicRecyclerAdapter.add(listList.get(i));
}
}
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onStartTask</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
progressBar.setVisibility(View.VISIBLE);
}
<span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;">@Override</span>
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #a626a4;">void</span> <span class="hljs-title" style="box-sizing: inherit; color: #4078f2;">onFinishTask</span><span class="hljs-params" style="box-sizing: inherit;">()</span> </span>{
addItemToAdapter();
progressBar.setVisibility(View.GONE);
}
}</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "segoe ui" , "roboto" , "oxygen" , "ubuntu" , "cantarell" , "fira sans" , "droid sans" , "helvetica neue" , sans-serif; font-size: 16px;">В методе onCreate() мы инициализируем леяут, ButterKnife, так же в этом методе мы инициализируем RecyclerView, создаем адаптер и сетим его в наш RecyclerView, и добавляем onScrollListener и в нем проверяем дошли ли мы до конца списка, и если дошли то запускаем наш AddItemsTask который по истечению 3 секунд добавит новые данные с помощью колбека onFinishTask(). Ну и в самом низу этого метода мы делаем запрос на сервер.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "segoe ui" , "roboto" , "oxygen" , "ubuntu" , "cantarell" , "fira sans" , "droid sans" , "helvetica neue" , sans-serif; font-size: 16px;">Метод recycleViewSetup() нам нужен для настройки RecyclerView, без этого метода наш список просто не отобразится на экране. В нем мы задаем размер, расположение, количество колонок и т.д., для нашего списка.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "segoe ui" , "roboto" , "oxygen" , "ubuntu" , "cantarell" , "fira sans" , "droid sans" , "helvetica neue" , sans-serif; font-size: 16px;">Методы onResponse() и onFailure() стандартные методы Retrofit, в первом мы сетим данные в список для дальнейшей работы с ним и вызываем метод который сетит часть данных, а именно 10 итемов в адаптер.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "segoe ui" , "roboto" , "oxygen" , "ubuntu" , "cantarell" , "fira sans" , "droid sans" , "helvetica neue" , sans-serif; font-size: 16px;">Метод addItemToAdapter() нам нужен для создания пагинации, в нем мы берем наш каунтер и прибавляем ему NUM_ITEMS_PAGE который равен у нас 10, собственно 10 итемам которые мы в начале будем отображать. Дальше в цикле мы проходимся paginationCounter количество раз с шагом paginationCounter — NUM_ITEMS_PAGE, это мы делаем для того что бы у нас всегда загружались только с нужного шага данные, то есть если мы на 5 шаге то у нас будет грузиться с 5 по 6 так как paginationCounter = 60, а NUM_ITEMS_PAGE = 10, а в сумме одно минус другое дает нам общее количество итемов которые нам нужно загрузить в адаптер. Потом мы останавливаем прогресс бар, проверяем что бы у нас не дай бог не выскачил IndexOfBoundsException и добавляем айтем в адаптер.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "segoe ui" , "roboto" , "oxygen" , "ubuntu" , "cantarell" , "fira sans" , "droid sans" , "helvetica neue" , sans-serif; font-size: 16px;">Ну и дальше идут два наших колбека onStartTask() и onFinishTask() которые выполняют собственно два важных события, делания прогресс бара видимым и прятание его с последующим вызовом метода addItemToAdapter().</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "segoe ui" , "roboto" , "oxygen" , "ubuntu" , "cantarell" , "fira sans" , "droid sans" , "helvetica neue" , sans-serif; font-size: 16px;">Наша разметка будет выглядеть очень просто, в ней у нас будет всего лишь RecycerView и ProgressBar.</span><br />
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; font-size: 16px;" />
<span style="background-color: white; box-sizing: inherit; color: #222222; font-family: , , "segoe ui" , "roboto" , "oxygen" , "ubuntu" , "cantarell" , "fira sans" , "droid sans" , "helvetica neue" , sans-serif; font-size: 16px; font-weight: bolder;">activity_main.xml</span><br />
<pre style="background-color: white; box-sizing: inherit; color: #222222; font-family: monospace, monospace; font-size: 16px; overflow-x: auto; overflow-y: hidden; padding: 0px; word-break: break-all;"><code class="xml hljs" style="background: rgb(251, 253, 255); border: 1px solid rgb(229, 232, 236); box-sizing: inherit; color: #383a42; display: block; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 14px; overflow-x: auto; padding: 17px 20px 20px; white-space: pre-wrap;"><span class="hljs-meta" style="box-sizing: inherit; color: #4078f2;"><?xml version="1.0" encoding="utf-8"?></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">LinearLayout</span> <span class="hljs-attr" style="box-sizing: inherit; color: #986801;">xmlns:android</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"http://schemas.android.com/apk/res/android"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_width</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_height</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:orientation</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"vertical"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:padding</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"10dp"</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">android.support.v7.widget.RecyclerView</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:id</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@+id/recycleView"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_width</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_height</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_weight</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"0.1"</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"></<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">android.support.v7.widget.RecyclerView</span>></span>
<span class="hljs-tag" style="box-sizing: inherit;"><<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">ProgressBar</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:id</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"@+id/progressBar"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">style</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"?android:attr/progressBarStyle"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_width</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"match_parent"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:layout_height</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"wrap_content"</span>
<span class="hljs-attr" style="box-sizing: inherit; color: #986801;">android:visibility</span>=<span class="hljs-string" style="box-sizing: inherit; color: #50a14f;">"gone"</span> /></span>
<span class="hljs-tag" style="box-sizing: inherit;"></<span class="hljs-name" style="box-sizing: inherit; color: #e45649;">LinearLayout</span>></span>
</code></pre>
<br style="background-color: white; box-sizing: inherit; color: #222222; font-family: -apple-system, system-ui, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; font-size: 16px;" />
<span style="background-color: white; color: #222222; font-family: , , "segoe ui" , "roboto" , "oxygen" , "ubuntu" , "cantarell" , "fira sans" , "droid sans" , "helvetica neue" , sans-serif; font-size: 16px;">И собственно все, у нас готов наш проект, включаем и наслаждаемся его работой. У тех кто дошел до этого момента должен случиться эстетически оргазм от того что все работает и все так красиво написанно. Возможно у кого-то конечно есть предложения по улучшению кода, я всегда за, предлагайте.</span><br />
<span style="font-size: xx-small;"><span style="background-color: white; font-family: "verdana" , sans-serif; font-size: xx-small;"><br /></span></span>
<br />
<h4 style="background-color: white; color: #666666; font-family: "trebuchet ms", trebuchet, verdana, sans-serif; font-size: 13.2px; margin: 0px; position: relative;">
<b><span style="font-size: xx-small;"><span style="font-family: "verdana" , sans-serif; font-size: small; line-height: 22.4px;">Исходники:</span></span></b></h4>
<h4 style="background-color: white; color: #666666; font-family: "trebuchet ms", trebuchet, verdana, sans-serif; font-size: 13.2px; margin: 0px; position: relative;">
<b><span style="font-size: small;"><a href="https://github.com/dajver/ArrayListPaginationExample" style="border: 0px; color: #990099; font-family: verdana, sans-serif; line-height: 22.4px; margin: 0px; outline: 0px; padding: 0px; text-decoration-line: none; vertical-align: baseline;">GitHub</a></span></b></h4>
</div>
dajverhttp://www.blogger.com/profile/09427222798699404442noreply@blogger.com0