Why is my adapter not being called in my fragment? - android

I have the following adapter:
class HomeAdapter(val list: List<Team>, val fragment: HomeFragment) : RecyclerView.Adapter<HomeAdapter.ViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
return ViewHolder(LayoutInflater.from(fragment.context).inflate(R.layout.list_team, parent, false))
}
override fun getItemCount(): Int {
return list.size
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.position?.text = list[position].position.toString()
holder.number?.text = list[position].number
holder.name?.text = list[position].name
holder.puntuation?.text = list[position].puntuation.toString()
}
class ViewHolder(v: View) : RecyclerView.ViewHolder(v) {
var view: View = v
var position: TextView? = view.findViewById(R.id.textViewPosition)
var number: TextView? = view.findViewById(R.id.textViewNumber)
var name: TextView? = view.findViewById(R.id.textViewName)
var puntuation: TextView? = view.findViewById(R.id.textViewPuntuation)
}
}
And I have the following call in my fragment:
adapter = HomeAdapter(teams, fragment!!)
if (adapter?.list!!.isNullOrEmpty()) {
image_empty?.visibility = View.VISIBLE
} else {
recycler?.adapter = adapter
}
But my adapter is not being called. What am I doing wrong?

Related

Android: Values are not assigned when using data binding in my custom adapter

I'm trying to pass my binding variable for the adapter to the ViewHolder to assing values to the textviews in my adapter but the values are not assigned and the click listeners dont do anything.
Here's my adapter class:
class DoneAppointmentsAdapter(var context: DoneAppointmentsFragment, listener: ContentListener, var arrayList: List<Appointment>) :
RecyclerView.Adapter<DoneAppointmentsAdapter.ItemHolder>() {
private val listener: ContentListener = listener
private var binding: DoneAppointmentsAdapterBinding? = null
var activity = context
override fun onCreateViewHolder(
parent: ViewGroup,
viewType: Int
): ItemHolder {
val viewHolder = LayoutInflater.from(parent.context)
.inflate(R.layout.done_appointments_adapter, parent, false)
binding = DoneAppointmentsAdapterBinding.inflate(LayoutInflater.from(parent.context))
return ItemHolder(viewHolder,binding, parent.context)
}
override fun onBindViewHolder(holder: ItemHolder, position: Int) {
holder.bind(arrayList, listener)
}
override fun getItemCount(): Int {
return arrayList.size
}
class ItemHolder(view: View, var binding: DoneAppointmentsAdapterBinding?, val context: Context) : RecyclerView.ViewHolder(view) {
fun bind(listOfData: List<Appointment>, listener: ContentListener) {
val dataListItem = listOfData[adapterPosition]
binding?.donePatientItemName?.text = "${dataListItem.patientName}"
binding?.donePatientItemTime?.text = "Some date"
binding?.donePatientItemPatientInfo?.setOnClickListener {
tempAppointmentId = dataListItem.id
listener.onPatientHistoryViewClicked(dataListItem.requestedBy)
}
binding?.donePatientItemReviewCase?.setOnClickListener {
amendPrescriptionWarning(dataListItem,context)
}
binding.donePatientItemViewCase.setOnClickListener {
startPreview(dataListItem)
}
}
}
}
You have messed up inside onCreateViewHolder . you have created view twice once with the LayoutInflater.from(parent.context) and once with DoneAppointmentsAdapterBinding.inflate . There should be only one in this case onlyDoneAppointmentsAdapterBinding .
class DoneAppointmentsAdapter(var context: DoneAppointmentsFragment, listener: ContentListener, var arrayList: List<Appointment>) :
RecyclerView.Adapter<DoneAppointmentsAdapter.ItemHolder>() {
private val listener: ContentListener = listener
override fun onCreateViewHolder(
parent: ViewGroup,
viewType: Int
): ItemHolder {
val binding = DoneAppointmentsAdapterBinding.inflate(LayoutInflater.from(parent.context))
return ItemHolder(binding)
}
override fun onBindViewHolder(holder: ItemHolder, position: Int) {
holder.bind(arrayList, listener)
}
override fun getItemCount(): Int {
return arrayList.size
}
class ItemHolder (var binding: DoneAppointmentsAdapterBinding) : RecyclerView.ViewHolder(binding.root) {
fun bind(listOfData: List<Appointment>, listener: ContentListener) {
val dataListItem = listOfData[adapterPosition]
binding.donePatientItemName.text = "${dataListItem.patientName}"
binding.donePatientItemTime.text = "Some date"
binding.donePatientItemPatientInfo.setOnClickListener {
tempAppointmentId = dataListItem.id
listener.onPatientHistoryViewClicked(dataListItem.requestedBy)
}
binding.donePatientItemReviewCase.setOnClickListener {
amendPrescriptionWarning(dataListItem,binding.donePatientItemReviewCase.context)
}
binding.donePatientItemViewCase.setOnClickListener {
startPreview(dataListItem)
}
}
}
}
It should be like this . I have also removed extra useless arguments from ItemHolder .
To make it clear the problem with your code was RecyclerView.ViewHolder(view) you were passing view while you were doing all action and stuff on binding those holds are two different instances of View . Which should be fixed with above code.

How to change Base Adapter into Recycler View Adapter?

I'm new to programming and trying to figure out how to stream .mp3 files in recyclerview
How to convert my Base Adapter into Recycler View Adapter? is there a simple way?
I need to do this because eventually I need a seekbar in every view of the recycler
My Base Adapter in Main Activity:
class MainActivity : AppCompatActivity() {
var listSongs = ArrayList<SongFile>()
var adapter : MySongAdapter? = null
var mp : MediaPlayer? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
listSongs.add(SongFile("title1","https://firebasestorage...."))
listSongs.add(SongFile("title2","https://firebasestorage...."))
listSongs.add(SongFile("title3","https://firebasestorage...."))
listSongs.add(SongFile("title4","https://firebasestorage....."))
adapter = MySongAdapter(listSongs)
listview.adapter = adapter
}
inner class MySongAdapter : BaseAdapter {
var myListSong = ArrayList<SongFile>()
constructor(myListSong: ArrayList<SongFile>) : super() {
this.myListSong = myListSong
}
override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View {
var myview = layoutInflater.inflate(R.layout.mylayout,null)
var Song = this.myListSong[position]
myview.textView.text = Song.Title
myview.button.setOnClickListener {
if(myview.button.text == "STOP") {
mp!!.stop()
myview.button.text = "PLAY"
}
else{
mp = MediaPlayer()
try {
mp!!.setDataSource(Song.SongURL)
mp!!.prepare()
mp!!.start()
myview.button.text = "STOP"
}catch (e:Exception){}
}
}
return myview
}
override fun getItem(p0: Int): Any {
return myListSong[p0]
}
override fun getItemId(p0: Int): Long {
return p0.toLong()
}
override fun getCount(): Int {
return myListSong.size
}
}
}
My empty Recycler View Adapter:
class Adapter(context: Context, private val List: ArrayList<Model>) : RecyclerView.Adapter<Adapter.ViewHodler>() {
private val mContext: Context
init {
mContext = context
}
override fun onCreateViewHolder(parent: ViewGroup, p1: Int): Adapter.ViewHodler {
val row = LayoutInflater.from(mContext).inflate(R.layout.list_item,parent,false)
return ViewHodler(row)
}
override fun getItemCount(): Int {
return List.size
}
inner class ViewHodler(v : View) : RecyclerView.ViewHolder(v) {
val viewTitle = v.title
}
override fun onBindViewHolder(holder: ViewHodler, position: Int) {
val model = List[position]
holder.viewTitle!!.text = model.Title
}
}
`
inner class ViewHodler(v : View) : RecyclerView.ViewHolder(v) {
val viewTitle = v.findViewById(R.id.title) as TextView
val button = v.findViewById(R.id.button) as Button
}
override fun onBindViewHolder(holder: ViewHodler, position: Int) {
val model = List[position]
holder.viewTitle?.text = model.Title
holder.button.setOnClickListener {
if(holder.button.text == "STOP") {
mp?.stop()
myview.button.text = "PLAY"
}else{
mp = MediaPlayer()
try {
mp?.setDataSource(Song.SongURL)
mp?.prepare()
mp?.start()
myview.button.text = "STOP"
}catch (e:Exception){}
}
}
}`
You can also avoid the code in onBindViewHolder() and create a method ViewHolder something like onBind(file : SongFile) and pass the object to this method.

How to multiple selected item pass from Recyclerview to Activity?

There are two Recyclerview in same activity rv1 and rv2. Selected item of rv1 will show in rv2
rv1:
Here I select multiple items
rv2:
it should shows like this
Adapter class of rv1:
class ServiceJobAdapter(val context: Context, var list:ArrayList<JobRespo>,var listener:OnItemClick):
RecyclerView.Adapter<ServiceJobAdapter.ItemsCarrier>(){
var currentSelectedIndex= -1
var selectedItem = SparseBooleanArray()
var animationItemsIndex = SparseBooleanArray()
private val reverseAllAnimations = false
var holder:ItemsCarrier? =null
class ItemsCarrier(itemView: View) : RecyclerView.ViewHolder(itemView)
{
var jobName = itemView.findViewById<TextView>(R.id.job_name)
var jobPrice = itemView.findViewById<TextView>(R.id.job_price)
var iconBack = itemView.findViewById(R.id.icon_back) as RelativeLayout
var iconFront = itemView.findViewById(R.id.icon_front) as RelativeLayout
var iconContainer = itemView.findViewById(R.id.icon_container) as CardView
fun binde(jobRespo: JobRespo) {
jobName.text = jobRespo.repDesc
jobPrice.text="₹"+jobRespo.repRice
if (iconFront.visibility == View.VISIBLE)
{
jobRespo.setChecked(false)
}else{
jobRespo.setChecked(true)
}
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemsCarrier {
val view = LayoutInflater.from(context).inflate(R.layout.job_row,parent,false)
return ItemsCarrier(view)
}
override fun getItemCount(): Int {
return list.size
}
override fun onBindViewHolder(holder: ItemsCarrier, position: Int) {
this.holder = holder
holder.itemView.isActivated = selectedItem[position,false]
holder.binde(list[position])
applyIconAnimation(holder, position)
// apply click events
applyClickEvents(holder, position)
}
private fun applyClickEvents(holder: ItemsCarrier, position: Int) {
holder.iconContainer.setOnClickListener {
listener.onIconClicked(position)
listener.AllItem(list[position]) }
}
private fun applyIconAnimation(holder: ItemsCarrier, position: Int)
{
if (selectedItem.get(position, false)) {
holder.iconFront!!.visibility = View.GONE
resetIconYAxis(holder.iconBack)
holder.iconBack.visibility = View.VISIBLE
holder.iconBack.alpha = 1f
if (currentSelectedIndex == position) {
FlipAnimator.flipView(context, holder.iconBack, holder.iconFront, true)
resetCurrentIndex()
}
} else {
holder.iconBack.visibility = View.GONE
resetIconYAxis(holder.iconFront)
holder.iconFront.visibility = View.VISIBLE
holder.iconFront.alpha = 1f
if (reverseAllAnimations && animationItemsIndex.get(
position,
false
) || currentSelectedIndex == position
) {
FlipAnimator.flipView(context, holder.iconBack, holder.iconFront, false)
resetCurrentIndex() } } }
private fun resetIconYAxis(view: RelativeLayout?)
{
if (view!!.rotationY != 0f) {
view.rotationY = 0f
}
}
private fun resetCurrentIndex() {
currentSelectedIndex = -1
}
fun toggleSelection(pos: Int) {
currentSelectedIndex = pos
if (selectedItem.get(pos, false)) {
selectedItem.delete(pos)
animationItemsIndex.delete(pos)
} else {
selectedItem.put(pos, true)
animationItemsIndex.put(pos, true)
}
notifyItemChanged(pos)
}
fun getSelectedItems(): ArrayList<JobRespo>
{
val selectItems = ArrayList<JobRespo>()
for(item in list)
{
if (!item.isChecked())
{
selectItems.add(item)
}
}
return selectItems}}
Using Interface
interface OnItemClick{
fun onIconClicked(position: Int)
fun AllItem(jobs:JobRespo)}
Implement interface in Activity
override fun onIconClicked(position: Int) {
mAdapter!!.toggleSelection(position)
}
override fun AllItem(jobs: JobRespo) {
val selectedItems:ArrayList<JobRespo>
=mAdapter!!.getSelectedItems()
selectIte.addAll(selectedItems)
}
Adapter class of 2nd Recyclerview:
lass SelectItemAdapter(val context: Context, var list:List<JobRespo>): RecyclerView.Adapter<SelectItemAdapter.ItemsCarriers>(){
class ItemsCarriers(itemView: View) : RecyclerView.ViewHolder(itemView) {
var itemName = itemView.findViewById<TextView>(R.id.item_name)
var itemPrice= itemView.findViewById<TextView>(R.id.item_peice)
var itmDelet =itemView.findViewById<LinearLayout>(R.id.item_delete)
fun bind(job: JobRespo) {
itemName.text = job.repDesc
itemPrice.text = job.repRice }
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemsCarriers {
val root = LayoutInflater.from(context).inflate(R.layout.select_item_row,parent,false)
return ItemsCarriers(root)
}
override fun getItemCount(): Int {
return list.size
}
override fun onBindViewHolder(holder: ItemsCarriers, position: Int) {
holder.bind(list[position])}}
Now how can i pass multiselected data from one recyclerview to anathor recyclerview of same activity?
Thanks your consideration and guidded to me :)
You can create a method in a second adapter to update the selected value like below and use it when you getting selected items.
fun setSelectedData(data:ArrayList<JobRespo>){
this.list.clear()
this.list.addAll(data)
notifyDataSetChanged ();
}

Setting RecyclerView adapter into ViewPager2

I've created a RecyclerView with Horizontal Scrolling and PageSnapHelper. Now I think to replace RecyclerView with ViewPager2.? Can I simply set RecyclerView Adapter I've created earlier for new ViewPager2.?
Adapter Class goes here
class QuoteAdapter(
val context: Context,
val list: ArrayList<ResultsItem>
) : RecyclerView.Adapter<QuoteAdapter.QuoteViewHolder>() {
var i = 0;
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int):
QuoteViewHolder {
val view = LayoutInflater.from(context)
.inflate(R.layout.item_quote, parent, false)
return QuoteViewHolder(view)
}
override fun getItemCount() = list.size
override fun onBindViewHolder(holder: QuoteViewHolder, position: Int) {
holder.quote.text = list[position].quoteText
holder.quote_by.text = "- ${list[position].quoteAuthor}"
ColorStore()
if (position == 0) {
holder.quote_bg.setBackgroundColor(ContextCompat.getColor(context, R.color.md_blue_400))
} else {
holder.quote_bg.setBackgroundColor(ContextCompat.getColor(context, colorList.random()))
}
holder.quote_bg.setOnClickListener {
holder.quote_bg.setBackgroundColor(ContextCompat.getColor(context, colorList.random()))
}
}
class QuoteViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
val quote = itemView.quote_text
val quote_by = itemView.by_text
val quote_bg = itemView.quote_bg
}
}
I just set recyclerview adapter to viewpager2. It works.

OnClickListener Button inside the Adapter Class Crashing the App in Kotlin

I am trying to store the values from retrofit into a database by pressing a AddtoCartButton but app is getting crashed when I press this button. I am able to retrieve the result from retrofit without any issues but onclicklistener is the issue.
Code:
inner class MoviesAdapter : RecyclerView.Adapter<MoviesAdapter.MovieViewHolder>() {
private val movies: MutableList<Movie> = mutableListOf()
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MovieViewHolder {
return MovieViewHolder(layoutInflater.inflate(R.layout.item_movie_layout, parent, false))
}
override fun getItemCount(): Int {
return movies.size
}
override fun onBindViewHolder(holder: MovieViewHolder, position: Int) {
holder.bindModel(movies[position])
}
fun setMovies(data: List<Movie>) {
movies.addAll(data)
notifyDataSetChanged()
}
inner class MovieViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
val movieGenreTxt : TextView = itemView.findViewById(R.id.movieGenre)
val movieYearTxt : TextView = itemView.findViewById(R.id.movieYear)
val movieAvatarImage : ImageView = itemView.findViewById(R.id.movieAvatar)
val movieDescription: TextView =itemView.findViewById(R.id.movieDescription)
fun bindModel(movie: Movie) {
// movieTitleTxt.text = movie.name
movieGenreTxt.text = movie.menu
movieYearTxt.text = movie.price
Picasso.get().load(movie.picture).into(movieAvatarImage)
movieDescription.text=movie.description
var movieName:String= movie.name!!
var testvar=movie.name.toString()
}
}
}
fun addtocart(view: View)
{
Toast.makeText(context,"Success on Click", Toast.LENGTH_SHORT).show()
print testvar
}
Error:
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.Button.setOnClickListener(android.view.View$OnClickListener)' on a null object reference
Below code solves the purpose.
Code:
inner class MoviesAdapter : RecyclerView.Adapter<MoviesAdapter.MovieViewHolder>() {
private val movies: MutableList<Movie> = mutableListOf()
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MovieViewHolder {
return MovieViewHolder(layoutInflater.inflate(R.layout.item_movie_layout, parent, false))
}
override fun getItemCount(): Int {
return movies.size
}
override fun onBindViewHolder(holder: MovieViewHolder, position: Int) {
holder.bindModel(movies[position])
}
fun setMovies(data: List<Movie>) {
movies.addAll(data)
notifyDataSetChanged()
}
inner class MovieViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
val movieGenreTxt : TextView = itemView.findViewById(R.id.movieGenre)
val movieYearTxt : TextView = itemView.findViewById(R.id.movieYear)
val movieAvatarImage : ImageView = itemView.findViewById(R.id.movieAvatar)
val movieDescription: TextView =itemView.findViewById(R.id.movieDescription)
fun bindModel(movie: Movie) {
// movieTitleTxt.text = movie.name
movieGenreTxt.text = movie.menu
movieYearTxt.text = movie.price
Picasso.get().load(movie.picture).into(movieAvatarImage)
movieDescription.text=movie.description
var movieName:String= movie.name!!
var testvar=movie.name.toString()
val addtocart = itemView.findViewById<Button>(R.id.idCart)
addtocart!!.setOnClickListener {
print $testvar
Toast.makeText(context,"Success on Click", Toast.LENGTH_SHORT).show()
startActivity(intent) }
}
}
}

Categories

Resources