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)
        }
    }
}

You may also like...

2 Responses

  1. Emre dedi ki:

    Yabancı sitelerdeki gibi github paylaşsanız daha iyi olur sanki.

    • serif dedi ki:

      Merhabalar, github üzerinde de paylaşımları yapıp makaleleri güncellediğimde linklerini ekleyebilirim. Teşekkürler.

Bir cevap yazın

E-posta hesabınız yayımlanmayacak.