diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index d5df8cf..95498ce 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,6 +1,7 @@ + >//single is an observable that emits one variable then closes it + +} \ No newline at end of file diff --git a/app/src/main/java/com/thanaa/countriesmvvm/model/CountriesService.kt b/app/src/main/java/com/thanaa/countriesmvvm/model/CountriesService.kt new file mode 100644 index 0000000..0de542e --- /dev/null +++ b/app/src/main/java/com/thanaa/countriesmvvm/model/CountriesService.kt @@ -0,0 +1,22 @@ +package com.thanaa.countriesmvvm.model + +import com.google.gson.Gson +import com.thanaa.countriesmvvm.di.DaggerApiComponent +import io.reactivex.Single +import retrofit2.Retrofit +import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory +import retrofit2.converter.gson.GsonConverterFactory +import javax.inject.Inject + +class CountriesService { + + @Inject + lateinit var api:CountriesAPI + init { + DaggerApiComponent.create().inject(this) + } + + fun getCountries(): Single> { + return api.getCountries() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/thanaa/countriesmvvm/model/Data.kt b/app/src/main/java/com/thanaa/countriesmvvm/model/Data.kt index f7d6bef..aa2a0a4 100644 --- a/app/src/main/java/com/thanaa/countriesmvvm/model/Data.kt +++ b/app/src/main/java/com/thanaa/countriesmvvm/model/Data.kt @@ -1,6 +1,10 @@ package com.thanaa.countriesmvvm.model +import com.google.gson.annotations.SerializedName -data class Country(var countryName: String?){ + +data class Country(@SerializedName("name")val countryName: String?, + @SerializedName("capital") val capital:String?, + @SerializedName("flagPNG")val flag:String?){ } \ No newline at end of file diff --git a/app/src/main/java/com/thanaa/countriesmvvm/util/Util.kt b/app/src/main/java/com/thanaa/countriesmvvm/util/Util.kt new file mode 100644 index 0000000..bc89b59 --- /dev/null +++ b/app/src/main/java/com/thanaa/countriesmvvm/util/Util.kt @@ -0,0 +1,16 @@ +package com.thanaa.countriesmvvm.util + +import android.content.Context +import android.widget.ImageView +import androidx.swiperefreshlayout.widget.CircularProgressDrawable + +fun getProgressDrawable(context: Context):CircularProgressDrawable{ + //progress than will be displayed in an image + return CircularProgressDrawable(context).apply { + strokeWidth = 10f + centerRadius = 50f + start() + } + + +} \ No newline at end of file diff --git a/app/src/main/java/com/thanaa/countriesmvvm/view/CountryListAdapter.kt b/app/src/main/java/com/thanaa/countriesmvvm/view/CountryListAdapter.kt index 90f4f58..14a13b8 100644 --- a/app/src/main/java/com/thanaa/countriesmvvm/view/CountryListAdapter.kt +++ b/app/src/main/java/com/thanaa/countriesmvvm/view/CountryListAdapter.kt @@ -1,28 +1,54 @@ package com.thanaa.countriesmvvm.view +import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import android.widget.ImageView import androidx.recyclerview.widget.RecyclerView +import androidx.swiperefreshlayout.widget.CircularProgressDrawable +import com.bumptech.glide.Glide +import com.bumptech.glide.request.RequestOptions +import com.thanaa.countriesmvvm.R import com.thanaa.countriesmvvm.model.Country +import com.thanaa.countriesmvvm.util.getProgressDrawable +import kotlinx.android.synthetic.main.activity_main.view.* +import kotlinx.android.synthetic.main.item_country.view.* -class CountryListAdapter(var countries:ArrayList):RecyclerView.Adapter() { +class CountryListAdapter(var countries:ArrayList):RecyclerView.Adapter() { - override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CountryViewHolder { - TODO("Not yet implemented") + fun updateCounties (newCountry:List){ + countries.clear() + countries.addAll(newCountry) + notifyDataSetChanged() } - + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = + CountryViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.item_country,parent,false)) override fun getItemCount()= countries.size override fun onBindViewHolder(holder: CountryViewHolder, position: Int) { holder.bind(countries[position]) } - class CountryViewHolder(view: View):RecyclerView.ViewHolder(view){ - fun bind (country:Country){ - } + class CountryViewHolder(view: View):RecyclerView.ViewHolder(view){ + private val imageView = view.imageView + private val capital = view.capital + private val countryName = view.name + private val progressDrawable = getProgressDrawable(view.context) + fun bind (country:Country){ + countryName.text = country.countryName + capital.text = country.capital + imageView.loadImage(country.flag, progressDrawable) } } -} \ No newline at end of file +} + +fun ImageView.loadImage(uri: String?, progressDrawable: CircularProgressDrawable) { +val options = RequestOptions().placeholder(progressDrawable).error(R.mipmap.ic_launcher) + Glide.with(this.context) + .setDefaultRequestOptions(options) + .load(uri) + .into(this) +} diff --git a/app/src/main/java/com/thanaa/countriesmvvm/view/MainActivity.kt b/app/src/main/java/com/thanaa/countriesmvvm/view/MainActivity.kt index d68185d..aad7f90 100644 --- a/app/src/main/java/com/thanaa/countriesmvvm/view/MainActivity.kt +++ b/app/src/main/java/com/thanaa/countriesmvvm/view/MainActivity.kt @@ -2,11 +2,64 @@ package com.thanaa.countriesmvvm.view import androidx.appcompat.app.AppCompatActivity import android.os.Bundle +import android.view.View +import android.widget.ListAdapter +import androidx.lifecycle.Observer +import androidx.lifecycle.ViewModel +import androidx.lifecycle.ViewModelProvider +import androidx.lifecycle.ViewModelProviders +import androidx.recyclerview.widget.GridLayoutManager +import androidx.recyclerview.widget.LinearLayoutManager +import androidx.recyclerview.widget.RecyclerView import com.thanaa.countriesmvvm.R +import com.thanaa.countriesmvvm.viewmodel.ListViewModel +import kotlinx.android.synthetic.main.activity_main.* class MainActivity : AppCompatActivity() { + lateinit var viewModel:ListViewModel + var countriesAdapter = CountryListAdapter(arrayListOf()) + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) + viewModel = ViewModelProviders.of(this).get(ListViewModel::class.java) + viewModel.refresh() + + countriesList.apply { + layoutManager = LinearLayoutManager(context) + adapter = countriesAdapter + } + swipeRefreshLayout.setOnRefreshListener { + swipeRefreshLayout.isRefreshing = false + viewModel.refresh() + } + + observeViewModel() + } + + private fun observeViewModel() { + + viewModel.countries.observe(this,Observer { countries -> + countries?.let { + countriesList.visibility = View.VISIBLE + countriesAdapter.updateCounties(it) + + } + }) + + viewModel.countryLoadError.observe(this, Observer { isError -> isError?.let { + list_error.visibility = if(it) View.VISIBLE else View.GONE + } }) + + viewModel.loading.observe(this, Observer { isLoading -> isLoading?.let{ + progressBar.visibility = if(it) View.VISIBLE else View.GONE + + if(it){ + list_error.visibility =View.GONE + countriesList.visibility = View.GONE + } + } }) + + + } } -} \ No newline at end of file diff --git a/app/src/main/java/com/thanaa/countriesmvvm/viewmodel/ListViewModel.kt b/app/src/main/java/com/thanaa/countriesmvvm/viewmodel/ListViewModel.kt index 7067174..94dbe37 100644 --- a/app/src/main/java/com/thanaa/countriesmvvm/viewmodel/ListViewModel.kt +++ b/app/src/main/java/com/thanaa/countriesmvvm/viewmodel/ListViewModel.kt @@ -2,25 +2,54 @@ package com.thanaa.countriesmvvm.viewmodel import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel +import com.thanaa.countriesmvvm.model.CountriesService import com.thanaa.countriesmvvm.model.Country +import io.reactivex.Scheduler +import io.reactivex.android.schedulers.AndroidSchedulers +import io.reactivex.disposables.CompositeDisposable +import io.reactivex.disposables.Disposable +import io.reactivex.observers.DisposableSingleObserver +import io.reactivex.schedulers.Schedulers class ListViewModel:ViewModel() { - + private val countriesService = CountriesService() + //disposable for cleaning the connection + private val disposable = CompositeDisposable() val countries = MutableLiveData>() val countryLoadError = MutableLiveData() val loading = MutableLiveData() - fun fetch(){ + fun refresh(){ fetchCountries() } private fun fetchCountries(){ - var mockData:List = listOf(Country("Saudi"),Country("US")) - countryLoadError.value = false - loading.value =false - countries.value = mockData - } + loading.value = true + disposable.add( + //called on a background thread + countriesService.getCountries() + .subscribeOn(Schedulers.newThread()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribeWith(object: DisposableSingleObserver>(){ + override fun onSuccess(value: List) { + countries.value = value + countryLoadError.value = false + loading.value = false + } + + override fun onError(e: Throwable) { + countryLoadError.value = true + loading.value = false + } + + }) + + ) + } + override fun onCleared(){ + disposable.clear() + } } \ No newline at end of file diff --git a/app/src/main/res/layout/item_country.xml b/app/src/main/res/layout/item_country.xml index 093ab24..065057b 100644 --- a/app/src/main/res/layout/item_country.xml +++ b/app/src/main/res/layout/item_country.xml @@ -3,8 +3,30 @@ xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="100dp"> + + + + + + + + \ No newline at end of file