I want to pass retrofit response to Activity so that i can set data in the recyclerview adapter. I don't want to use LiveData or RxJava.
Here imageDetails is the list of Json Object and I want to pass it to MainActivity.
TrendingViewModel.kt
class TrendingViewModel : ViewModel() {
fun fetchGifs() {
val apiService = GiphyApi().getClient()?.create(ApiInterface::class.java)
val call = apiService?.getTrendingResults(20, Constants.API_KEY)
var imageDetails: List<ImageDetails>
call?.enqueue(object : retrofit2.Callback<GiphyResponse> {
override fun onResponse(call: Call<GiphyResponse>?, response: Response<GiphyResponse>?) {
imageDetails = response?.body()?.data!!
}
override fun onFailure(call: Call<GiphyResponse>?, t: Throwable?) {
}
})
}}
MainActivity.kt
class MainActivity : AppCompatActivity() {
private lateinit var layoutManager: RecyclerView.LayoutManager
lateinit var adapter: RecyclerViewAdapter
lateinit var trendingViewModel: TrendingViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding: ActivityMainBinding = DataBindingUtil.setContentView(this, R.layout.activity_main)
val debugTree: Timber.DebugTree = Timber.DebugTree()
TrendingViewModel().fetchGifs()
Timber.plant(debugTree)
trendingViewModel = ViewModelProviders.of(this).get(TrendingViewModel::class.java)
trendingViewModel.fetchGifs()
layoutManager = GridLayoutManager(this, 3) as RecyclerView.LayoutManager
binding.recyclerview.layoutManager = layoutManager
adapter = RecyclerViewAdapter(this)
binding.recyclerview.adapter = adapter
adapter.setListData(//TODO I need the response data here)
}}
RecyclerViewAdapter.kt
Edit: Everthing is working fine but My list is getting updated after all the default function is called.
class RecyclerViewAdapter(context: Context) : RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder>(){
private var gifList: List<ImageDetails>? = Collections.emptyList()
private var mContext: Context? = null
init {
this.mContext = context
}
fun setListData(list: List<ImageDetails>) {
gifList=list
Log.i("Size SetListData", gifList!!.size.toString())
//Here it is showing List size 20
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder? {
val binding = DataBindingUtil.inflate<RecyclerviewListItemBinding>(LayoutInflater.from(parent.context), R.layout.recyclerview_list_item,
parent, false)
return ViewHolder(binding)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
//val binding = holder.binding;
Log.i("Size SizeBindHolder",gifList?.size.toString())
//Size = 0
/*Glide.with(mContext)
.load(gifList?.get(position)?.images?.dimen?.url)
.into(holder.imageView)*/
}
override fun getItemCount(): Int {
Log.i("Size ItemCount",gifList?.size.toString())
// Size = 0
return gifList?.size!!
}
class ViewHolder(var binding: RecyclerviewListItemBinding) : RecyclerView.ViewHolder(binding.root) {
var imageView: ImageView
init {
this.binding = binding
imageView = binding.imageView
}
}
1- in your activity add:
public class MainActivity extends AppCompatActivity implements Observer {
....
}
2- implement the method update() in your activity:
#Override
public void update(Observable o, Object arg) {
}
3- create an Observable object:
public class RetrofitObservable extends Observable {
private static RetrofitObservable instance = null;
public static RetrofitObservable getInstance() {
if(instance == null) {
instance = new RetrofitObservable();
}
return instance;
}
public void notifyObserverWithResponse(Object response) {
setChanged();
notifyObservers(response);
}
}
4- in your activity onResume() add this line:
RetrofitObservable.getInstance().addObserver(this);
5- in your activity onPause() add this line:
RetrofitObservable.getInstance().deleteObserver(this);
6- in your Retrofit response, call this line:
RetrofitObservable.getInstance(). notifyObserverWithResponse(yourResponseHere);
7- in your activity update method, handle your response:
#Override
public void update(Observable o, Object arg) {
YourRetrofitResponse response = (YourRetrofitResponse) arg;
// make your changes here
}
You can use pass your desired method which needs to be called as functional parameter, try below here fetchGifs accepts one method as parameter & in MainActivity we are passing adapter.setListData to it as parameter
class TrendingViewModel : ViewModel() {
fun fetchGifs(callback: (giphyResponse: GiphyResponse) -> Any) {
val apiService = GiphyApi().getClient()?.create(ApiInterface::class.java)
val call = apiService?.getTrendingResults(20, Constants.API_KEY)
var imageDetails: List<ImageDetails>
call?.enqueue(object : retrofit2.Callback<GiphyResponse> {
override fun onResponse(call: Call<GiphyResponse>?, response: Response<GiphyResponse>?) {
imageDetails = response?.body()?.data!!
callback(imageDetails)
}
override fun onFailure(call: Call<GiphyResponse>?, t: Throwable?) {
}
})
}}
class MainActivity : AppCompatActivity() {
private lateinit var layoutManager: RecyclerView.LayoutManager
lateinit var adapter: RecyclerViewAdapter
lateinit var trendingViewModel: TrendingViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding: ActivityMainBinding = DataBindingUtil.setContentView(this, R.layout.activity_main)
val debugTree: Timber.DebugTree = Timber.DebugTree()
Timber.plant(debugTree)
trendingViewModel = ViewModelProviders.of(this).get(TrendingViewModel::class.java)
trendingViewModel.fetchGifs()
layoutManager = GridLayoutManager(this, 3) as RecyclerView.LayoutManager
binding.recyclerview.layoutManager = layoutManager
adapter = RecyclerViewAdapter(this)
binding.recyclerview.adapter = adapter
TrendingViewModel().fetchGifs(result -> adapter.setListData(result))
}}
Related
I have an editText and a button. When I click on the button the data from the edittext gets inserted into the database. On the save activity I have recyclerView which will show the items getting from the viewModel. I have put the observer to observer the data but it is not showing any item in the recuclerView.
class MainActivity : AppCompatActivity(), NoteAdapter.OnItemClicked {
private lateinit var recyclerView: RecyclerView
private lateinit var btnAdd: Button
private lateinit var etNote: EditText
lateinit var viewModel: MyViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
recyclerView = findViewById(R.id.recyclerView)
btnAdd = findViewById(R.id.btn_add)
etNote = findViewById(R.id.et_note)
val mAdapter = NoteAdapter(this)
recyclerView.apply {
adapter = mAdapter
layoutManager = LinearLayoutManager(this#MainActivity)
}
viewModel = ViewModelProvider(this,
ViewModelProvider.AndroidViewModelFactory.getInstance(application))[MyViewModel::class.java]
viewModel.allNotes.observe(this, Observer {note->
note?.let {
mAdapter.submitList(it)
}
})
btnAdd.setOnClickListener {
addNote()
}
}
override fun onClick(note: Notes) {
viewModel.delete(note)
}
private fun addNote(){
val note: String = etNote.text.toString()
if(note.isNotEmpty()) {
viewModel.insert(Notes(note))
Toast.makeText(this, "$note inserted", Toast.LENGTH_SHORT).show()
}
}
}
Adapter Class
class NoteAdapter(private val clickListener: OnItemClicked)
: ListAdapter<Notes, NoteAdapter.MyViewHolder>(NoteComparator()) {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.note_item, parent, false)
val viewHolder = MyViewHolder(view)
viewHolder.ivDelete.setOnClickListener{
clickListener.onClick(getItem(viewHolder.adapterPosition))
}
return viewHolder
}
override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
val currentNote = getItem(position)
holder.apply {
tvNoteItem.text = currentNote.note
}
}
interface OnItemClicked{
fun onClick(note: Notes)
}
class MyViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
val tvNoteItem: TextView = itemView.findViewById(R.id.tv_note)
val ivDelete: ImageView = itemView.findViewById(R.id.iv_delete)
}
class NoteComparator : DiffUtil.ItemCallback<Notes>(){
override fun areItemsTheSame(oldItem: Notes, newItem: Notes): Boolean {
return oldItem == newItem
}
override fun areContentsTheSame(oldItem: Notes, newItem: Notes): Boolean {
return oldItem == newItem
}
}
}
ViewModel Class
class MyViewModel(application: Application) : AndroidViewModel(application) {
private val repository: NotesRepository
val allNotes : LiveData<List<Notes>>
init {
val dao = NoteDatabase.getDatabase(application).noteDao()
repository = NotesRepository(dao)
allNotes = repository.noteList
}
fun delete(note: Notes) = viewModelScope.launch(Dispatchers.IO) {
repository.delete(note)
}
fun insert(note: Notes) = viewModelScope.launch(Dispatchers.IO) {
repository.insert(note)
}
}
Heey Divyansh,
Analyzing your code I believe the problem is in your ViewModel. You are trying to change the property allNotes, which is a LiveData. You need mutable live data, so declare it like private because we can't expose a mutable property. And your allNotes property will receive the changes from this mutable property, like this:
class MyViewModel: ViewModel() {
private val _allNotes = MutableLiveData<List<Notes>>(emptyList())
val allNotes: LiveData<List<Notes>>
get() = _allNotes
}
Then, update the mutable live data:
class MyViewModel: ViewModel() {
// ...
init {
val dao = NoteDatabase.getDatabase(application).noteDao()
repository = NotesRepository(dao)
_allNotes.value = repository.noteList
}
}
I have found why it is not displaying the items because the viewModel is not inserting the the data as I have used Dispatcher.IO in the viewModel scope.
I removed it and now it is inserting and showing the items.
I use Callback pattern as a reaction of ClickListener, but I'm trying to use Coroutine at the moment.
Sometimes, so much of overlap of callback is hell.
When I click a item of RecyclerView, I want to know that position of item I clicked.
I made it with Channel and it works.
MainActivity.class
class MainActivity: Activity() {
private lateinit var binding: ActivityYoutubeFakeHomeBinding
private lateinit var myAdapter: MyAdapter
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityYoutubeFakeHomeBinding.inflate(layoutInflater)
setContentView(binding.root)
setView()
}
private fun setView() = scope.launch {
val positionChannel = Channel<Int>(Channel.UNLIMITED)
myAdapter = MyAdapter(this#MainActivity, positionChannel)
launch {
while(true) {
dialogUtil.showEdit(positionChannel.receive())
}
}
binding.run {
recyclerView.apply {
adapter = myAdapter
layoutManager = LinearLayoutManager(context)
}
}
}
}
MyAdapter.class
class MyAdapter(private val context: Context,
private val channel: Channel<Int>): RecyclerView.Adapter< MyAdapter.HomeViewHolder>() {
private val fakeHomeList = mutableListOf<FakeVideo>()
inner class HomeViewHolder(private val binding: ItemBinding): RecyclerView.ViewHolder(binding.root) {
fun bind(fakeVideo: FakeVideo) {
binding.run {
thumbnailImageView.setImageBitmap(fakeVideo.thumbnail)
titleTextView.text = fakeVideo.title
root.setOnClickListener {
CoroutineScope(Dispatchers.Default).launch {
channel.send(adapterPosition)
}
}
}
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): HomeViewHolder {
val binding = ItemBinding.inflate(LayoutInflater.from(parent.context), parent, false)
return HomeViewHolder(binding)
}
override fun onBindViewHolder(holder: HomeViewHolder, position: Int) {
holder.bind(fakeHomeList[position])
}
override fun getItemCount() = fakeHomeList.size
}
Yeah, it works. But I'm not sure whether this is the proper way.
Is there any better solution with Coroutine maybe like suspend function something?
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>> {
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 have an actitvity with Recyclerview which display data. Now I want to update my RecyclerView once got a new data.For now each time I close and reopen my app the new data will be displayed. but i want it without close to update my view.
I have tried this,
but nothing will work,
fun setupViewPager(viewPager: ViewPager, it: List<TransactionEntity>, incoming: TransactionAdapterDirection, mainActivity: MainActivity) {
val cc: Context = mainActivity.applicationContext
if(adapter.count < 2) {
if (incoming.equals(OUTGOING)) {
val gson = Gson()
val gson1 = GsonBuilder().create()
val model = it
val IT = gson.toJson(model)
val pref = cc.applicationContext.getSharedPreferences("MyPrefSend", 0)
val editor = pref.edit()
editor.putString("NEWIT_SEND", IT)
editor.apply()
adapter.addFragment(SendingFragment(),"SEND")
adapter.notifyDataSetChanged()
} else if (incoming.equals(INCOMING)) {
val gson = Gson()
val gson1 = GsonBuilder().create()
val model = it
val IT = gson.toJson(model)
val pref = cc.applicationContext.getSharedPreferences("MyPrefRec", 0)
val editor = pref.edit()
editor.putString("NEWIT_REC", IT)
editor.apply()
adapter.addFragment(ReceiveFragment(), "RECEIVE")
adapter.notifyDataSetChanged()
}
viewPager.adapter = adapter
}
}
class ViewPagerAdapter(manager: FragmentManager) : FragmentStatePagerAdapter(manager)
{
private val mFragmentList: ArrayList<Fragment> = ArrayList<Fragment>()
private val mFragmentTitleList: ArrayList<String> = ArrayList<String>()
override fun getCount(): Int {
return mFragmentList.size
}
override fun getItem(position: Int): Fragment? {
var fragment: Fragment? = null
if (position == 0) {
fragment = SendingFragment()
} else if (position == 1) {
fragment = ReceiveFragment()
}
return fragment
}
fun addFragment(fragment: Fragment, title: String) {
mFragmentList.add(fragment)
mFragmentTitleList.add(title)
}
override fun getPageTitle(position: Int): CharSequence? {
return mFragmentTitleList[position]
}
override fun getItemPosition(fragItem: Any): Int {
var position = 0
if (fragItem is ReceiveFragment) {
position = 0
} else if (fragItem is SendingFragment) {
position = 1
}
return if (position >= 0) position else PagerAdapter.POSITION_NONE
}
}
**Framgnet.kt**
class ReceiveFragment: Fragment()
{
private var linearLayoutManager: LinearLayoutManager? = null
fun fromJson(jsonString: String, type: Type): Any {
return Gson().fromJson(jsonString, type)
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val pref = context!!.getSharedPreferences("MyPrefRec", 0)
val mFragIT = pref.getString("NEWIT_REC", "")
val NewIT = fromJson(mFragIT,
object : TypeToken<List<TransactionEntity>>() {
}.type) as List<TransactionEntity>
val activity = activity as MainActivity
val myAppDatabaseData = activity.getAppDatabaseData()
val myNetwrk = activity.getNwtwrkData()
// Inflate the layout for this fragment
val rootView = inflater.inflate(R.layout.receive_fragment, container, false)
val recyclerView = rootView.findViewById<RecyclerView>(R.id.transaction_recycler_in) as RecyclerView
linearLayoutManager = LinearLayoutManager(activity, LinearLayout.VERTICAL, false)
recyclerView.layoutManager = linearLayoutManager
recyclerView.adapter = TransactionRecyclerAdapter(NewIT,myAppDatabaseData,TransactionAdapterDirection.INCOMING,myNetwrk)
recyclerView.setHasFixedSize(true)
return rootView
}
}
I have tried this, mAdapter.notifyDataSetChanged();
If you want to update data from activity/fragment than you can make one function inside adapter as below:
public void update(ArrayList<String> modelList){
//string arraylist is for example pass your data
// replace your adapter data with argument data
mAdapter.notifyDataSetChanged();
}
For kotlin:
fun update(modelList:ArrayList<String){
myList = modelList
myAdapter!!.notifyDataSetChanged()
}
Call this function from activity/fragment as below :
mAdapter.update(response.getList());
You can do it with a function in your ItemAdapter:
/**
* Refresh the whole data set of items.
*/
fun refreshDataset() {
mDataset = parseItems(mAppCtx)
notifyDataSetChanged()
}
and then, any time you receive a new set of data, you can call such function directly.
If you want to do in more Kotlin style do like this:
1) Create an abstract class for Adapter:
abstract class BaseRecyclerAdapter<Type, ViewHolder : BaseViewHolder<Type>>(list: List<Type> = mutableListOf()) : RecyclerView.Adapter<ViewHolder>() {
var items: MutableList<Type> = list.toMutableList()
set(value) {
field = value
notifyDataSetChanged()
}
override fun getItemCount() = items.size
enter code here
override fun onBindViewHolder(holder: ViewHolder, position: Int) = holder.bind(items[position]) }
2) Create an abstract class for ViewHolder:
abstract class BaseViewHolder<in T>(override val containerView: View): RecyclerView.ViewHolder(containerView), LayoutContainer {
abstract fun bind(item: T) }
3) How to use:
class MyActivity : AppCompatActivity() { private var adapter: MyAdapter? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.main_activity)
//This is your data which you set first time
val initData = mutableListOf<String>()
adapter = MyAdapter(initData)
myRecyclerView.layoutManager = adapter
myRecyclerView.layoutManager = LinearLayoutManager(this)
}
// Call this function when you need to update adapter
private fun notifyAdapter(list: MutableList<String>){
adapter.items = list
}}
Create MyAdapter:
private class MyAdapter(list: MutableList<String>) : BaseRecyclerAdapter<String, ViewHolder>(list) {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ViewHolder.newInstance(parent)
}
Create ViewHolder for MyAdapter:
private class ViewHolder(containerView: View) : BaseViewHolder<String>(containerView) {
companion object {
fun newInstance(parent: ViewGroup) = ViewHolder(parent.inflate(R.layout.item))
}
override fun bind(item: String) {
title.text = item
}}
Create item for ViewHolder:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.appcompat.widget.AppCompatTextView
android:id="#+id/title"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
If you have any questions please ask
You should try LiveData
LiveData is a data holder class that can be observed within a given
lifecycle. This means that an Observer can be added in a pair with a
LifecycleOwner, and this observer will be notified about modifications
of the wrapped data only if the paired LifecycleOwner is in active
state.
Documentation: https://developer.android.com/reference/android/arch/lifecycle/LiveData