[Разработка мобильных приложений, Разработка под Android, Kotlin] Retrofit2 на Android используя Kotlin
Автор
Сообщение
news_bot ®
Стаж: 6 лет 9 месяцев
Сообщений: 27286
Сегодня мы рассмотрим работу с Retrofit 2. Правды ради стоит отметить, что мы будем работать еще с 2 отдельными библиотеками, а именно Picasso и Spots-dialog.
Это статью я рекомендую к прочтению только для тех, кто еще не работал с Retrofit 2. Ведь в этой статье я буду описывать все максимально подробно, чтобы все поняли.
0. Создание проекта
Здесь все максимально просто, создаем новый проект в Android Studio, выбираем Empty Activity. Далее необходимо выбрать язык программирования, у нас это будет Kotlin.
1. Добавление зависимостей
Сейчас нам нужно добавить все необходимые библиотеки, поэтому мы заходим в build.gradle и добавляем следующие:
dependencies {
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:converter-gson:2.5.0'
implementation 'com.squareup.picasso:picasso:2.71828'
//noinspection GradleCompatible
implementation 'com.android.support:design:28.0.0'
implementation 'com.github.d-max:spots-dialog:1.1@aar'
}
Как вы уже могли заметить здесь мы добавили все необходимые библиотеки, в том числе и Spots progress dialog. Более подробно вы можете ознакомится с этим здесь. После чего в build.gradle(Modul:app) мы должны вставить это:
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
Осталось лишь зайти в manifests и добавить разрешение на использование телефона
<uses-permission android:name="android.permission.INTERNET"/>
2. Добавление data class'ов
Прежде чем перейти к второму пункту нам нужно узнать, а откуда получать данные? Парсить будет отсюда.
Отлично, далее копируем содержимое этого сайта и идем сюда. Сюда мы вставляем ранее скопированный текст с нашего сайта, после того как мы нажали на tree нам выдался список, раскроем его, теперь мы видим, что у нас есть 8 объектов. Если кто-то не понял, то я покажу вам скрин:
То что вы видите справа это наш текст, который мы скопировали, а то что справа, это уже обработанные данные.
Теперь вернемся к Android Studio мы создаем папку называем ее Model там мы создаем kotlin class и называем ее Movie из обычного класса мы преобразуем data class, мы просто перед class добавим data, а фигурные скобки заменяем на круглые, далее в скобках указываем переменные которые мы уже подсмотрели на сайте, кстати переменные должны быть нулабельного типа.
Полный код
SPL
data class Movie(
var name: String? = null,
var realname: String? = null,
var team: String? = null,
var firstapperance: String? = null,
var createdby: String? = null,
var publisher: String? = null,
var imageurl: String? = null,
var bio: String? = null
)
Если вы зададитесь вопросом, а почему папка называется Model, то я вам скажу, что:
Model — это логика, которая связанна с данными приложения. Другими словами это POJO, классы работы с API, базой данных.
3. Создание Client
Далее мы создаем папку Retrofit, а в папке мы создаем object, и называем его RetrofitClient, далее создаем переменную retrofit типа Retrofit, после этого создаем функцию и называем ее getCleint(baseUrl: String) и тип возвращаемого значения Retrofit. В теле функции необходимо выполнить проверку retrofit'a на null и если ретрофит равен null, то мы к ретрофиту присваиваем Retrofit.Builder() присоединяем baseUrl с параметром baseUrl далее присоединяем метод addconverterFactory c параметром GsonConverterFactory.create() и билдим с помощью метода build() и возвращаем ретрофит в ненулевой тип
Полный код
SPL
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
object RetrofitClient {
private var retrofit: Retrofit? = null
fun getClient(baseUrl: String): Retrofit {
if (retrofit == null) {
retrofit = Retrofit.Builder()
.baseUrl(baseUrl)
.addConverterFactory(GsonConverterFactory.create())
.build()
}
return retrofit!!
}
}
Builder в Retrofit — это экземпляр, который использует интерфейс и API Builder, чтобы задать определение конечной точки URL для операций HTTP
4. Работа с Interface
Interface - нужен для создания абстрактных классов.
Создаем пакет Interface в него мы кладем Interface и называем RetrofitServieces. Создаем Get запрос в скобках пишем кавычки, а в кавычках указывает ветку с которой будем парсить данные у нас это marvel. Но перед этим стоит сказать что такое GET и POST запрос
GET — запрашивает данные с определенного ресурса(сайта)
POST — отправляет данные на сервер для последующей обработки
Хорошо, теперь нужно создать функцию getMovieList, которая должна будет возвращать Call типа MutableList, a MutableList должен быть типа Movie
Полный код
SPL
import com.example.retrofitmarvel.Model.Movie
import retrofit2.Call
import retrofit2.http.*
interface RetrofitServices {
@GET("marvel")
fun getMovieList(): Call<MutableList<Movie>>
}
5. Common
Сейчас мы должны создать папку Common, в эту папку мы кладем object и называем его Common, создаем переменную, называем ее BASE_URL и в нее мы должны положить ссылку с которой парсим данные, но не класть последнюю ветку, так как именно с нее мы получаем данные. Создаем переменную retrofitServices, у нее есть метод get() к нему мы присваиваем RetrofitClient, а уже потом к RetrofitClient мы сетим метод getClient c параметром RetrofitServices::class.java
Полный код
SPL
import com.example.retrofitmarvel.Interface.RetrofitServices
import com.example.retrofitmarvel.Retrofit.RetrofitClient
object Common {
private val BASE_URL = "https://www.simplifiedcoding.net/demos/"
val retrofitService: RetrofitServices
get() = RetrofitClient.getClient(BASE_URL).create(RetrofitServices::class.java)
}
6. Макет
Переходим к activity_main.xml и добавляем туда RecyclerView
XML
SPL
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerMovieList"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
В папке layout создаем item_layout в root element указываем CardView
item_layout
SPL
<androidx.cardview.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:cardElevation="8dp"
android:layout_margin="8dp">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/linearLayout"
android:layout_width="match_parent"
android:layout_height="167dp">
<ImageView
android:id="@+id/image_movie"
android:layout_width="0dp"
android:layout_height="100dp"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/txt_name"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.238" />
<TextView
android:id="@+id/txt_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="192dp"
android:layout_marginLeft="192dp"
android:layout_marginTop="16dp"
android:text="name"
android:textColor="@android:color/black"
android:textSize="20sp"
android:textStyle="bold"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/txt_team"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="196dp"
android:layout_marginLeft="196dp"
android:layout_marginTop="8dp"
android:text="team"
android:textColor="@android:color/black"
android:textSize="16sp"
android:textStyle="normal"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/txt_name" />
<TextView
android:id="@+id/txt_createdby"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="184dp"
android:layout_marginLeft="184dp"
android:layout_marginTop="12dp"
android:text="createdby"
android:textColor="@android:color/black"
android:textSize="18sp"
android:textStyle="italic"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/txt_team" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
7. Adapter
Теперь мы должны создать пакет Adapter, в него мы кладем класс и называем его MyMovieAdapter
Adapter отвечает за извлечение данных из набора данных и за создание объектов View по основе этих данных.
В классе MyMovieAdapter мы создаем переменные, которые будут доступны только в этом классе private val movieList: MutableList типа Movie и указываем тип возвращаемого значения у нас это будет RecyclerView.Adapter типа MyMovieAdapter.MyViewHolder
Имплементируем методы, а именно onCreateViewHolder, getItemCount и onBindViewHolder.
Создаем класс MyViewHolder, в данном класс указываем параметр itemView: View и тип возвращаемого значения RecyclerView.ViewHolder и в тело данного класса мы помещаем переменные, например:
val image:ImageView = itemView.image_movie image_movie у нас тянется из item_layout
и так указываем для всех оставшихся view элементов.
Создам функцию bind c параметром listItem: Movie, здесь мы можем сделать наши view элементы кликабельными, я думаю вы умеете это делать.
Далее мы переделываем getItemCount() в override fun getItemCount() = movieList.size. Здесь все просто, мы создали функцию и возвращаем movieList.size. Отлично, осталось лишь разобраться с onBindViewHolder и onCreateViewHolder
onCreateViewHolder — создает новый объект ViewHolder всякий раз, когда RecyclerView нуждается в этом.
onBindViewHolder — принимает объект ViewHolder и устанавливает необходимые данные для соответствующей строки во view компоненте
Сейчас мы разберем случай c onCreateViewHolder тип возвращаемого значения MyViewHolder.
Создаем переменную itemView присваиваем ей LayoutInflater.from(parent.context).inflate(R.layout.item_layout, parent, false) и возвращаем MyViewHolder с параметром itemView. Теперь переходим к onBindViewHolder в теле мы создаем переменную listItem: Movie и присваиваем movieList[position]. Далее к holder'y мы присоединяем метод bind с параметрами listItem. Далее используем библиотеку Picasso.
Picasso.get().load(movieList[position].imageurl).into(holder.image). После чего добавляем holder.txt_name.text = movieList[position].name, и так мы делаем со всеми нашими view элементами
Полный код
SPL
import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import android.widget.Toast
import androidx.recyclerview.widget.RecyclerView
import com.example.retrofitmarvel.Model.Movie
import com.example.retrofitmarvel.R
import com.squareup.picasso.Picasso
import kotlinx.android.synthetic.main.item_layout.view.*
class MyMovieAdapter(private val context: Context,private val movieList: MutableList<Movie>):RecyclerView.Adapter<MyMovieAdapter.MyViewHolder>() {
class MyViewHolder(itemView: View): RecyclerView.ViewHolder(itemView){
val image: ImageView = itemView.image_movie
val txt_name: TextView = itemView.txt_name
val txt_team: TextView = itemView.txt_team
val txt_createdby: TextView = itemView.txt_createdby
fun bind(listItem: Movie) {
image.setOnClickListener {
Toast.makeText(it.context, "нажал на ${itemView.image_movie}", Toast.LENGTH_SHORT)
.show()
}
itemView.setOnClickListener {
Toast.makeText(it.context, "нажал на ${itemView.txt_name.text}", Toast.LENGTH_SHORT).show()
}
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
val itemView = LayoutInflater.from(parent.context).inflate(R.layout.item_layout, parent, false)
return MyViewHolder(itemView)
}
override fun getItemCount() = movieList.size
override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
val listItem = movieList[position]
holder.bind(listItem)
Picasso.get().load(movieList[position].imageurl).into(holder.image)
holder.txt_name.text = movieList[position].name
holder.txt_team.text = movieList[position].team
holder.txt_createdby.text = movieList[position].createdby
}
}
8. MainActivity
Отлично! Осталось совсем чуть-чуть. Переходим в MainActivity для начала мы создадим переменные, и чтобы не объявлять их типа null объявим их через lateinit var mService: RetrofitServices, нам необходимо создать еще 3 таких, а именно: LinearLayoutManager, MyMovieAdapter, AlertDialog. Вы можете назвать их как хотите, это роли не сыграет. В методе onCreate мы к RetrofitServices присваиваем Common.retrofitServices. На следующей строке к нашему recyclerView мы присоединяем setHasFixedSize(true) — благодаря этому методу мы сможем оптимизировать свой список, после мы к нашему layoutManager присваиваем LinearLayoutManager(this).
Layout Manager — это вещь, которая отвечает позиционирование View компонентов, которые больше не видны пользователю. Далее все также легко к нашему списку присоединяем layoutManager и уже к этому присваиваем layoutManager. Хорошо, теперь работа с библиотекой SpotsDialog. указываем ранее названную переменную с типом AlertDialog присваиваем SpotsDialog присоединяем метод Builder после этого присоединяем метод setCancelablec c параметром true к этому мы должны присоединить метод setContext c параметром this и присоединить метод build.
Теперь мы должны создать новую функцию за пределами метода onCreate назваться функция будет getAllMovieList. В теле этой функции мы должны указать наш dialog и присоединить к нему метод show()
далее к mService добавляем метод getMovieList .enqueue(object: Callback<MutableList> { )
Сейчас нам необходимо имплементировать методы, у нас их две onResponse и onFailure
и в onResponse, а именно в теле данного метода мы к adapter'y присваиваем
MyMovieAdapter(baseContext, response.body() as MutableList<Movie>)
далее к adapter'y присваиваем метод notifyDataSetChanged(). К нашему списку мы присоединяем adapter и присваиваем adapter. после к dialog присваиваем метод dismiss(). Это значит то, что наш диалог пропадет после того, как наши данные загрузятся.
Полный код
SPL
import android.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.recyclerview.widget.LinearLayoutManager
import com.example.retrofitmarvel.Adapter.MyMovieAdapter
import com.example.retrofitmarvel.Common.Common
import com.example.retrofitmarvel.Interface.RetrofitServices
import com.example.retrofitmarvel.Model.Movie
import com.example.retrofitmarvel.R
import dmax.dialog.SpotsDialog
import kotlinx.android.synthetic.main.activity_main.*
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
class MainActivity : AppCompatActivity() {
lateinit var mService: RetrofitServices
lateinit var layoutManager: LinearLayoutManager
lateinit var adapter: MyMovieAdapter
lateinit var dialog: AlertDialog
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
mService = Common.retrofitService
recyclerMovieList.setHasFixedSize(true)
layoutManager = LinearLayoutManager(this)
recyclerMovieList.layoutManager = layoutManager
dialog = SpotsDialog.Builder().setCancelable(true).setContext(this).build()
getAllMovieList()
}
private fun getAllMovieList() {
dialog.show()
mService.getMovieList().enqueue(object : Callback<MutableList<Movie>> {
override fun onFailure(call: Call<MutableList<Movie>>, t: Throwable) {
}
override fun onResponse(call: Call<MutableList<Movie>>, response: Response<MutableList<Movie>>) {
adapter = MyMovieAdapter(baseContext, response.body() as MutableList<Movie>)
adapter.notifyDataSetChanged()
recyclerMovieList.adapter = adapter
dialog.dismiss()
}
})
}
}
Отлично! В этой статье мы научились работать с Retrofit2 и помещать его в RecyclerView.
===========
Источник:
habr.com
===========
Похожие новости:
- [Программирование, Разработка мобильных приложений, GitHub] Используем бесплатные возможности Github Actions для CI/CD на Flutter-проекте
- [Разработка мобильных приложений, Разработка под Android] Чем опасен postDelayed
- [Тестирование IT-систем, Тестирование веб-сервисов, Kotlin] Kotlin. Автоматизация тестирования (часть 1). Kotest: Начало
- [Разработка мобильных приложений, Разработка под Android] Navigation Component-дзюцу, vol. 3 — Corner-кейсы
- [Разработка под iOS, Разработка игр, Разработка под Android, Unity, Дизайн игр] Alt: City Online. Как я в одиночку создавал «Gta Online» для мобильных устройств. Часть 1
- [Flutter, Разработка мобильных приложений] Flutter.dev: Continuous delivery с Flutter (перевод)
- [Gradle, Kotlin, Разработка мобильных приложений, Разработка под Android] Знакомство с App Gallery. Создаем аккаунт разработчика
- [Программирование, Scala] Scala мертва?
- [Информационная безопасность, Разработка под Android, Разработка под Windows, Системы обмена сообщениями] Хакеры из Ирана годами воровали личные данные и прослушивали пользователей Telegram
- [Информационная безопасность, IT-инфраструктура, Исследования и прогнозы в IT, IT-компании] Зона доступа: 30 способов, которые позволят разблокировать любой смартфон. Часть 1
Теги для поиска: #_razrabotka_mobilnyh_prilozhenij (Разработка мобильных приложений), #_razrabotka_pod_android (Разработка под Android), #_kotlin, #_retrofit_2, #_android, #_kotlin, #_razrabotka_mobilnyh_prilozhenij (
Разработка мобильных приложений
), #_razrabotka_pod_android (
Разработка под Android
), #_kotlin
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 15:00
Часовой пояс: UTC + 5
Автор | Сообщение |
---|---|
news_bot ®
Стаж: 6 лет 9 месяцев |
|
Сегодня мы рассмотрим работу с Retrofit 2. Правды ради стоит отметить, что мы будем работать еще с 2 отдельными библиотеками, а именно Picasso и Spots-dialog. Это статью я рекомендую к прочтению только для тех, кто еще не работал с Retrofit 2. Ведь в этой статье я буду описывать все максимально подробно, чтобы все поняли. 0. Создание проекта Здесь все максимально просто, создаем новый проект в Android Studio, выбираем Empty Activity. Далее необходимо выбрать язык программирования, у нас это будет Kotlin. 1. Добавление зависимостей Сейчас нам нужно добавить все необходимые библиотеки, поэтому мы заходим в build.gradle и добавляем следующие: dependencies {
implementation 'com.squareup.retrofit2:retrofit:2.9.0' implementation 'com.squareup.retrofit2:converter-gson:2.5.0' implementation 'com.squareup.picasso:picasso:2.71828' //noinspection GradleCompatible implementation 'com.android.support:design:28.0.0' implementation 'com.github.d-max:spots-dialog:1.1@aar' } Как вы уже могли заметить здесь мы добавили все необходимые библиотеки, в том числе и Spots progress dialog. Более подробно вы можете ознакомится с этим здесь. После чего в build.gradle(Modul:app) мы должны вставить это: compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } Осталось лишь зайти в manifests и добавить разрешение на использование телефона <uses-permission android:name="android.permission.INTERNET"/>
2. Добавление data class'ов Прежде чем перейти к второму пункту нам нужно узнать, а откуда получать данные? Парсить будет отсюда. Отлично, далее копируем содержимое этого сайта и идем сюда. Сюда мы вставляем ранее скопированный текст с нашего сайта, после того как мы нажали на tree нам выдался список, раскроем его, теперь мы видим, что у нас есть 8 объектов. Если кто-то не понял, то я покажу вам скрин: То что вы видите справа это наш текст, который мы скопировали, а то что справа, это уже обработанные данные. Теперь вернемся к Android Studio мы создаем папку называем ее Model там мы создаем kotlin class и называем ее Movie из обычного класса мы преобразуем data class, мы просто перед class добавим data, а фигурные скобки заменяем на круглые, далее в скобках указываем переменные которые мы уже подсмотрели на сайте, кстати переменные должны быть нулабельного типа. Полный кодSPLdata class Movie(
var name: String? = null, var realname: String? = null, var team: String? = null, var firstapperance: String? = null, var createdby: String? = null, var publisher: String? = null, var imageurl: String? = null, var bio: String? = null ) Если вы зададитесь вопросом, а почему папка называется Model, то я вам скажу, что: Model — это логика, которая связанна с данными приложения. Другими словами это POJO, классы работы с API, базой данных. 3. Создание Client Далее мы создаем папку Retrofit, а в папке мы создаем object, и называем его RetrofitClient, далее создаем переменную retrofit типа Retrofit, после этого создаем функцию и называем ее getCleint(baseUrl: String) и тип возвращаемого значения Retrofit. В теле функции необходимо выполнить проверку retrofit'a на null и если ретрофит равен null, то мы к ретрофиту присваиваем Retrofit.Builder() присоединяем baseUrl с параметром baseUrl далее присоединяем метод addconverterFactory c параметром GsonConverterFactory.create() и билдим с помощью метода build() и возвращаем ретрофит в ненулевой тип Полный кодSPLimport retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory object RetrofitClient { private var retrofit: Retrofit? = null fun getClient(baseUrl: String): Retrofit { if (retrofit == null) { retrofit = Retrofit.Builder() .baseUrl(baseUrl) .addConverterFactory(GsonConverterFactory.create()) .build() } return retrofit!! } } Builder в Retrofit — это экземпляр, который использует интерфейс и API Builder, чтобы задать определение конечной точки URL для операций HTTP 4. Работа с Interface Interface - нужен для создания абстрактных классов. Создаем пакет Interface в него мы кладем Interface и называем RetrofitServieces. Создаем Get запрос в скобках пишем кавычки, а в кавычках указывает ветку с которой будем парсить данные у нас это marvel. Но перед этим стоит сказать что такое GET и POST запрос GET — запрашивает данные с определенного ресурса(сайта) POST — отправляет данные на сервер для последующей обработки Хорошо, теперь нужно создать функцию getMovieList, которая должна будет возвращать Call типа MutableList, a MutableList должен быть типа Movie Полный кодSPLimport com.example.retrofitmarvel.Model.Movie
import retrofit2.Call import retrofit2.http.* interface RetrofitServices { @GET("marvel") fun getMovieList(): Call<MutableList<Movie>> } 5. Common Сейчас мы должны создать папку Common, в эту папку мы кладем object и называем его Common, создаем переменную, называем ее BASE_URL и в нее мы должны положить ссылку с которой парсим данные, но не класть последнюю ветку, так как именно с нее мы получаем данные. Создаем переменную retrofitServices, у нее есть метод get() к нему мы присваиваем RetrofitClient, а уже потом к RetrofitClient мы сетим метод getClient c параметром RetrofitServices::class.java Полный кодSPLimport com.example.retrofitmarvel.Interface.RetrofitServices
import com.example.retrofitmarvel.Retrofit.RetrofitClient object Common { private val BASE_URL = "https://www.simplifiedcoding.net/demos/" val retrofitService: RetrofitServices get() = RetrofitClient.getClient(BASE_URL).create(RetrofitServices::class.java) } 6. Макет Переходим к activity_main.xml и добавляем туда RecyclerView XMLSPL<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <androidx.recyclerview.widget.RecyclerView android:id="@+id/recyclerMovieList" android:layout_width="0dp" android:layout_height="0dp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> </androidx.constraintlayout.widget.ConstraintLayout> В папке layout создаем item_layout в root element указываем CardView item_layoutSPL<androidx.cardview.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="wrap_content" app:cardElevation="8dp" android:layout_margin="8dp"> <androidx.constraintlayout.widget.ConstraintLayout android:id="@+id/linearLayout" android:layout_width="match_parent" android:layout_height="167dp"> <ImageView android:id="@+id/image_movie" android:layout_width="0dp" android:layout_height="100dp" android:layout_marginEnd="8dp" android:layout_marginRight="8dp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toStartOf="@+id/txt_name" app:layout_constraintHorizontal_bias="0.0" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintVertical_bias="0.238" /> <TextView android:id="@+id/txt_name" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="192dp" android:layout_marginLeft="192dp" android:layout_marginTop="16dp" android:text="name" android:textColor="@android:color/black" android:textSize="20sp" android:textStyle="bold" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> <TextView android:id="@+id/txt_team" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="196dp" android:layout_marginLeft="196dp" android:layout_marginTop="8dp" android:text="team" android:textColor="@android:color/black" android:textSize="16sp" android:textStyle="normal" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/txt_name" /> <TextView android:id="@+id/txt_createdby" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="184dp" android:layout_marginLeft="184dp" android:layout_marginTop="12dp" android:text="createdby" android:textColor="@android:color/black" android:textSize="18sp" android:textStyle="italic" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/txt_team" /> </androidx.constraintlayout.widget.ConstraintLayout> </androidx.cardview.widget.CardView> 7. Adapter Теперь мы должны создать пакет Adapter, в него мы кладем класс и называем его MyMovieAdapter Adapter отвечает за извлечение данных из набора данных и за создание объектов View по основе этих данных. В классе MyMovieAdapter мы создаем переменные, которые будут доступны только в этом классе private val movieList: MutableList типа Movie и указываем тип возвращаемого значения у нас это будет RecyclerView.Adapter типа MyMovieAdapter.MyViewHolder Имплементируем методы, а именно onCreateViewHolder, getItemCount и onBindViewHolder. Создаем класс MyViewHolder, в данном класс указываем параметр itemView: View и тип возвращаемого значения RecyclerView.ViewHolder и в тело данного класса мы помещаем переменные, например: val image:ImageView = itemView.image_movie image_movie у нас тянется из item_layout и так указываем для всех оставшихся view элементов. Создам функцию bind c параметром listItem: Movie, здесь мы можем сделать наши view элементы кликабельными, я думаю вы умеете это делать. Далее мы переделываем getItemCount() в override fun getItemCount() = movieList.size. Здесь все просто, мы создали функцию и возвращаем movieList.size. Отлично, осталось лишь разобраться с onBindViewHolder и onCreateViewHolder onCreateViewHolder — создает новый объект ViewHolder всякий раз, когда RecyclerView нуждается в этом. onBindViewHolder — принимает объект ViewHolder и устанавливает необходимые данные для соответствующей строки во view компоненте Сейчас мы разберем случай c onCreateViewHolder тип возвращаемого значения MyViewHolder. Создаем переменную itemView присваиваем ей LayoutInflater.from(parent.context).inflate(R.layout.item_layout, parent, false) и возвращаем MyViewHolder с параметром itemView. Теперь переходим к onBindViewHolder в теле мы создаем переменную listItem: Movie и присваиваем movieList[position]. Далее к holder'y мы присоединяем метод bind с параметрами listItem. Далее используем библиотеку Picasso. Picasso.get().load(movieList[position].imageurl).into(holder.image). После чего добавляем holder.txt_name.text = movieList[position].name, и так мы делаем со всеми нашими view элементами Полный кодSPLimport android.content.Context
import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.widget.ImageView import android.widget.TextView import android.widget.Toast import androidx.recyclerview.widget.RecyclerView import com.example.retrofitmarvel.Model.Movie import com.example.retrofitmarvel.R import com.squareup.picasso.Picasso import kotlinx.android.synthetic.main.item_layout.view.* class MyMovieAdapter(private val context: Context,private val movieList: MutableList<Movie>):RecyclerView.Adapter<MyMovieAdapter.MyViewHolder>() { class MyViewHolder(itemView: View): RecyclerView.ViewHolder(itemView){ val image: ImageView = itemView.image_movie val txt_name: TextView = itemView.txt_name val txt_team: TextView = itemView.txt_team val txt_createdby: TextView = itemView.txt_createdby fun bind(listItem: Movie) { image.setOnClickListener { Toast.makeText(it.context, "нажал на ${itemView.image_movie}", Toast.LENGTH_SHORT) .show() } itemView.setOnClickListener { Toast.makeText(it.context, "нажал на ${itemView.txt_name.text}", Toast.LENGTH_SHORT).show() } } } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder { val itemView = LayoutInflater.from(parent.context).inflate(R.layout.item_layout, parent, false) return MyViewHolder(itemView) } override fun getItemCount() = movieList.size override fun onBindViewHolder(holder: MyViewHolder, position: Int) { val listItem = movieList[position] holder.bind(listItem) Picasso.get().load(movieList[position].imageurl).into(holder.image) holder.txt_name.text = movieList[position].name holder.txt_team.text = movieList[position].team holder.txt_createdby.text = movieList[position].createdby } } 8. MainActivity Отлично! Осталось совсем чуть-чуть. Переходим в MainActivity для начала мы создадим переменные, и чтобы не объявлять их типа null объявим их через lateinit var mService: RetrofitServices, нам необходимо создать еще 3 таких, а именно: LinearLayoutManager, MyMovieAdapter, AlertDialog. Вы можете назвать их как хотите, это роли не сыграет. В методе onCreate мы к RetrofitServices присваиваем Common.retrofitServices. На следующей строке к нашему recyclerView мы присоединяем setHasFixedSize(true) — благодаря этому методу мы сможем оптимизировать свой список, после мы к нашему layoutManager присваиваем LinearLayoutManager(this). Layout Manager — это вещь, которая отвечает позиционирование View компонентов, которые больше не видны пользователю. Далее все также легко к нашему списку присоединяем layoutManager и уже к этому присваиваем layoutManager. Хорошо, теперь работа с библиотекой SpotsDialog. указываем ранее названную переменную с типом AlertDialog присваиваем SpotsDialog присоединяем метод Builder после этого присоединяем метод setCancelablec c параметром true к этому мы должны присоединить метод setContext c параметром this и присоединить метод build. Теперь мы должны создать новую функцию за пределами метода onCreate назваться функция будет getAllMovieList. В теле этой функции мы должны указать наш dialog и присоединить к нему метод show() далее к mService добавляем метод getMovieList .enqueue(object: Callback<MutableList> { ) Сейчас нам необходимо имплементировать методы, у нас их две onResponse и onFailure и в onResponse, а именно в теле данного метода мы к adapter'y присваиваем MyMovieAdapter(baseContext, response.body() as MutableList<Movie>)
далее к adapter'y присваиваем метод notifyDataSetChanged(). К нашему списку мы присоединяем adapter и присваиваем adapter. после к dialog присваиваем метод dismiss(). Это значит то, что наш диалог пропадет после того, как наши данные загрузятся. Полный кодSPLimport android.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import androidx.recyclerview.widget.LinearLayoutManager import com.example.retrofitmarvel.Adapter.MyMovieAdapter import com.example.retrofitmarvel.Common.Common import com.example.retrofitmarvel.Interface.RetrofitServices import com.example.retrofitmarvel.Model.Movie import com.example.retrofitmarvel.R import dmax.dialog.SpotsDialog import kotlinx.android.synthetic.main.activity_main.* import retrofit2.Call import retrofit2.Callback import retrofit2.Response class MainActivity : AppCompatActivity() { lateinit var mService: RetrofitServices lateinit var layoutManager: LinearLayoutManager lateinit var adapter: MyMovieAdapter lateinit var dialog: AlertDialog override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) mService = Common.retrofitService recyclerMovieList.setHasFixedSize(true) layoutManager = LinearLayoutManager(this) recyclerMovieList.layoutManager = layoutManager dialog = SpotsDialog.Builder().setCancelable(true).setContext(this).build() getAllMovieList() } private fun getAllMovieList() { dialog.show() mService.getMovieList().enqueue(object : Callback<MutableList<Movie>> { override fun onFailure(call: Call<MutableList<Movie>>, t: Throwable) { } override fun onResponse(call: Call<MutableList<Movie>>, response: Response<MutableList<Movie>>) { adapter = MyMovieAdapter(baseContext, response.body() as MutableList<Movie>) adapter.notifyDataSetChanged() recyclerMovieList.adapter = adapter dialog.dismiss() } }) } } Отлично! В этой статье мы научились работать с Retrofit2 и помещать его в RecyclerView. =========== Источник: habr.com =========== Похожие новости:
Разработка мобильных приложений ), #_razrabotka_pod_android ( Разработка под Android ), #_kotlin |
|
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 15:00
Часовой пояс: UTC + 5