I have a recycler view issue where the data is not being displayed. onCreateViewHolder and onBindViewHolder are not being called. When I call notifyDataSetChanged(), notifyChanged() is called but mObservers is empty, so it won't update my list.
public void notifyChanged() {
for (int i = mObservers.size() - 1; i >= 0; i--) {
mObservers.get(i).onChanged();
}
}
here's my adapter code:
class ReleasesAdapter : RecyclerView.Adapter<ReleasesAdapter.ReleasesViewHolder>() {
private val data = mutableListOf<Album>(Album())
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ReleasesViewHolder {
return ReleasesViewHolder(
LayoutInflater.from(parent.context)
.inflate(R.layout.song_item, parent, false)
)
}
override fun onBindViewHolder(holder: ReleasesViewHolder, position: Int) {
holder.bindView(data[position])
}
override fun getItemCount(): Int {
return data.size
}
fun setItems(items: List<Album>) {
data.addAll(items)
notifyDataSetChanged()
}
inner class ReleasesViewHolder(
override val containerView: View
) : RecyclerView.ViewHolder(containerView), LayoutContainer {
fun bindView(item: Album) {
containerView.nameTv.text = item.name
}
}
}
And here's my activity code:
#AndroidEntryPoint
class MainActivity : AppCompatActivity(), Contract.View {
#Inject
lateinit var presenter: Contract.Presenter
private val releasesAdapter = ReleasesAdapter()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
resultsRv.run {
adapter = releasesAdapter
layoutManager = LinearLayoutManager(this#MainActivity)
}
presenter.loadNewReleases()
}
override fun showReleases(data: List<Album>) {
releasesAdapter.setItems(data)
}
override fun showErrorMessage(message: String) {
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.appcompat.widget.LinearLayoutCompat xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".presentation.MainActivity">
<com.google.android.material.appbar.MaterialToolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"/>
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/resultsRv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:listitem="#layout/song_item" />
</androidx.appcompat.widget.LinearLayoutCompat>
song_item.xml
<?xml version="1.0" encoding="utf-8"?>
<com.google.android.material.textview.MaterialTextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/nameTv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="#dimen/song_item_margin"
android:textColor="#color/black" />
Please send help :(
Edit: Added Xml code
I believe you are using the scope functions wrong especially run in this case. Use run() function if you need to compute some value or want to limit the scope of multiple local variables.
So while your other code seems okay, I believe your Adapter and LayoutManager is not being assigned. I would suggest you replace the run with apply and try again.
resultsRv.apply {
adapter = releasesAdapter
layoutManager = LinearLayoutManager(this#MainActivity)
}
Related
I'm using Kotlin to create an event that generates a toast message on click of a recyclerview. I run into trouble making a Tost message in a recyclerview event.
I tried the following page, but couldn't solve it.
Toast message is not working in Recycler View
error code is
in kotlin & None of the following functions can be called with the arguments supplied: public open fun makeText(p0: Context!, p1: CharSequence!, p2: Int): Toast! defined in android.widget.Toast public open fun makeText(p0: Context!, p1: Int, p2: Int): Toast! defined in android.widget.Toast
PrintActivity.kt
package com.questionbank
class PrintActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val vBinding = ActivityPrintBinding.inflate(layoutInflater)
setContentView(vBinding.root)
val helper = SqliteHelper(this, "myDB.sql", 1)
var recyclerViewAdapter = CustomAdapter()
recyclerViewAdapter.listData = helper.select()
vBinding.myRecyclerView.adapter = recyclerViewAdapter
vBinding.myRecyclerView.layoutManager = LinearLayoutManager(this)
vBinding.myRecyclerView.addItemDecoration(
DividerItemDecoration(this, DividerItemDecoration.VERTICAL)
)
}
class CustomAdapter : RecyclerView.Adapter<CustomAdapter.Holder>() {
var listData = ArrayList<questionType>()
inner class Holder(val vBinding: QuestionLayoutRecyclerBinding) :
RecyclerView.ViewHolder(vBinding.root) {
fun setData(id:Int?, question: String, answer: String, exp: String) {
vBinding.printId.text=id.toString()
vBinding.myLinear.setOnClickListener {
// error occur
Toast.makeText(this#PrintActivity, "test", Toast.LENGTH_SHORT).show()
}
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): Holder {
val vBinding = QuestionLayoutRecyclerBinding.inflate(
LayoutInflater.from(parent.context),
parent,
false
)
return Holder(vBinding)
}
override fun onBindViewHolder(holder: Holder, position: Int) {
val question = listData[position]
holder.setData(question.id, question.question, question.answer, question.exp)
}
override fun getItemCount(): Int {
return listData.size
}
}
}
activity_print
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".PrintActivity">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/myRecyclerView"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginStart="32dp"
android:layout_marginTop="32dp"
android:layout_marginEnd="32dp"
android:layout_marginBottom="32dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
question_layout_recycler.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/myLinear"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="10dp">
<TextView
android:id="#+id/printId"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="TextView" />
</LinearLayout>
Two ways to fix,
Make CustomAdapter class as inner class.
innner class CustomAdapter : RecyclerView.Adapter<CustomAdapter.Holder>() {
So toast function it will take constant from activity class.
In viewholder, get context from view. it.context will get context from linearlayout.
vBinding.myLinear.setOnClickListener {
Toast.makeText(it.context, "test", Toast.LENGTH_SHORT).show()
}
Its recommended to place adapter logic in separate file and use second solution.
So you dont need to make adapter as inner class.
My app shows multiple ImageButton with recycleview, everything works fine, what i want is when a person clicks a Imagebutton, they will be directed to the activity "monactivitefinal" and keep the content of "article.ifram" so that I use it on this new activity.
all the Imagebutton redirect to the same activity "monactivitefinal" only the variable "article.ifram" that changes
This is my code :
class Article(var id: Int, var nom: String, var lienimg: String, var ifram: String){
}
class ArticleAdapter(var articles: ArrayList<Article>) : RecyclerView.Adapter<ArticleAdapter.MyViewHolder>(){
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
var vue=LayoutInflater.from(parent.context).inflate(
R.layout.listevisitess,
parent,
false
)
return MyViewHolder(vue)
}
override fun getItemCount(): Int {
return articles.size
}
override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
var article = articles.get(position)
holder.nomvisite.setText(article.nom)
holder.lieimgvisite.setText(article.lienimg)
holder.ifram.setText(article.ifram)
var urldelimg:String = article.lienimg
Glide.with(holder.imagedubloc.context).load(urldelimg).into(holder.imagedubloc)
}
class MyViewHolder(var vue: View):RecyclerView.ViewHolder(vue){
var nomvisite=vue.findViewById<TextView>(R.id.nom_visite)
var lieimgvisite=vue.findViewById<TextView>(R.id.lienimg)
var ifram=vue.findViewById<TextView>(R.id.ifram)
var imagedubloc=vue.findViewById<ImageView>(R.id.imagedubloc)
}
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:gravity="center">
<TextView
android:id="#+id/nom_visite"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="25dp"
/>
<TextView
android:id="#+id/lienimg"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="25dp"
/>
<ImageButton
android:id="#+id/imagedubloc"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#android:color/transparent"
android:scaleType="fitCenter"
/>
<TextView
android:id="#+id/ifram"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="25dp"
/>
</LinearLayout>
<?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="match_parent"
android:orientation="vertical"
android:gravity="center"
tools:context=".MainActivity">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclevirtuel"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</androidx.recyclerview.widget.RecyclerView>
</LinearLayout>
Thank you
You can pass an extra field within your Intent that you are using to navigate to the new activity, you code would be like this:
class ArticleAdapter(var articles: ArrayList<Article>) : RecyclerView.Adapter<ArticleAdapter.MyViewHolder>(){
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
var vue=LayoutInflater.from(parent.context).inflate(
R.layout.listevisitess,
parent,
false
)
return MyViewHolder(vue)
}
override fun getItemCount(): Int {
return articles.size
}
override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
var article = articles.get(position)
holder.nomvisite.setText(article.nom)
holder.lieimgvisite.setText(article.lienimg)
holder.ifram.setText(article.ifram)
var urldelimg:String = article.lienimg
Glide.with(holder.imagedubloc.context).load(urldelimg).into(holder.imagedubloc)
// here you pass your "ifram" value to the activity you're navigating to
holder.imagedubloc.setOnClickListener {
startActivity(Intent(holder.vue.context,monactivitefinal::class.java).apply {
putExtra("ifram", article.ifram)
})
}
}
class MyViewHolder(var vue: View):RecyclerView.ViewHolder(vue){
var nomvisite=vue.findViewById<TextView>(R.id.nom_visite)
var lieimgvisite=vue.findViewById<TextView>(R.id.lienimg)
var ifram=vue.findViewById<TextView>(R.id.ifram)
var imagedubloc=vue.findViewById<ImageView>(R.id.imagedubloc)
}
}
in your activity you can get "ifram" value as follows:
val ifram = getIntent().getStringExtra("ifram")
You need add listener to handle onClick Event, then the ButtonListActivity needs to implement this interface and init your adapter with it like this.
Listener
interface ImageButtonClickListener {
fun onImageButtonClick(articleIfram: String)
}
Activity with list of buttons
class ButtonListActivity : AppCompactActivity(), ImageButtonClickListener {
private val adapter: ArticleAdapter = ArticleAdapter(ArrayList(), this)
override fun onImageButtonClick(articleIfram: String) {
val intent = Intent(context, Monactivitefinal::class.java)
intent.putExtra("articleIfram", articleIfram)
startActivity(intent)
}
}
Your adapter
class ArticleAdapter(
val onImageButtonClickListener: ImageButtonClickListener,
var articles: ArrayList<Article>
) : RecyclerView.Adapter<ArticleAdapter.MyViewHolder>(){
override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
var article = articles.get(position)
imagedubloc.setOnClickListener {
onImageButtonClickListener.onImageButtonClick(article. ifram)
}
}
}
You could use lambda if you don't want to add listener
Activity with list of buttons
class ButtonListActivity : AppCompactActivity(), ImageButtonClickListener {
private val onImageButtonClick: (String) -> Unit = {
val intent = Intent(context, Monactivitefinal::class.java)
intent.putExtra("articleIfram", articleIfram)
startActivity(intent)
}
private val adapter: ArticleAdapter = ArticleAdapter(ArrayList(), onImageButtonClick)
}
Your adapter
class ArticleAdapter(
val onImageButtonClickListener: (String) -> Unit,
var articles: ArrayList<Article>
) : RecyclerView.Adapter<ArticleAdapter.MyViewHolder>(){
override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
var article = articles.get(position)
imagedubloc.setOnClickListener {
onImageButtonClickListener(article. ifram)
}
}
}
I am working with nested recyclerView. According to business logic, first I have to call an API that fetched the list of item that is shown in the Parent recycler view. After that, if a user clicks any of the items of the parent recycler view, another API is called which fetches a list of sub-items, and I have to show the item list in the inner recycler view of that clicked-positioned parent recycler view.
I successfully implemented showing items in the parent recycler view and sub-items in the clicked-position nested recycler view.
But the problem I am facing is when I clicked any specific item of the parent recycler view, all the other nested recycler view's item get changed with the newly populated sub-items value.
How can I solve this issue?. Here is the sample code
main_item.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.appcompat.widget.LinearLayoutCompat xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<com.google.android.material.card.MaterialCardView
style="#style/CardViewStyle"
android:id="#+id/chapter_layout"
android:layout_width="match_parent">
<com.google.android.material.textview.MaterialTextView
android:id="#+id/chapter_name_text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<com.google.android.material.textview.MaterialTextView
android:id="#+id/header_text_view"
android:layout_width="0dp"
android:layout_height="wrap_content"/>
</com.google.android.material.card.MaterialCardView>
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/chapter_topic_recycler_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="gone"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
tools:itemCount="3"
tools:listitem="#layout/item_main" />
</androidx.appcompat.widget.LinearLayoutCompat>
MainItemViewHolder.kt
class MainItemViewHolder(val view: View) : RecyclerView.ViewHolder(view) {
fun bind(item: SpecificChapter, onClick: (SpecificChapter, Int) -> Unit) {
with(view) {
chapter_name_text_view.text = "Chapter "+ item.no
header_text_view.text = item.name
chapter_layout.setOnClickListener { onClick(item, bindingAdapterPosition) }
}
}
}
MainItemAdapter.kt
class MainItemAdapter(
val onClick: (SpecificChapter, Int) -> Unit
) : ListAdapter<SpecificChapter, MainItemViewHolder>(DIFF_CALLBACK) {
companion object {
private val DIFF_CALLBACK = object : DiffUtil.ItemCallback<SpecificChapter>() {
override fun areItemsTheSame(old: SpecificChapter, aNew: SpecificChapter) = (old.id == aNew.id)
override fun areContentsTheSame(old: SpecificChapter, aNew: SpecificChapter) = (old == aNew)
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MainItemViewHolder {
return MainItemViewHolder(parent.inflate(R.layout.main_item))
}
override fun onBindViewHolder(holder: MainItemViewHolder, position: Int) {
holder.bind(getItem(position)!!, onClick)
}
}
sub_item.xml
<?xml version="1.0" encoding="utf-8"?>
<com.google.android.material.card.MaterialCardView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.google.android.material.textview.MaterialTextView
android:id="#+id/chapter_topic_text_view"
android:layout_width="0dp"
android:layout_height="wrap_content" />
</com.google.android.material.card.MaterialCardView>
SubItemViewHolder.kt
class SubItemViewHolder(val view: View) : RecyclerView.ViewHolder(view) {
fun bind(item: SpecificTopic, onClick: (SpecificTopic) -> Unit) {
with(view) {
chapter_topic_text_view.text = item.name
chapter_topic_layout.setOnClickListener { onClick(item) }
}
}
}
SubItemAdapter.kt
class SubItemAdapter(
val onClick: (SpecificTopic) -> Unit
) : ListAdapter<SpecificTopic, SubItemViewHolder>(DIFF_CALLBACK) {
companion object {
private val DIFF_CALLBACK = object : DiffUtil.ItemCallback<SpecificTopic>() {
override fun areItemsTheSame(old: SpecificTopic, aNew: SpecificTopic) = (old.id == aNew.id)
override fun areContentsTheSame(old: SpecificTopic, aNew: SpecificTopic) = (old == aNew)
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SubItemViewHolder {
return SubItemViewHolder(parent.inflate(R.layout.sub_item))
}
override fun onBindViewHolder(holder: SpecificTopicViewHolder, position: Int) {
holder.bind(getItem(position)!!, onClick)
}
}
activity_chapter.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/chapter_recycler_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
tools:listitem="#layout/main_item"/>
</androidx.appcompat.widget.LinearLayoutCompat>
ChapterActivity.kt
class ChapterActivity : BaseActivity<ChapterViewModel>() {
var chapterPosition = 0
private val mainItemAdapter: MainItemAdapter by lazy {
MainItemAdapter { specificChapter, position ->
// sub item Api call when clicked specific item. response is viewmodel.allTopics
chapterPosition = position
specificChapter.id?.let { viewModel.getChapterWiseTopics(it) }
}
}
private val subItemAdapter: SubItemAdapter by lazy {
SubItemAdapter {
}
}
override fun onResume() {
super.onResume()
// Main item Api call. response is viewmodel.allChapters
viewModel.getChapters("subject_code")
}
override fun observeLiveData() {
// showing Main item in parent recyclerView
observe(viewModel.allChapters) {
val chapterList = ArrayList<SpecificChapter>()
chapterList.add(SpecificChapter(...))
chapter_recycler_view.adapter = mainItemAdapter
mainItemAdapter.submitList(chapterList)
chapter_recycler_view.setItemViewCacheSize(chapterList.size)
}
// showing sub item in nested recyclerView
observe(viewModel.allTopics) {
val topicList = ArrayList<SpecificTopic>()
topicList.add(SpecificTopic(...))
with((chapter_recycler_view.findViewHolderForAdapterPosition(chapterPosition) as MainItemViewHolder).itemView) {
this.chapter_topic_recycler_view.adapter = subItemAdapter
subItemAdapter.submitList(topicList)
}
}
}
}
I'm unable to update my RecyclerView. Tried every solution on stackoverflow but nothing helps. I've tried to add layoutmanager in code, hardcode number of items, made new files, checked if I had duplicate files etc.. I also debugged and confirmed that "onAttachedToRecyclerView" is called, but getItemCount and the others i've listed in the adapter are not called except for the constructor
Adapter:
class BaseAdapter(context: Context, val items: List<Item>) :
RecyclerView.Adapter<LineBoxAdapter.BaseAdapter>() {
override fun getItemCount(): Int = items.size
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.textView.text = items[position].text
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int):
ViewHolder {
return ViewHolder(
LayoutInflater.from(parent.context).inflate(
R.layout.simple_item,
parent,
false
)
)
}
class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
val textView = itemView.findViewById<TextView>(R.id.title)
}
}
Function that updates recyclerView:
val listView =
LayoutInflater.from(context).inflate(R.layout.list, viewGroup,
false)
val list = listView.findViewById<RecyclerView>(R.id.
LinearLayoutManager(context)
val adapter = BaseAdapter(context, items)
list.adapter = adapter
adapter.notifyDataSetChanged()
RECYCLERVIEW:
<android.support.v7.widget.RecyclerView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/items_list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:overScrollMode="never"
android:requiresFadingEdge="horizontal"
app:layoutManager="android.support.v7.widget.LinearLayoutManager" />
SIMPLE_ITEM:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clickable="false"
android:orientation="horizontal">
<LinearLayout xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
>
<TextView
android:id="#+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:text="25" />
</LinearLayout>
You should avoid using existing class names from API.
I will post my working code.
simple_item:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="#+id/text_simple_item"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
RecyclerAdapter:
class RecyclerAdapter(context: Context, val items: List<Item>) :
RecyclerView.Adapter<RecyclerAdapter.MyViewHolder>() {
override fun getItemCount(): Int = items.size
override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
holder.textView.text = items[position].itemName
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int):
MyViewHolder {
return MyViewHolder(
LayoutInflater.from(parent.context).inflate(
R.layout.simple_item,
parent,
false
)
)
}
class MyViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
val textView = itemView.findViewById<TextView>(R.id.text_simple_item)
}
}
My Activity:
class RecyclerActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_recycler)
val recyler = findViewById<RecyclerView>(R.id.rv_activity_recycler)
val list = mutableListOf(Item("Me"), Item("You"), Item("We"))
val adapter = RecyclerAdapter(this, list)
recyler.layoutManager = LinearLayoutManager(this)
recyler.adapter = adapter
}
}
My Item:
class Item(val itemName: String)
I'm currently trying to create a dynamic header with a recyclerView. I have written the ListAdapter aswell as the ViewHolder. The custom list elements are added, and also the numer of the elements within the list is correct, but somehow it's not showing the object data, but only the dummyText that was added at the layoutdesign.
HeaderlistAdapter:
class HeaderListAdapter(val context: Context, val headers: List<CustomHeader>) : RecyclerView.Adapter<HeaderViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup?, viewType: Int): HeaderViewHolder {
val view = LayoutInflater.from(context).inflate(R.layout.ui_basic_custom_list_element_header, parent, false)
return HeaderViewHolder(view)
}
override fun getItemCount(): Int {
return headers.size
}
override fun onBindViewHolder(holder: HeaderViewHolder?, position: Int) {
holder?.bindHeader(headers[position])
}
fun setFocus(step:UIStep)
{
for(header in headers)
header.Active=header.MainContent==step
notifyDataSetChanged()
}
}
HeaderViewHolder:
class HeaderViewHolder:RecyclerView.ViewHolder{
#Bind(R.id.ui_adapter_main) var mainText:TextView?=null
#Bind(R.id.ui_adapter_additional) var additionalText:TextView?=null
#Bind(R.id.ui_adapter_layout) var layout:LinearLayout?=null
constructor(itemView: View): super(itemView){
ButterKnife.bind(this,itemView)
}
fun bindHeader(header:CustomHeader){
if(header.Active) {
mainText?.text = header.MainContent.description
additionalText?.text=header.AdditionalText
layout?.setBackgroundColor(R.color.colorBackgroundActive.toInt())
}
else{
mainText?.text=header.MainContent.number.toString()
additionalText?.text=""
layout?.setBackgroundColor(R.color.colorBackgroundInactive.toInt())
}
}
}
Here is, how the listAdapter looks within the view
<android.support.v7.widget.RecyclerView
android:id="#+id/ui_basic_lv_header"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:background="#color/colorBackgroundInactive"
android:layout_weight="1" />
Below here you se the xml of the custom element
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="horizontal"
android:background="#color/colorBackgroundInactive"
android:textColor="#color/colorHeaderFont"
android:id="#+id/ui_adapter_layout">
<TextView
android:id="#+id/ui_adapter_main"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:text="Main Info"
android:textSize="36sp"/>
<TextView
android:id="#+id/ui_adapter_additional"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:text="additional"
android:gravity="center_vertical"/>
Looks like there was something wrong with the
#Bind
I replaced that by using findViewById within the binHeader function:
fun bindHeader(header:CustomHeader){
val mainText = itemView.findViewById<TextView>(R.id.ui_adapter_main)
val additionalText = itemView.findViewById<TextView>(R.id.ui_adapter_additional)
val layout = itemView.findViewById<LinearLayout>(R.id.ui_adapter_layout)
if(header.Active) {
mainText?.text = header.MainContent.description
additionalText?.text=header.AdditionalText
layout?.setBackgroundColor(R.color.colorBackgroundActive.toInt())
}
else{
mainText?.text=header.MainContent.number.toString()
additionalText?.text=""
layout?.setBackgroundColor(R.color.colorBackgroundInactive.toInt())
}
}
contentList may be null ,if contentList is Null, the method following '?' will not execute . and after setting the adapter can not call notifyDataSetChanged ;
You should set layout manager for recyclerview
myRecyclerView.setLayoutManager(linearLayoutManagerVertical);