im trying to make an apps that use GitHub search user API with Retrofit.i want to make that when i type some username,it will show any github username related with it will be displayed on RecyclerView.is there something that i've missed or write wrongly?
since the apps run just fine,but when i try to search the username,it just show the 1 username type instead every username related to it.
here's my example to search username:
https://api.github.com/search/users?q=sidiqpermana
and heres some of my coding
RetrofitClient.kt
object RetrofitClient {
private const val BASE_URL = "https://api.github.com/"
private val retrofit = Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build()
val apiInstance = retrofit.create(Api::class.java)
}
Api.kt
interface Api {
#GET("search/users")
#Headers("Authorization: token N7QNdhhICaLmxSTzAWr70V7nqf6yaK4B6Z15")
fun getSearchUsers(
#Query("q") query: String
):Call<UserResponse>
}
UserResponse.kt
data class UserResponse(
val items : ArrayList<User>
)
UserAdapter.kt
class UserAdapter : RecyclerView.Adapter<UserAdapter.UserViewHolder>() {
private val list = ArrayList<User>()
fun setList(users: ArrayList<User>){
list.clear()
list.addAll(users)
notifyDataSetChanged()
}
inner class UserViewHolder(val binding: ItemUserBinding) : RecyclerView.ViewHolder(binding.root){
fun bind(user: User){
binding.apply {
Glide.with(itemView)
.load(user.avatar_url)
.transition(DrawableTransitionOptions.withCrossFade())
.centerCrop()
.into(tvUser)
tvUsername.text = user.login
}
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): UserViewHolder {
val view = ItemUserBinding.inflate(LayoutInflater.from(parent.context), parent, false)
return UserViewHolder((view))
}
override fun onBindViewHolder(holder: UserViewHolder, position: Int) {
holder.bind(list[position])
}
override fun getItemCount(): Int = list.size
}
MainActivity.kt
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
private lateinit var viewModel: MainViewModel
private lateinit var adapter: UserAdapter
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
adapter = UserAdapter()
adapter.notifyDataSetChanged()
viewModel= ViewModelProvider(this, ViewModelProvider.NewInstanceFactory()).get(MainViewModel::class.java)
binding.apply {
rvUser.layoutManager = LinearLayoutManager ( this#MainActivity)
rvUser.setHasFixedSize(true)
rvUser.adapter = adapter
btnSearch.setOnClickListener{
searchUser()
}
etQuery.setOnKeyListener { _, KeyCode, event ->
if (event.action == KeyEvent.ACTION_DOWN && KeyCode == KeyEvent.KEYCODE_ENTER){
searchUser()
return#setOnKeyListener true
}
return#setOnKeyListener false
}
}
viewModel.getSearchUsers().observe(this,{
if (it!=null){
adapter.setList(it)
showLoading(false)
}
})
}
private fun searchUser(){
binding.apply {
val query = etQuery.text.toString()
if (query.isEmpty()) return
showLoading(true)
viewModel.setSearchUsers(query)
}
}
private fun showLoading(state: Boolean){
if (state){
binding.progressBar.visibility = View.VISIBLE
}else{
binding.progressBar.visibility = View.GONE
}
}
}
MainViewModel.kt
class MainViewModel : ViewModel() {
val listUsers = MutableLiveData<ArrayList<User>>()
fun setSearchUsers(query: String){
RetrofitClient.apiInstance
.getSearchUsers(query)
.enqueue(object : Callback<UserResponse>{
override fun onResponse(
call: Call<UserResponse>,
response: Response<UserResponse>
) {
if (response.isSuccessful){
listUsers.postValue(response.body()?.items)
}
}
override fun onFailure(call: Call<UserResponse>, t: Throwable) {
t.message?.let { Log.d("Failure", it) }
}
})
}
fun getSearchUsers(): LiveData<ArrayList<User>>{
return listUsers
}
}
Related
I am trying to use an intent in an onClick method,the intent does work...but it doesn't want to change to the other activity
im looking everywhere but nothing seems wrong.
note:i dont know why FragmentPagerAdapter is deprecated
code:
MainActivity.kt
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
private lateinit var viewModel: MainViewModel
private lateinit var adapter: UserAdapter
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
adapter = UserAdapter()
adapter.notifyDataSetChanged()
adapter.setOnItemClickCallback(object : UserAdapter.OnItemClickCallback{
override fun onItemClicked(data: User) {
Intent(this#MainActivity, DetailUserActivity::class.java).also{
intent.putExtra(DetailUserActivity.EXTRA_USERNAME, data.login)
startActivity(intent)
}
}
})
viewModel= ViewModelProvider(this, ViewModelProvider.NewInstanceFactory())[MainViewModel::class.java]
binding.apply {
rvUser.layoutManager = LinearLayoutManager ( this#MainActivity)
rvUser.setHasFixedSize(true)
rvUser.adapter = adapter
btnSearch.setOnClickListener{
searchUser()
}
etQuery.setOnKeyListener { _, KeyCode, event ->
if (event.action == KeyEvent.ACTION_DOWN && KeyCode == KeyEvent.KEYCODE_ENTER){
searchUser()
return#setOnKeyListener true
}
return#setOnKeyListener false
}
}
viewModel.getSearchUsers().observe(this) {
if (it != null) {
adapter.setList(it)
showLoading(false)
}
}
}
private fun searchUser(){
binding.apply {
val query = etQuery.text.toString()
if (query.isEmpty()) return
showLoading(true)
viewModel.setSearchUsers(query)
}
}
private fun showLoading(state: Boolean){
if (state){
binding.progressBar.visibility = View.VISIBLE
}else{
binding.progressBar.visibility = View.GONE
}
}
}
UserAdapter.kt
class UserAdapter : RecyclerView.Adapter<UserAdapter.UserViewHolder>() {
private val list = ArrayList<User>()
private var onItemClickCallback: OnItemClickCallback? = null
fun setOnItemClickCallback (onItemClickCallback: OnItemClickCallback){
this.onItemClickCallback = onItemClickCallback
}
fun setList(users: ArrayList<User>){
list.clear()
list.addAll(users)
notifyDataSetChanged()
}
inner class UserViewHolder(private val binding: ItemUserBinding) : RecyclerView.ViewHolder(binding.root){
fun bind(user: User){
binding.root.setOnClickListener{
onItemClickCallback?.onItemClicked(list[adapterPosition])
}
binding.apply {
Glide.with(itemView)
.load(user.avatar_url)
.transition(DrawableTransitionOptions.withCrossFade())
.centerCrop()
.into(tvUser)
tvUsername.text = user.login
}
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): UserViewHolder {
val view = ItemUserBinding.inflate(LayoutInflater.from(parent.context), parent, false)
return UserViewHolder((view))
}
override fun onBindViewHolder(holder: UserViewHolder, position: Int) {
holder.bind(list[position])
}
override fun getItemCount(): Int = list.size
interface OnItemClickCallback{
fun onItemClicked(data: User)
}
}
DetailUserAdapter.kt
class DetailUserViewModel: ViewModel() {
val user= MutableLiveData<DetailUserResponse>()
fun setUserDetail(username: String){
RetrofitClient.apiInstance
.getUserDetail(username)
.enqueue(object : Callback<DetailUserResponse>{
override fun onResponse(
call: Call<DetailUserResponse>,
response: Response<DetailUserResponse>
) {
if (response.isSuccessful){
user.postValue(response.body())
}
}
override fun onFailure(call: Call<DetailUserResponse>, t: Throwable) {
t.message?.let { Log.d("Failure", it) }
}
})
}
fun getUserDetail(): LiveData<DetailUserResponse>{
return user
}
}
SectionPagerAdapter.kt
class SectionPagerAdapter(private val mCtx: Context, fm: FragmentManager) : FragmentPagerAdapter(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) {
#StringRes
private val TAB_TITLES = IntArray(R.string.tab_1)
override fun getCount(): Int = 2
override fun getItem(position: Int): Fragment {
var fragment: Fragment? = null
when(position){
0 -> fragment = FollowerFragment()
1 -> fragment = FollowingFragment()
}
return fragment as Fragment
}
override fun getPageTitle(position: Int): CharSequence? {
return mCtx.resources.getString(TAB_TITLES[position])
}
}
The code here has a minor issue:
Intent(this#MainActivity, DetailUserActivity::class.java).also{
intent.putExtra(DetailUserActivity.EXTRA_USERNAME, data.login)
startActivity(intent)
}
Here you are using .also, which passes the Intent you are creating as it however you are using intent for launching Activity which is the intent you get in your activity, the same you can get using getIntent(), this is causing this issue here.
Please change this to something similar to this and try:
Intent(this#MainActivity, DetailUserActivity::class.java).also{
it.putExtra(DetailUserActivity.EXTRA_USERNAME, data.login)
startActivity(it)
}
or may be similar to this:
Intent(this#MainActivity, DetailUserActivity::class.java).also{ launchIntent ->
launchIntent.putExtra(DetailUserActivity.EXTRA_USERNAME, data.login)
startActivity(launchIntent)
}
Thanks!
getting this error for enqueue for kotlin android and it is showing Unresolved reference: enqueue
my code
class NewsActivity : AppCompatActivity() {
private lateinit var mRecyclerView: RecyclerView
private lateinit var mProgressBar: ProgressBar
private lateinit var mAdapter: NewsAdapter
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_news)
mRecyclerView = findViewById(R.id.recycler_view)
mProgressBar = findViewById(R.id.progress_circular)
getItemList()
}
private fun getItemList() {
mProgressBar.visibility = View.VISIBLE
val apical = ApiClient.create().getData()
apical.enqueue(object : retrofit2.Callback<List<DataModelItem>> {
override fun onFailure(call: Call<List<DataModelItem>>, t: Throwable) {
mProgressBar.visibility = View.GONE
}
override fun onResponse(
call: Call<List<DataModelItem>>,
response: Response<List<DataModelItem>>) {
if (response.isSuccessful){
val itemListNews = response.body()!!
mAdapter = NewsAdapter(itemListNews)
val layoutManager = LinearLayoutManager(this#NewsActivity)
mRecyclerView.layoutManager = layoutManager
mRecyclerView.adapter = mAdapter
}
}
})
}
}
this is News activity
class NewsAdapter(private val itemList : List<DataModelItem>) : RecyclerView.Adapter<NewsAdapter.CustomViewHolder>() {
override fun onCreateViewHolder(
parent: ViewGroup,
viewType: Int
): NewsAdapter.CustomViewHolder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.item_view, parent, false)
return CustomViewHolder(view)
}
override fun getItemCount(): Int {
return itemList.size
}
override fun onBindViewHolder(holder: NewsAdapter.CustomViewHolder, position: Int) {
val itemData = itemList.get(position)
Picasso.get().load(itemData.images).into(holder.img1)
holder.Titlenews.setText(itemData.title)
holder.txt_description.setText(itemData.summary)
holder.publish_time.setText(itemData.publish_date)
}
inner class CustomViewHolder(view: View): RecyclerView.ViewHolder(view){
var img1:ImageView
var Titlenews: TextView
var txt_description: TextView
var publish_time: TextView
init {
img1 = view.findViewById(R.id.item_image)
Titlenews = view.findViewById(R.id.Titlenews)
txt_description = view.findViewById(R.id.txt_description)
publish_time = view.findViewById(R.id.publish_time)
}
}
}
this is the news adapter
object ApiClient {
var BASE_URL = ""
fun create() :Api{
val retrofit = Retrofit.Builder()
.addConverterFactory(GsonConverterFactory.create())
.baseUrl(BASE_URL)
.build()
return retrofit.create(Api::class.java)
}
}
this is Api client
Help required
I want not getting a solution as always it is giving me an error for enqueue .
Try changing
apical.enqueue(object : retrofit2.Callback<List<DataModelItem>> {
to
apical.enqueue(object : retrofit.Callback<List<DataModelItem>> {
The data in the RecyclerView is called the first time without issues. However when i refresh the data, for some reason all the items goes blank.
The MainActivity is this
class BusinessActivity : AppCompatActivity() {
private val businessViewModel: BusinessViewModel by viewModel()
private val imageLoader: ImageLoader by inject()
private lateinit var staggeredGridLayoutManager: StaggeredGridLayoutManager
private lateinit var skeleton: Skeleton
private val adapter: BusinessAdapter by lazy { BusinessAdapter(imageLoader, businessViewModel) }
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_business)
initToolbar()
skeleton = findViewById<SkeletonLayout>(R.id.skeletonLayout)
staggeredGridLayoutManager = StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL)
staggeredGridLayoutManager.gapStrategy = StaggeredGridLayoutManager.GAP_HANDLING_MOVE_ITEMS_BETWEEN_SPANS
recycler_view.apply {
layoutManager = staggeredGridLayoutManager
adapter = this#BusinessActivity.adapter
setHasFixedSize(true)
}
setupSkeleton()
initializeObserverBusiness()
refreshBusiness.setOnRefreshListener {
refreshBusiness.isRefreshing = true
skeleton.showSkeleton()
businessViewModel.retrieveBusiness()
}
}
private fun initToolbar() {
setSupportActionBar(toolbar)
supportActionBar?.title = getString(R.string.app_name)
this.setSystemBarColor(this)
}
private fun setupSkeleton(){
skeleton = recycler_view.applySkeleton(R.layout.business_card, 6)
skeleton.showSkeleton()
}
private fun initializeObserverBusiness(){
businessViewModel.uiState.observe(this, Observer {
val dataState = it ?: return#Observer
if (!dataState.showProgress){
refreshBusiness.isRefreshing = false
skeleton.showOriginal()
}
if (dataState.business != null && !dataState.business.consumed){
dataState.business.consume()?.let { business ->
adapter.submitList(business)
}
}
if (dataState.error != null && !dataState.error.consumed){
dataState.error.consume()?.let { error ->
Toast.makeText(this, resources.getString(error), Toast.LENGTH_LONG).show()
}
}
})
}
}
and the Adapter for the RecyclerView, im currently using DiffCallback and ListAdapter due to a better performance.
class BusinessAdapter(var imageLoader: ImageLoader, var viewModel: BusinessViewModel) : ListAdapter<Business, BusinessViewHolder>(DIFF_CALLBACK){
companion object{
private val DIFF_CALLBACK = object : DiffUtil.ItemCallback<Business>() {
override fun areItemsTheSame(oldItem: Business, newItem: Business) = oldItem.id == newItem.id
override fun areContentsTheSame(oldItem: Business, newItem: Business) = oldItem == newItem
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = BusinessViewHolder.create(parent)
override fun onBindViewHolder(holder: BusinessViewHolder, position: Int) {
holder.bind(getItem(position), imageLoader, viewModel)
}
}
and the ViewHolder for the Adapter
class BusinessViewHolder constructor(override val containerView: View) : RecyclerView.ViewHolder(containerView), LayoutContainer {
fun bind(business: Business, imageLoader: ImageLoader, viewModel: BusinessViewModel) {
businessImage?.let { imageLoader.load("${BuildConfig.MY_URL}/gallery/${business.images[0]}", it) }
ownerBusiness.text = business.owner
businessName.text = business.name
cardBusiness.setOnClickListener {
viewModel.callDetailBusiness(business.id)
}
}
companion object {
fun create(parent: ViewGroup): BusinessViewHolder {
return BusinessViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.business_card, parent, false))
}
}
}
and the ViewModel
class BusinessViewModel (private val businessRepository: BusinessRepository): ViewModel() {
private val _uiState = MutableLiveData<BusinessDataState>()
val uiState: LiveData<BusinessDataState> get() = _uiState
val _showDetailBusiness = MutableLiveData<Int?>()
val showDetailBusiness: LiveData<Int?> get() = _showDetailBusiness
init {
retrieveBusiness()
}
fun retrieveBusiness(){
viewModelScope.launch {
runCatching {
emitUiState(showProgress = true)
businessRepository.retrieveBusiness()
}.onSuccess {
emitUiState(business = Event(it))
}.onFailure {
emitUiState(error = Event(R.string.internet_failure_error))
}
}
}
fun callDetailBusiness(businessId: Int) {
_showDetailBusiness.value = businessId
}
private fun emitUiState(showProgress: Boolean = false, business: Event<List<Business>>? = null, error: Event<Int>? = null){
val dataState = BusinessDataState(showProgress, business, error)
_uiState.value = dataState
}
data class BusinessDataState(val showProgress: Boolean, val business: Event<List<Business>>?, val error: Event<Int>?)
}
When the data is loaded for the first time i see this.
however when i apply the SwipeRefresh. I receive the data.
D/OkHttp: [{"id":18,"name":"Whatsup","owner":"Mi
Soledad","category":"ToDo",
but the RecyclerView won't attach the new information...
I am getting started for using Mvvm architecture, but I am facing problem with my adapter -> It never called
I have an adapter here :
class LocationResultAdapter: RecyclerView.Adapter<LocationResultAdapter.ViewHolder>() {
private lateinit var resultList:List<ResultSearchBean>
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val binding: ItemPostBinding = DataBindingUtil.inflate(LayoutInflater.from(parent.context), R.layout.item_post, parent, false)
return ViewHolder(binding)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.bind(resultList[position])
}
override fun getItemCount(): Int {
return if (resultList.isNotEmpty()) {
resultList.size
} else {
0
}
}
fun updateList(list: List<ResultSearchBean>) {
resultList = list
notifyDataSetChanged()
}
class ViewHolder(private val binding: ItemPostBinding):RecyclerView.ViewHolder(binding.root){
private val viewModel = LocationViewModel()
fun bind(resultSearchBean: ResultSearchBean){
viewModel.bind(resultSearchBean)
binding.viewModel = viewModel
}
}
}
this adapter is called in my ViewModel
class LocationResultViewModel(private val resultSearchDao: ResultSearchDao): BaseViewModel() {
#Inject
lateinit var mFi9Api: Fi9Api
private lateinit var mSubscription: Disposable
var mSearchText: String = ""
val adapter: LocationResultAdapter = LocationResultAdapter()
override fun onCleared() {
super.onCleared()
mSubscription.dispose()
}
fun search(searchText: String) {
resultLocations(searchText)
}
private fun resultLocations(searchText: String) {
mSearchText = searchText
mSubscription = mFi9Api.getLocation(mSearchText)
.flatMap { resource ->
return#flatMap Observable.fromCallable {
resultSearchDao.deleteAll()
resultSearchDao.insertAll(resource.distinctBy { r -> r.label })
}
}
.concatMap {
return#concatMap resultSearchDao.all()
}
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribeWith(GetLocationListSubscriber())
}
inner class GetLocationListSubscriber : ResourceObserver<List<ResultSearchBean>>() {
override fun onNext(#NonNull t: List<ResultSearchBean>) {
adapter.updateList(t)
}
override fun onError(#NonNull e: Throwable) {
}
override fun onComplete() {
// Nothing to do
}
}
In my activity I have this following code :
class LocationResultActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
private lateinit var viewModel: LocationResultViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
binding.resultList.layoutManager = LinearLayoutManager(this, RecyclerView.VERTICAL, false)
viewModel = ViewModelProviders.of(this, ViewModelFactory(this)).get(LocationResultViewModel::class.java)
binding.viewModel = viewModel
search_btn.setOnClickListener {
viewModel.search(search_et.text.toString())
}
}
}
Only the method: adapter.updateList(t) is called.
I put some break point on onCreateViewHolder, OnBindViewHolder, getItemCount but it never called
What did I do that does not work?
Thank you for your help
I think you need to assign your adapter to your RecyclerView.
Try this:
binding.resultList.adapter = viewModel.adapter
I would like to show my items in a recycler view via RoomDatabase. But when I start application - it shows empty screen with only title.
It's an adapter for recycler view
class AlarmAdapter : ListAdapter<Alarm, AlarmAdapter.AlarmHolder>(DIFF_CALLBACK) {
private lateinit var alarmViewModel: AlarmViewModel
companion object {
private val DIFF_CALLBACK = object : DiffUtil.ItemCallback<Alarm>() {
override fun areItemsTheSame(oldItem: Alarm, newItem: Alarm): Boolean {
return oldItem.id == newItem.id
}
override fun areContentsTheSame(oldItem: Alarm, newItem: Alarm): Boolean {
return oldItem.days == newItem.days && oldItem.timeInMinutes == newItem.timeInMinutes
&& oldItem.departTimeInMinutes == newItem.departTimeInMinutes && oldItem.fromAddress == newItem.fromAddress
&& oldItem.toAddress == newItem.toAddress && oldItem.isEnabled == newItem.isEnabled
}
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): AlarmHolder {
val itemView = LayoutInflater.from(parent.context)
.inflate(R.layout.alarm_item, parent, false)
alarmViewModel = ViewModelProviders.of(parent.context as FragmentActivity).get(AlarmViewModel::class.java)
return AlarmHolder(itemView)
}
override fun onBindViewHolder(holder: AlarmHolder, position: Int) {
val currentAlarm = getItem(position)
holder.fromAddress.text = currentAlarm.fromAddress
// and other texts
holder.alarmSwitch.isEnabled = currentAlarm.isEnabled
holder.alarmSwitch.setOnClickListener {
holder.alarmSwitch.toggle()
currentAlarm.isEnabled = !currentAlarm.isEnabled
alarmViewModel.update(currentAlarm)
}
}
inner class AlarmHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
internal var fromAddress = itemView.findViewById<TextView>(R.id.alarm_item_from_address)
// and other resources
}
}
Here is a part of MainActivity
class MainActivity : AppCompatActivity() {
companion object {
private const val DAY_MINUTES = 24 * 60
}
private var currentEditAlarmDialog: EditAlarmDialog? = null
private lateinit var alarmViewModel: AlarmViewModel
private lateinit var adapter: AlarmAdapter
private lateinit var layoutManager: LinearLayoutManager
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
delegate.localNightMode = AppCompatDelegate.MODE_NIGHT_YES
setContentView(R.layout.activity_main)
layoutManager = LinearLayoutManager(this)
recycler_view.layoutManager = layoutManager
recycler_view.setHasFixedSize(true)
adapter = AlarmAdapter()
recycler_view.adapter = adapter
alarmViewModel = ViewModelProviders.of(this).get(AlarmViewModel::class.java)
alarmViewModel.getAllAlarms().observe(this, Observer<List<Alarm>> {
adapter.submitList(it)
})
}
AlarmViewModel class
class AlarmViewModel(application: Application) : AndroidViewModel(application) {
private val repository = AlarmRepository(application)
private val allAlarms = repository.getAllAlarms()
fun insert(alarm: Alarm) {
repository.insert(alarm)
}
fun update(alarm: Alarm) {
repository.update(alarm)
}
fun delete(alarm: Alarm) {
repository.delete(alarm)
}
fun deleteAllAlarms() {
repository.deleteAllNotes()
}
fun getAllAlarms() = allAlarms
fun getAlarmById(id: Int) = repository.getAlarmById(id)
}
It is a repository
class AlarmRepository(application: Application) {
private var alarmDao: AlarmDao
private var allAlarms: LiveData<List<Alarm>>
private val uiScope = CoroutineScope(Dispatchers.IO)
init {
val database: AlarmDatabase = AlarmDatabase.getInstance(application.applicationContext)!!
alarmDao = database.alarmDao()
allAlarms = alarmDao.getAllAlarms()
}
fun getAllAlarms() = allAlarms
fun insert(alarm: Alarm) {
uiScope.launch { alarmDao.insert(alarm) }
}
fun delete(alarm: Alarm) {
uiScope.launch { alarmDao.delete(alarm) }
}
fun deleteAllNotes() {
uiScope.launch { alarmDao.deleteAllAlarms() }
}
fun update(alarm: Alarm) {
uiScope.launch { alarmDao.update(alarm) }
}
fun getAlarmById(id: Int) = alarmDao.getAlarmById(id)
}
And the Dao class
#Dao
interface AlarmDao {
#Insert
fun insert(alarm: Alarm)
#Delete
fun delete(alarm: Alarm)
#Update
fun update(alarm: Alarm)
#Query("DELETE FROM alarm_table")
fun deleteAllAlarms()
#Query("SELECT * FROM alarm_table ORDER BY days ASC")
fun getAllAlarms() : LiveData<List<Alarm>>
#Query("SELECT * FROM alarm_table WHERE id = :id")
fun getAlarmById(id: Int) : Alarm
}
What can I do to solve this problem?
If you need more code - just tell me about that!
In your AlarmViewModel class, put the call to the repo in the getAllAlarms method.
fun getAllAlarms() {
repository.getAllAlarms()
}
remove this from init method
allAlarms = alarmDao.getAllAlarms()
and put
fun getAllAlarms() = alarmDao.getAllAlarms()