I'm new to Kotlin and trying to use ViewModel with retrofit to call responses, problem is retrofit won't call anything so nothing showed up.
Tried messing around with ViewModels where it's called
Tried generating new POJO from GSON
Put uses-permission INTERNET inside AndroidManifest
class MovieView(context: Context) : ViewModel() {
private val API_KEY: String = context.getString(R.string.api)
private val TAG = MovieView::class.java!!.getSimpleName()
private var resultsItem: MutableLiveData<List<ResultsItem>>? = null
fun getData(): LiveData<List<ResultsItem>> {
if (resultsItem == null) {
resultsItem = MutableLiveData()
loadData()
}
return resultsItem as MutableLiveData<List<ResultsItem>>
}
fun loadData() {
val apiInterface = ApiClient.getList().create(ApiInterface::class.java)
val responseCall = apiInterface.getMovieList(API_KEY)
responseCall.enqueue(object : Callback<Response> {
override fun onResponse(call: Call<Response>, response: retrofit2.Response<Response>) {
val resultsItemList = response.body()!!.results
resultsItem?.value = resultsItemList
Log.d(TAG,"response")
}
override fun onFailure(call: Call<Response>, t: Throwable) {
Log.d(TAG, "null")
}
})
}
}
Expected response from retrofit but none were found, null was also not there means it wasn't even executed.
EDIT :
class MovieFragment : Fragment() {
companion object {
fun newInstance() = MovieFragment()
}
private lateinit var viewModel: MovieView
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
recycler.setHasFixedSize(true)
recycler.layoutManager = LinearLayoutManager(context)
recycler.adapter = MovieAdapter(viewModel.getData(), this.context!!)
viewModel = ViewModelProviders.of(this).get(MovieView::class.java)
return inflater.inflate(R.layout.movie_fragment, container, false)
}
}
and
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
MovieFragment movieFragment = new MovieFragment();
getSupportFragmentManager().beginTransaction().add(R.id.framelayout, movieFragment);
resultsItem
has to be an immutable property which is observed by the Activity/Fragment and then you need to call just loadData()
. fun getData()
isn't even needed here.
As for the call not executing.. Are you sure nothing is really executed? Not onResponse
neither onFailure
? That doesn't seem possible to me. Maybe put t.printStackTrace()
inside onFailure
and see in the LogCat if there's this stacktrace.
Edit:
Add commit
to your fragment transaction in MainActivity
, like that:
getSupportFragmentManager()
.beginTransaction()
.add(R.id.framelayout, movieFragment)
.commit();
Also you should observe your LiveData
inside fragment:
val adapter = MovieAdapter(this.context!!)
recycler.adapter = adapter
viewModel = ViewModelProviders.of(this).get(MovieView::class.java)
viewModel.resultsItem.observe(this, Observer { adapter.update(it) })
viewModel.loadData()
And add a factory for your ViewModel:
private val factory = object: ViewModelProvider.Factory {
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
return MovieView([email protected]!!) as T
}
}
viewModel = ViewModelProviders.of(this, factory).get(MovieView::class.java)