I have a vertical chat recycler-view
i am trying to show multiple horizontal recycler-view's
in which contain a "carousel
" of card views. I am able to inflate the horizontal views but when i try to add two of the same kind of horizontal view as independent items in the parent view i either get the new data added to the original and then displayed twice or if i clear the old array the new data replaces the old data in the recycler-view
and a second one is not added.
I am unsure if this is due to me not generating individual adapters per horizontal view or some array issue.
My adapter
generation, called in the onBindViewHolder
of the parent recycler-view:
fun generateAdapter(holder: ViewHolder): CarouselAdapter{
val layoutManager = LinearLayoutManager(appContext, LinearLayoutManager.HORIZONTAL, false )
holder.carouselView.layoutManager = layoutManager
val adapterCarousel = CarouselAdapter()
holder.carouselView.adapter = adapterCarousel
snapHelper.attachToRecyclerView(holder.carouselView)
holder.carouselView.addItemDecoration(ItemOffsetDecoration(12))
holder.carouselView.isNestedScrollingEnabled = false
layoutManager.isSmoothScrollbarEnabled = true
layoutManager.stackFromEnd = true
return adapterCarousel
}
Calling of data onto child recycler-view:
"rates" -> {
if (items[i].ratesData != null) {
val adapter = generateAdapter(holder)
for (j in 0 until (items[i].ratesData!!.size)) {
adapter.addCarousel(ChatNew(items[i].msgTime, null, null, null, items[i].ratesData!![j], null, null, null, null))
}
}
//ParseHelper.clearArrays()
}
Child adapter:
class CarouselAdapter : RecyclerView.Adapter<ViewHolderCarousel>() {
private val RATES = 1
private val IMG_BUTTON = 2
private val IMG_NO_BUTTON = 3
private val BLUE = 4
private val NO_IMG_BUTTON = 5
private val ERROR = 0
lateinit var type : String
var items: ArrayList<ChatNew> = ArrayList()
fun addCarousel(carousel: ChatNew){
items.add(carousel)
notifyItemInserted(itemCount)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolderCarousel {
return when(viewType) {
RATES -> RatesViewHolderNew(LayoutInflater.from(appContext).inflate(R.layout.carousel_rate, parent, false))
IMG_BUTTON -> ImgButtonViewHolder(LayoutInflater.from(appContext).inflate(R.layout.carousel_img_btn, parent, false))
IMG_NO_BUTTON -> ImgNoButtonViewHolder(LayoutInflater.from(appContext).inflate(R.layout.carousel_img_no_btn, parent, false))
NO_IMG_BUTTON-> NoImgButtonViewHolder(LayoutInflater.from(appContext).inflate(R.layout.carousel_no_img_btn, parent, false))
else -> BlueViewHolder(LayoutInflater.from(appContext).inflate(R.layout.carousel_noimg_nobtn, parent, false))
}
}
override fun getItemCount(): Int {
return items.size
}
override fun onBindViewHolder(holder: ViewHolderCarousel, i: Int) {
type = findType(holder)
when (type){
"rates" -> {
val ri = items[i]
//for (i in 0 until (ri.ratesData!!.size)){
holder.pnView.text = ri.ratesData?.pn
holder.mpView.text =ri.ratesData?.mp
holder.itView.text = ri.ratesData?.it
holder.brView.text = ri.ratesData?.br
holder.pfView.text = ri.ratesData?.pf
holder.aprcView.text = ri.ratesData?.aprc
holder.tpView.text = ri.ratesData?.tp
holder.headDivider!!.setBackgroundColor(ContextCompat.getColor(appContext!!, R.color.NWBlue))
// }
}
"carousel button" -> {
val ci = items[i]
holder.imgView.setImageResource(ci.carouselData?.img!!)
holder.number.text = ci.carouselData?.number
holder.title.text = ci.carouselData?.title
holder.content.text = ci.carouselData?.content
holder.magicString.text = ci.carouselData?.magicString
}
"img no button" -> {
val ci = items[i]
holder.imgViewNoBtn.setImageResource(ci.carouselData?.img!!)
holder.numberNoBtn.text = ci.carouselData?.number
holder.titleNoBtn.text = ci.carouselData?.title
holder.contentNoBtn.text = ci.carouselData?.content
holder.noButtonString.text = ci.carouselData?.noButtonString
}
"no img no button" -> {
val ci = items[i]
holder.imgViewNoImgNoBtn.setBackgroundColor(ContextCompat.getColor(appContext!!,R.color.NWBlue))
holder.numberNoImgNoBtn.text = ci.carouselData?.number
holder.titleNoImgNoBtn.text = ci.carouselData?.title
holder.contentNoImgNoBtn.text = ci.carouselData?.content
}
"no img button" -> {
val ci = items[i]
holder.imgViewNoImg.setBackgroundColor(ContextCompat.getColor(appContext!!,R.color.NWBlue))
holder.numberNoImg.text = ci.carouselData?.number
holder.titleNoImg.text = ci.carouselData?.title
holder.contentNoImg.text = ci.carouselData?.content
holder.magicStringNoImg.text = ci.carouselData?.magicString
}
}
}
override fun getItemViewType(i: Int): Int {
return when (items.isNotEmpty()) {
true -> {
when {
items[i].ratesData != null -> RATES
items[i].carouselData != null -> {
when (items[i].carouselData?.img != null) {
true -> {
return if (items[i].carouselData?.magicString != null) {
//has image and button
IMG_BUTTON
} else {
//has image but no button
IMG_NO_BUTTON
}
}
false -> {
return if (items[i].carouselData?.magicString != null) {
//has no image but button
NO_IMG_BUTTON
} else {
//has no image and no button
BLUE
}
}
}
}
else -> ERROR
}
}
false -> ERROR
}
}
fun findType(holder: ViewHolderCarousel): String {
return when (holder) {
is RatesViewHolderNew -> "rates"
is ImgButtonViewHolder -> "carousel button"
is ImgNoButtonViewHolder -> "img no button"
is NoImgButtonViewHolder -> "no img button"
is BlueViewHolder -> "no img no button"
else -> "error"
}
}
}
open class ViewHolderCarousel(view: View) : RecyclerView.ViewHolder(view) {
// looks at the view and finds components on that view
// carousel for rates
val headDivider: LinearLayout? = view.head_divider
val pnView = view.pn_view
val mpView = view.mp_view
val itView = view.it_view
val brView = view.br_view
val pfView = view.pf_view
val aprcView = view.aprc_view
val tpView = view.tp_view
//TODO: set up links for "r" sections
//carousel with img and button
val imgView = view.imageView_btn
val number = view.number_btn
val title = view.title_btn
val content = view.content_btn
val magicString = view.carousel_button_btn
//carousel with img but no button
val imgViewNoBtn = view.imageView_no_btn
val numberNoBtn = view.number_no_btn
val titleNoBtn = view.title_no_btn
val contentNoBtn = view.content_no_btn
val noButtonString = view.magic_string_no_btn
//carousel with no img or button
val imgViewNoImgNoBtn = view.imageView_no_img_no_btn
val numberNoImgNoBtn = view.number_no_img_no_btn
val titleNoImgNoBtn = view.title_no_img_no_btn
val contentNoImgNoBtn = view.content_no_img_no_btn
val imgViewNoImg = view.imageView_no_img
val numberNoImg = view.number_no_img
val titleNoImg = view.title_no_img
val contentNoImg = view.content_no_img
val magicStringNoImg = view.carousel_button_no_img
}
class RatesViewHolderNew(itemView: View) : ViewHolderCarousel(itemView)
class ImgButtonViewHolder(itemView: View) : ViewHolderCarousel(itemView)
class ImgNoButtonViewHolder(itemView: View) : ViewHolderCarousel(itemView)
class NoImgButtonViewHolder(itemView: View) : ViewHolderCarousel(itemView)
class BlueViewHolder(itemView: View) : ViewHolderCarousel(itemView)
Any ideas on how i could ensure that each time i add a new set of carousel data it gets added as an independent item in the parent view would be appreciated.
It turns out that you can fix this by having each addition to the parent adapter/view as an async task. Am unsure why this works but am not complaining.
doAsync {
adapter.addChatMessage(Chat(time, null, null, null, contentRates, null, null, null, null))
}