Android Jetpack Compose – Retrofit2 Kullanımı
Androidin en profesyonel Web Service Client kütüphanelerinden olan Retrofit’in Retrofit2 sürümünü kullanarak Jetpack Compose projesinde verileri web sayfası üzerinden nasıl çekebileceğimiz konusuna değineceğiz. Hazırsak başlayalım…
Çıktı:
İnternet erişim izinlerimizi AndroidManifest.xml dosyamıza tanımlayalım;
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
application tag’i altına http/https bağlantılarının tamamını açabilmek için eklemeyi unutmayalım;
android:usesCleartextTraffic="true"
build.gradle dosyamıza gerekli kütüphanelerimizi tanımlayalım;
implementation "com.squareup.retrofit2:retrofit:2.9.0"
implementation "com.squareup.retrofit2:converter-gson:2.9.0"
implementation "com.squareup.okhttp3:okhttp:5.0.0-alpha.2"
implementation "io.coil-kt:coil-compose:1.3.2"
ardından projemize network, model, viewmodel klasörlerini/paketlerini oluşturalım.
Movie adında model paketimiz içerisine data class oluşturalım. Bu sınıf json verisini class’a deserialize edebilmek için gerekli olacaktır.
data class Movie(
val name:String,
val imageUrl:String,
val desc:String,
val category: String
)
network paketi altında ApiService adında interface oluşturalım;
interface ApiService {
}
verilerimizi çekeceğimiz dosyayı annotate edip, ilgili metodu Movie listesi formatında döndürelim.
interface ApiService {
@GET("movielist.json")
suspend fun getMovies() : List<Movie>
}
şimdi Api servisimizin hangi link üzerinden çalışacağını tanımlayacağımız ana tanımlayıcıyı oluşturup, Retrofit builder’dan instance üretelim.
interface ApiService {
@GET("movielist.json")
suspend fun getMovies() : List<Movie>
companion object{
var apiService:ApiService? = null
fun getInstance() : ApiService{
if(apiService == null){
apiService = Retrofit.Builder()
.baseUrl("http://serifgungor.com/demo/")
.addConverterFactory(GsonConverterFactory.create())
.build().create(ApiService::class.java)
}
return apiService!!
}
}
}
buradaki baseUrl üzerinden movielist.json yani http://serifgungor.com/demo/movielist.json adresi açıldığında getMovies metodumuz üzerinden verileri listeleyebilir duruma geleceğiz.
MovieViewModel adlı ViewModel’den türeyen bir sınıf üretelim ve bu sınıfı viewmodel paketine taşıyalım.
class MovieViewModel: ViewModel() {
}
Bu viewmodel web servisten gelen verileri view’a gönderebilmek için bir köprü görevi görecektir.
var movieListResponse:List<Movie> by mutableStateOf(listOf())
var errorMessage: String by mutableStateOf("")
getMovieList adlı fonksiyonu üretelim. Bu fonksiyon ApiService’deki getMovies fonksiyonundan dönen değeri movieListResponse’a iletebilme olanağı sağlayacaktır.
fun getMovieList(){
viewModelScope.launch {
val apiService = ApiService.getInstance()
try{
val movieList = apiService.getMovies()
movieListResponse = movieList
}catch (e:Exception){
errorMessage = e.message.toString()
}
}
}
activity paketine HomeUi adlı sınıf oluşturup, içerisine view’de göstereceğimiz görüntü için bir satır görüntüsü fonksiyonu üretelim;
@Composable
fun MovieItem(movie: Movie){
Card(
modifier = Modifier.padding(16.dp).fillMaxWidth().height(240.dp),
elevation = 4.dp) {
Column(
Modifier
.padding(4.dp)
.fillMaxSize(),
verticalArrangement = Arrangement.Center
){
Image(
painter = rememberImagePainter(data = movie.imageUrl,
builder = {
scale(Scale.FIT)
placeholder(R.drawable.ic_launcher_background)
}),
contentDescription = movie.desc,
contentScale = ContentScale.Crop,
modifier = Modifier
.fillMaxWidth()
.height(160.dp)
.clip(RoundedCornerShape(8.dp))
)
Text(text = movie.name, textAlign = TextAlign.Center, fontSize = 24.sp)
Text(text = movie.desc, textAlign = TextAlign.Left, fontSize = 18.sp)
}
}
}
Çağıracağımız ComponentActivity sınıfımızın içerisindeyken ilgili listeyi çağırıp verileri döndürelim;
class MainActivity : ComponentActivity() {
val movieViewModel by viewModels<MovieViewModel>()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colors.background
) {
MovieList(movieList = movieViewModel.movieListResponse)
movieViewModel.getMovieList()
}
}
}
}
verileri döndürebilmek için lazyColumn ile verileri iterate edelim;
@Composable
fun MovieList(movieList:List<Movie>){
LazyColumn{
itemsIndexed(items = movieList){index,item ->
MovieItem(movie = item)
}
}
}
Yabancı sitelerdeki gibi github paylaşsanız daha iyi olur sanki.
Merhabalar, github üzerinde de paylaşımları yapıp makaleleri güncellediğimde linklerini ekleyebilirim. Teşekkürler.