Save/Restore Fragment state with RecyclerView in Android - android

I have created an Android app, which connects to GitHub API and shows a list of repositories of certain user. List is shown by recyclerView. I'm trying to save and restore a list, when I'm switching fragments. I have tried to save a list to a variable and add this to recyclerView. But it doesn't work.
My Fragment:
class MainFragment : Fragment() {
lateinit var recyclerView: RecyclerView
var responseSave:List<GitHubPOJO> = ArrayList()
var posts: MutableList<GitHubPOJO> = ArrayList()
lateinit var btn:Button
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
val view = inflater.inflate(R.layout.fragment_main, container, false)
btn = view.findViewById(R.id.button)
btn.setOnClickListener {
posts = ArrayList()
val name:String = view!!.findViewById<EditText>(R.id.editText).text.toString()
recyclerView = view!!.findViewById(R.id.posts_recycle_view)
val layoutManager = LinearLayoutManager(this.activity!!)
recyclerView.layoutManager = layoutManager
val adapter = PostsAdapter(posts)
recyclerView.adapter = adapter
//HIDE KEYBOARD
val inputMethodManager = this.activity!!.getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager
if(activity!!.currentFocus !=null) {
inputMethodManager.hideSoftInputFromWindow(this.activity!!.currentFocus!!.windowToken, 0)
}
val service = Retrofit.Builder()
.baseUrl("https://api.github.com/") // CHANGE API
.addConverterFactory(GsonConverterFactory.create())
.build()
.create(GitHubService::class.java)
service.retrieveRepositories(name)
.enqueue(object : Callback<List<GitHubPOJO>> {
override fun onResponse(call: Call<List<GitHubPOJO>>, response: Response<List<GitHubPOJO>>) {
responseSave = response.body()!!
posts.addAll(responseSave)
response.body()?.forEach { println ("TAG_: $it")}
recyclerView.adapter?.notifyDataSetChanged()
}
override fun onFailure(call: Call<List<GitHubPOJO>>, t: Throwable) {
//Toast.makeText(this#MainFragment, "Error occurred while networking", Toast.LENGTH_SHORT).show()
}
})
recyclerView.addOnItemTouchListener(
ClickListener(this.activity!!, recyclerView, object : ClickListener.OnItemClickListener {
override fun onLongItemClick(view: View?, position: Int) {
}
override fun onItemClick(view: View, position: Int) {
val url = posts!![position].htmlUrl
println("URL = $url")
view.findNavController().navigate(MainFragmentDirections.actionMainFragmentToWebFragment(url))
}
})
)
}
return view
}
And there is my code onResume:
override fun onResume() {
super.onResume()
val adapter = PostsAdapter()
adapter.updateAdapterList(responseSave.toMutableList())
println("RESUME")
println(responseSave)
}
When I print responseSave I see that my list is there. But it doesn't appears in RecyclerView.
Fragments are swithced by standart navigation library.
Activity code:
class MainActivity : AppCompatActivity(){
private lateinit var navController: NavController
private lateinit var mNavView:NavigationView
private lateinit var mDrawerLayout:DrawerLayout
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
mDrawerLayout = findViewById(R.id.drawer_layout)
mNavView = findViewById(R.id.nav_view)
navController = this.findNavController(R.id.myNavHostFragment)
NavigationUI.setupActionBarWithNavController(this, navController,mDrawerLayout)
NavigationUI.setupWithNavController(mNavView, navController)
}
override fun onSupportNavigateUp(): Boolean {
val navController = this.findNavController(R.id.myNavHostFragment)
return NavigationUI.navigateUp(mDrawerLayout,navController)
}}
My RecyclerView Adapter code:
class PostsAdapter(private var posts: MutableList<GitHubPOJO>? = ArrayList()) : RecyclerView.Adapter<PostsAdapter.ViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val v = LayoutInflater.from(parent.context).inflate(R.layout.post_item, parent, false)
return ViewHolder(v)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val post = posts!![position]
holder.post.text = post.name
holder.site.text = post.fullName // Change what you wanna see
}
fun updateAdapterList(newList: MutableList<GitHubPOJO>) {
posts!!.clear()
posts!!.addAll(newList)
notifyDataSetChanged()
}
override fun getItemCount(): Int {
return posts?.size ?: 0
}
inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
var post: TextView = itemView.findViewById<View>(R.id.postitem_post) as TextView
var site: TextView = itemView.findViewById<View>(R.id.postitem_site) as TextView
}}

Add a method in your adapter thats something like;
fun updateAdapterList(newList: MutableList<GitHubPOJO>) {
oldList.clear()
oldList.addAll(newList)
notifyDataSetChanged()
}
Then call this in your onResume() and pass in your updated list

The problem is on your onResume method. You are not adding an Adapter and a LayoutManager to the RecylerView so it can't display the data. Try moving the RecylerView initalization code from the onClickListener to your onResume method:
recyclerView = view!!.findViewById(R.id.posts_recycle_view)
val layoutManager = LinearLayoutManager(this.activity!!)
recyclerView.layoutManager = layoutManager
val adapter = PostsAdapter(posts)
recyclerView.adapter = adapter
Although having this initialization code in your onCreateView method would be better since it's the first lifecycle method called when a fragment returns to the front view from the backstack.

Related

My recyclerview resets when I add or delete an item from a Table (with Room) in Kotlin

First of all, I am Spanish so my english is not good.
I have an app with Kotlin and room, and it has a Recyclerview.
I have 3 tables: coaster, user and favorite.
The user can add coasters to favorite, and this is done succesfully.
The problem that I have is that when the user clicks on the button to add or delete from favorites, the recyclerview resets, it displays again. So it scrolls to the top of the Screen, and also some odd spaces appears after the element.
I also have a function to search, and it happens the same: spaces appears after each element when I am searching.
I have tried everything: notifyItemChanged,
notifyDataSetChanged... it doesnt work! I also tried removing the observer once from the recyclerview...
My main activity:
class CoasterFragment : Fragment() {
lateinit var coasterListener: CoasterListener
lateinit var usuarioCoaster: List\<UsuarioCoaster\>
private lateinit var searchView: SearchView
private lateinit var cAdapter: CoasterRecyclerViewAdapter
private var \_binding: FragmentCoasterBinding? = null
private val binding get() = \_binding!!
private val viewModel: CoastersViewModel by viewModels()
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
_binding = FragmentCoasterBinding.inflate(inflater, container, false)
val root: View = binding.root
/* val livedata = viewModel.coasters()
livedata.observe(viewLifecycleOwner,object: Observer <List<CoasterFavorito>> {
override fun onChanged(it: List<CoasterFavorito>) {
createRecyclerView(it)
livedata.removeObserver(this)
}
})*/
viewModel.coasters().observe(viewLifecycleOwner){createRecyclerView(it)}
coasterListener = CoasterListenerImpl(requireContext(), viewModel)
searchView = binding.search
searchView.clearFocus()
searchView.setOnQueryTextListener(object: SearchView.OnQueryTextListener{
override fun onQueryTextSubmit(query: String?): Boolean {
if(query != null){
searchDatabase(query)
}
return true
}
override fun onQueryTextChange(query: String?): Boolean {
if(query != null){
searchDatabase(query)
}
return true
}
})
return root
}
fun createRecyclerView(coasters: List<CoasterFavorito>) {
cAdapter =
CoasterRecyclerViewAdapter(
coasters as MutableList<CoasterFavorito>,
coasterListener,
requireContext()
)
val recyclerView = binding.recyclerCoaster
recyclerView.apply {
layoutManager = LinearLayoutManager(context, RecyclerView.VERTICAL, false)
adapter = cAdapter
addItemDecoration(DividerItemDecoration(context, RecyclerView.VERTICAL))
cAdapter.notifyDataSetChanged()
}
}
fun searchDatabase(query: String) {
val searchQuery = "%$query%"
viewModel.searchDatabase(searchQuery).observe(viewLifecycleOwner) { createRecyclerView(it)
}
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
}
my adapter:
class CoasterRecyclerViewAdapter(val coasters: List<CoasterFavorito>, val listener: CoasterListener,
val context: Context, ) : RecyclerView.Adapter<CoasterRecyclerViewAdapter.ViewHolder>(){
class ViewHolder private constructor(val binding: CoasterItemBinding, private val listener: CoasterListener,
private val context: Context): RecyclerView.ViewHolder(binding.root){
fun relleno(data: CoasterFavorito){
binding.nombre.text = data.coaster.nombre
binding.parque.text = data.coaster.parque
binding.ciudad.text = data.coaster.ciudad
binding.provincia.text = data.coaster.provincia
binding.comunidad.text = data.coaster.comunidadAutonoma
Glide
.with(context)
.load(data.coaster.imagen)
.centerCrop()
.into(binding.imagen)
binding.check.isChecked = data.favorito
binding.check.setOnClickListener{
if (data.favorito) {
listener.delFavorito(data.coaster.id)
binding.check.isChecked = false
} else {
listener.addFavorito(data.coaster.id)
binding.check.isChecked = true
}
}
}
companion object{
fun crearViewHolder(parent: ViewGroup, listener: CoasterListener, adapter: CoasterRecyclerViewAdapter, context: Context):ViewHolder{
val layoutInflater = LayoutInflater.from(parent.context)
val binding = CoasterItemBinding.inflate(layoutInflater, parent, false)
return ViewHolder(binding, listener, context )
}
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ViewHolder.crearViewHolder(parent, listener, this, context)
override fun onBindViewHolder(holder: ViewHolder, position: Int) = holder.relleno(coasters[position])
override fun getItemCount() = coasters.size
}
interface CoasterListener {
fun addFavorito(id: Long)
fun delFavorito(id: Long)
}
I have tried everything: notifyItemChanged,
notifyDataSetChanged... it doesnt work! I also tried removing the observer once from the recyclerview...
Your createRecyclerView function should be invoked only once in a whole lifecycle of the Fragment. You should not create any new RecyclerView.Adapter, or set a LayoutManager to the RecyclerView every time your data set changes.
Therefore the Observer used in viewModel.coasters.observe() should only submit a new List to the existing Adapter and call .notifyDataSetChanged(), or other notifying functions.

How can I display firebase data in a fragment with recyclerview? Kotlin Android Studio

hello I have an activity that has a navigation bar and fragments inside, in one of my fragments I save data in firebase, I want to get those data and display it in other fragment with recycler view. I watched a tutorial on youtube to do it cuz my teacher didn't teach us anything, the issue is the fragment that was supposed the display the data shows nothing, it's blank but I didn't understand why cuz I'm really new to this, if someone can take a look at my code and help me I would really appreciate it
This is my data class
data class Event(var eventName: String, var eventTime:String?=null)
This is ViewModel
class EventViewModel :ViewModel() {
private val repository : EventRepository
private val _allEvents = MutableLiveData<List<Event>>()
val allEvents : LiveData<List<Event>> = _allEvents
init {
repository= EventRepository().getInstance()
repository.loadEvents(_allEvents)
}
}
This is Repository
class EventRepository {
private val databaseReference: DatabaseReference= FirebaseDatabase.getInstance().getReference("PetEvents")
#Volatile private var INSTANCE : EventRepository ?=null
fun getInstance() : EventRepository{
return INSTANCE ?: synchronized(this) {
val instance = EventRepository()
INSTANCE=instance
instance
}
}
fun loadEvents(eventList : MutableLiveData<List<Event>>){
databaseReference.addValueEventListener(object:ValueEventListener{
override fun onDataChange(snapshot: DataSnapshot) {
try {
val _eventList : List<Event> = snapshot.children.map { dataSnapshot ->
dataSnapshot.getValue(Event::class.java)!!
}
eventList.postValue(_eventList)
}
catch (e: Exception){
}
}
override fun onCancelled(error: DatabaseError) {
TODO("Not yet implemented")
}
})
}
}
This is Adapter
class EventAdapter : RecyclerView.Adapter<EventAdapter.MyViewHolder>() {
private var eventList =ArrayList<Event>()
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
val itemView = LayoutInflater.from(parent.context).inflate(
R.layout.event_item_cell,
parent, false
)
return MyViewHolder(itemView)
}
override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
val currentItem = eventList[position]
holder.eventName.text =currentItem.eventName
holder.eventTime.text =currentItem.eventTime
}
override fun getItemCount(): Int {
return eventList.size
}
fun updateEventList(eventList: List<Event>){
this.eventList.clear()
this.eventList.addAll(eventList)
notifyDataSetChanged()
}
class MyViewHolder(itemView: View): RecyclerView.ViewHolder(itemView){
val eventName :TextView = itemView.findViewById(R.id.txEventName)
val eventTime :TextView = itemView.findViewById(R.id.txEventTime)
}
}
And this is the fragment I wish to display the data
private lateinit var viewModel : EventViewModel
private lateinit var eventRecyclerView: RecyclerView
lateinit var adapter: EventAdapter
class MainFragment : Fragment() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment_main, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
eventRecyclerView=view.findViewById(R.id.recyclerView)
eventRecyclerView.layoutManager= LinearLayoutManager(context)
eventRecyclerView.setHasFixedSize(true)
adapter = EventAdapter()
eventRecyclerView.adapter= adapter
viewModel = ViewModelProvider(this).get(EventViewModel::class.java)
viewModel.allEvents.observe(viewLifecycleOwner, Observer {
adapter.updateEventList(it)
})
}
}
In my fragment xml I put a recycler view, there's no issue about that
And my item cell is a cardview idk if it has anything to with the problem I'm getting tho

How to clear RecyclerView when updating data?

I have a RecyclerView with a ListAdapter. The list that is shown in the RecyclerView comes from a Flow that is observed in the Fragment that the recyclerView is instantiated.
When the Fragment is created, the data are calculated too (in onViewCreated Method) .
In the first data-calculation the RecyclerView is empty, a progressBar is shown, then the data is calculated, the progressbar hides, and the RecyclerView is populated.
If I go again in this Fragment to re-calculate the data, the previous list is shown simultaneously with the progressbar, and then is updated.
I want every time that new data is calculated to NOT show the previous list (just like the first data-calculation), but can't find a way to do it.
I tried to clear() the currentList and notifyDataSetChanged() but it still happens.. Any ideas?
Here is the code:
Fagment:
#AndroidEntryPoint
class YourPlanFragment : Fragment(R.layout.fragment_your_plan) {
lateinit var navController: NavController
private lateinit var binding: FragmentYourPlanBinding
private val sharedViewModel: WorkoutPlansViewModel by activityViewModels()
private lateinit var appBarConfiguration: AppBarConfiguration
#Inject
lateinit var dataStore: UserPreferencesRepo
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
navController = Navigation.findNavController(view)
binding = FragmentYourPlanBinding.bind(view)
appBarConfiguration = AppBarConfiguration(navController.graph)
val toolbar = binding.yourPlanToolbar
toolbar.setupWithNavController(navController, appBarConfiguration)
val exerciseAdapter = DayListAdapter(DayListAdapter.OnClickListener {
navigateTo(sharedViewModel.weekIndex, it.dayNumber)
})
exerciseAdapter.currentList.clear()
exerciseAdapter.notifyDataSetChanged()
binding.recyclerViewYourPlan.apply {
adapter = exerciseAdapter
layoutManager = LinearLayoutManager(requireContext())
setHasFixedSize(true)
recycledViewPool.clear()
removeAllViews()
adapter?.notifyDataSetChanged()
}
if (!sharedViewModel.planGenerated) {
// Here the data is generated
sharedViewModel.onTriggerEvent(WorkoutPlansEvent.GetWorkoutPlanEvent)
} else if (sharedViewModel.planGenerated) {
sharedViewModel.onTriggerEvent(WorkoutPlansEvent.GetWeekEvent)
}
viewLifecycleOwner.lifecycleScope.launch {
viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) {
sharedViewModel.yourPlanState.collect { yourPlanState ->
when (yourPlanState.progressBarState) {
is ProgressBarState.Loading -> {
binding.progressBar.isVisible = true
}
is ProgressBarState.Idle -> {
binding.progressBar.isInvisible = true
}
}
exerciseAdapter.submitList(yourPlanState.planDays)
}
}
}
}
private fun navigateTo(
currentWeek: Int,
dayNumber: Int,
) {
val action =
YourPlanFragmentDirections.actionYourPlanFragmentToYourDayFragment(
currentWeek,
dayNumber
)
navController.navigate(action)
}
}
ListAdapter:
class DayListAdapter(private val onClickListener: OnClickListener) :
ListAdapter<Day, DayListAdapter.DayViewHolder>(ExerciseComparator()) {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): DayViewHolder {
val binding = ListItemDayBinding.inflate(LayoutInflater.from(parent.context), parent, false)
return DayViewHolder(binding)
}
override fun onBindViewHolder(holder: DayViewHolder, position: Int) {
val currentItem = getItem(position)
holder.itemView.setOnClickListener {
onClickListener.onClick(currentItem)
}
if (currentItem != null) {
holder.bind(currentItem)
}
}
class DayViewHolder(private val binding: ListItemDayBinding) :
RecyclerView.ViewHolder(binding.root) {
fun bind(day: Day) {
binding.apply {
dayNumber = day.dayNumber.toString()
executePendingBindings()
}
}
}
class ExerciseComparator : DiffUtil.ItemCallback<Day>() {
override fun areItemsTheSame(oldItem: Day, newItem: Day) =
oldItem.dayNumber == newItem.dayNumber
override fun areContentsTheSame(oldItem: Day, newItem: Day) =
oldItem == newItem
}
class OnClickListener(val clickListener: (day: Day) -> Unit) {
fun onClick(day: Day) = clickListener(day)
}
}
This is happing because of the activityViewModels() that will preserve the viewmodel based on activity lifecycle. Either create WorkoutPlansViewModel using viewmodels() or Try to clear the list from the WorkoutPlansViewModel when you are creating the fragment.

I am trying to infalte the activitymain.xml file but i don't know why adapter class is not being inflated

This my adapter class which is trying to inflate the recycler view with the video_View and the arraylist is ending up with the value 0. I have tried a lot of method to make it working but every time it is everytime not inflating the recyclerView.
Adapter class:
class Video_adapter(var videolist: ArrayList<String>):RecyclerView.Adapter<Video_adapter.ViewHolder>(){
class ViewHolder(view: CardView):RecyclerView.ViewHolder(view){
val video:VideoView = view.findViewById(R.id.video)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.video_view,parent,false) as CardView
Log.i("OnCreateView","OnCreateViewHolder is working")
return ViewHolder(view)
}
override fun getItemCount(): Int {
return videolist.size
Log.i("Video_list1",videolist.size.toString())
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
var video = videolist[position]
holder.video.setVideoURI(video.toUri())
holder.video.setOnTouchListener( View.OnTouchListener { v, event ->
if (event.action == MotionEvent.ACTION_DOWN){
holder.video.start()
}
true
})
}
}
This is my main kotlin file
class MainActivity : AppCompatActivity() {
lateinit var toolbar: androidx.appcompat.widget.Toolbar
lateinit var recyclerView: RecyclerView
lateinit var layoutManager: RecyclerView.LayoutManager
lateinit var recycleradpter:Video_adapter
lateinit var videolist: ArrayList<String>
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
toolbar = findViewById(R.id.toolbar)
recyclerView = findViewById(R.id.recycler_view)
layoutManager = LinearLayoutManager(this)
recyclerView.layoutManager = layoutManager
videolist = ArrayList()
getJson()
Log.i("Video_list",videolist.size.toString())
recycleradpter = Video_adapter(videolist)
Log.i("Video_list",videolist.size.toString())
recyclerView.adapter = recycleradpter
}
fun getJson(){
val url = "https://raw.githubusercontent.com/bikashthapa01/myvideos-android-app/master/data.json"
val queue = Volley.newRequestQueue(this)
//volley request
val request = JsonObjectRequest(Request.Method.GET,url,null,Response.Listener<JSONObject>{ response ->
try {
val categories = response.getJSONArray("categories")
for (i in 0 until categories.length()){
val category = categories.getJSONObject(i)
val videos = category.getJSONArray("videos")
for (i in 0 until videos.length()){
val video = videos.getJSONObject(i)
val source = video.getString("sources")
videolist.add(source)
Log.i("Url",source)
Toast.makeText(this,"Json request working",Toast.LENGTH_LONG).show()
}
}
}
catch (e:JSONException){
Log.i("error ",e.toString())
}
},Response.ErrorListener {error ->
Log.i("JSon_request_error",error.toString())
})
Log.i("Video_list",videolist.size.toString())
queue.add(request)
}
}
I am not able to find what is wrong with the code why it is not inflating the recycler view.
After the for loop in getJson method call
recycleradpter.notifyDataSetChanged() to refresh the RecyclerView.

No Adapter attached in Bottom Navigation

I am trying to display items in bottom navigation activity using recycler view but I am not getting the item values.
I have three layouts in my project activity_main.xml, list_row.xml and fragment_home.xml. Recycler view is in fragment_home.xml and list_row.xml contains two text views. I am not seeing any error in the code but in the log, I am getting No adapter attached message. Your help is highly appreciated.
Error:
E/RecyclerView: No adapter attached; skipping layout
Below is the HomeFragment.kt code.
class HomeFragment : Fragment() {
private var adapter:PersonListAdapter?=null
private var personList:ArrayList<Person>?=null
private var layoutManager: RecyclerView.LayoutManager?=null
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_home, container, false)
personList=ArrayList<Person>()
layoutManager= LinearLayoutManager(this.context)
adapter= PersonListAdapter(personList, this.context!!)
recyclerView.layoutManager=layoutManager
recyclerView.adapter=adapter
for (i in 0..16) {
val person = Person()
person.name="Hello" + i
person.age = 20 + i
personList!!.add(person)
}
adapter!!.notifyDataSetChanged()
}
}
MainActivity.kt code
class MainActivity : AppCompatActivity() {
private var adapter:PersonListAdapter?=null
private var personList:ArrayList<Person>?=null
private var layoutManager: RecyclerView.LayoutManager?=null
private val mOnNavigationItemSelectedListener = BottomNavigationView.OnNavigationItemSelectedListener {item->
when(item.itemId){
R.id.home -> {
println("home pressed")
replaceFragment(HomeFragment())
return#OnNavigationItemSelectedListener true
}
}
false
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
bottomNavigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener)
replaceFragment(HomeFragment())
}
private fun replaceFragment(fragment: Fragment){
val fragmentTransaction = supportFragmentManager.beginTransaction()
fragmentTransaction.replace(R.id.fragmentContainer, fragment)
fragmentTransaction.commit()
}
}
Data Class:
class PersonListAdapter(private val list: ArrayList<Person>?, private val context: Context): RecyclerView.Adapter<PersonListAdapter.ViewHolder>()
{
override fun getItemCount(): Int {
return list!!.size
}
override fun onCreateViewHolder(parent: ViewGroup, position: Int): ViewHolder {
val view= LayoutInflater.from(context).inflate(R.layout.list_row,parent,false)
return ViewHolder(view)
}
override fun onBindViewHolder(p0: ViewHolder, p1: Int) {
p0?.bindItem(list?.get(p1))
}
class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView)
{
fun bindItem(person: Person?)
{
var name: TextView =itemView.findViewById(R.id.name) as TextView
var age: TextView =itemView.findViewById(R.id.age) as TextView
name.text=person!!.name
age.text = person.age.toString()
}
}
}
The first thing you do in your HomeFragment's onCreateView() is returning your inflated layout. So all of your code inside onCreateView method is untouchable. Instead just hold a reference to your inflated layout and return it at the end.
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,savedInstanceState: Bundle?): View? {
val view = inflater.inflate(R.layout.fragment_home, container, false)
val recyclerView = view.findViewById<RecyclerView>(R.id.recyclerView)
personList=ArrayList<Person>()
layoutManager= LinearLayoutManager(this.context)
adapter= PersonListAdapter(personList, this.context!!)
recyclerView.layoutManager=layoutManager
recyclerView.adapter=adapter
for (i in 0..16) {
val person = Person()
person.name="Hello" + i
person.age = 20 + i
personList!!.add(person)
}
adapter!!.notifyDataSetChanged()
return view
}

Categories

Resources