RecyclerView - Alphabet index not appearing - android

As part of my RecyclerView, I was expecting a row of letters to appear underneath it but for some reason the row is not appearing despite setting the properties to show it on screen.
Kotlin activity
class MainActivity : AppCompatActivity() {
private lateinit var adapterFruit: AdapterFruit
private lateinit var adapterAlphabet: AdapterAlphabet
private val arrayItemsFruit = ArrayList<ItemFruit>()
private val arrayItemsBtns = ArrayList<ItemAlphabet>()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val mToolbar = findViewById<Toolbar>(R.id.myToolbar)
val mRecyclerViewV = findViewById<RecyclerView>(R.id.mRecyclerViewWithToolbarV)
val mRecyclerViewH = findViewById<RecyclerView>(R.id.mRecyclerViewWithToolbarH)
// ...Do other stuff here
setSupportActionBar(mToolbar)
val mTitle = findViewById<TextView>(R.id.myToolbar_title)
mTitle.text = getString(R.string.fruit)
// Alphabet array
arrayItemsBtns.add(ItemAlphabet("A"))
arrayItemsBtns.add(ItemAlphabet("B"))
arrayItemsBtns.add(ItemAlphabet("C"))
arrayItemsBtns.add(ItemAlphabet("D"))
arrayItemsBtns.add(ItemAlphabet("F"))
arrayItemsBtns.add(ItemAlphabet("G"))
arrayItemsBtns.add(ItemAlphabet("K"))
arrayItemsBtns.add(ItemAlphabet("L"))
arrayItemsBtns.add(ItemAlphabet("M"))
arrayItemsBtns.add(ItemAlphabet("O"))
arrayItemsBtns.add(ItemAlphabet("P"))
arrayItemsBtns.add(ItemAlphabet("Q"))
arrayItemsBtns.add(ItemAlphabet("R"))
arrayItemsBtns.add(ItemAlphabet("S"))
arrayItemsBtns.add(ItemAlphabet("T"))
arrayItemsBtns.add(ItemAlphabet("W"))
// Fruit array items
arrayItemsFruit.add(
ItemFruit(
getString(R.string.apple)
)
)
arrayItemsFruit.add(
ItemFruit(
getString(R.string.blackberry)
)
)
arrayItemsFruit.add(
ItemFruit(
getString(R.string.cherry)
)
)
arrayItemsFruit.add(
ItemFruit(
getString(R.string.date)
)
)
arrayItemsFruit.add(
ItemFruit(
getString(R.string.fig)
)
)
arrayItemsFruit.add(
ItemFruit(
getString(R.string.grapefruit)
)
)
arrayItemsFruit.add(
ItemFruit(
getString(R.string.kiwi)
)
)
arrayItemsFruit.add(
ItemFruit(
getString(R.string.lemon)
)
)
arrayItemsFruit.add(
ItemFruit(
getString(R.string.mango)
)
)
arrayItemsFruit.add(
ItemFruit(
getString(R.string.pineapple)
)
)
arrayItemsFruit.add(
ItemFruit(
getString(R.string.quince)
)
)
arrayItemsFruit.add(
ItemFruit(
getString(R.string.raspberry)
)
)
arrayItemsFruit.add(
ItemFruit(
getString(R.string.strawberry)
)
)
arrayItemsFruit.add(
ItemFruit(
getString(R.string.tomato)
)
)
arrayItemsFruit.add(
ItemFruit(
getString(R.string.watermelon)
)
)
// Set Vertical RecyclerView
val isScreenSmall = resources.getBoolean(R.bool.isScreenSmall)
if (isScreenSmall) {
// Use special item decoration for small devices
mRecyclerViewV.layoutManager =
LinearLayoutManager(this)
val mListener = AdapterView.OnItemClickListener { _, _, _, _ -> }
adapterFruit = AdapterFruit(arrayItemsFruit, mListener)
mRecyclerViewV.addItemDecoration(
androidx.recyclerview.widget.DividerItemDecoration(
this,
LinearLayout.VERTICAL
)
)
mRecyclerViewV.adapter = adapterFruit
}
else {
// Use special item decoration for large devices
val numberOfColumns = 2
mRecyclerViewV.layoutManager =
androidx.recyclerview.widget.GridLayoutManager(this, numberOfColumns)
val mListener = AdapterView.OnItemClickListener { _, _, _, _ -> }
adapterFruit = AdapterFruit(arrayItemsFruit, mListener)
mRecyclerViewV.adapter = adapterFruit
}
// Set Horizontal RecyclerView
mRecyclerViewH.layoutManager = LinearLayoutManager(this,
RecyclerView.HORIZONTAL,
false)
val mListener = AdapterView.OnItemClickListener { _, _, _, _ -> }
adapterAlphabet = AdapterAlphabet(arrayItemsBtns, mListener)
mRecyclerViewH.adapter = adapterAlphabet
}
}
Main layout
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/ll_activityToolbarAndRecyclerview"
android:layout_width="match_parent"
android:layout_height="match_parent">
<include
layout="#layout/my_toolbar"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/mRecyclerViewWithToolbarV"
android:layout_width="0dp"
android:layout_height="0dp"
android:scrollbars="vertical"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/myToolbar"
app:layout_constraintBottom_toTopOf="#+id/mRecyclerViewWithToolbarH"/>
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/mRecyclerViewWithToolbarH"
android:layout_width="0dp"
android:layout_height="0dp"
android:scrollbars="horizontal"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/mRecyclerViewWithToolbarV"
app:layout_constraintBottom_toBottomOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
Button layout
<?xml version="1.0" encoding="utf-8"?>
<com.google.android.material.button.MaterialButton
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/myBtn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clickable="true"
android:focusable="true"
android:gravity="start|center_vertical"
android:padding="20dp"
android:layout_margin="20dp"
android:textAllCaps="false"
android:textColor="?android:attr/textColorPrimary"
android:textSize="22sp"
app:strokeColor="?android:attr/textColorPrimary"
style="#style/Widget.MaterialComponents.Button.OutlinedButton" />
ItemAlphabet
data class ItemAlphabet(
val alphabetLetter: String
)
Alphabet index adapter
class AdapterAlphabet(
var listAlphabet: MutableList<ItemAlphabet>,
private val clickListener: AdapterView.OnItemClickListener
) : RecyclerView.Adapter<AdapterAlphabet.CompanyViewHolder>() {
class CompanyViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
var btnAlphabet: MaterialButton = itemView.findViewById(R.id.myBtn)
fun bind(alphabet: ItemAlphabet)
{
// Binding the data with the view holder views
btnAlphabet.text = alphabet.alphabetLetter
// Click events for list items (based on position)
itemView.setOnClickListener {v ->
// val intent: Intent = when (alphabet.alphabetLetter) {
// v.resources.getString(R.string.apple) -> {
//
// }
// else -> {
//// Intent
// }
// }
// itemView.context.startActivity(intent)
}
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): AdapterAlphabet.CompanyViewHolder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.rv_item_btn,parent,false)
return AdapterAlphabet.CompanyViewHolder(view)
}
override fun getItemCount(): Int {
return listAlphabet.size
}
override fun onBindViewHolder(holder: CompanyViewHolder, position: Int) {
// Getting the product of the specified position
val product = listAlphabet[position]
// Binding to click listener
holder.bind(product)
}
}
Tablet result
Update
Ali Ahsan's suggestion

Based on your screenshot in the updated question, I suggest the following layout structure:
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/ll_activityToolbarAndRecyclerview"
android:layout_width="match_parent"
android:layout_height="match_parent">
<include
layout="#layout/my_toolbar"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/mRecyclerViewWithToolbarV"
android:layout_width="0dp"
android:layout_height="0dp"
android:scrollbars="vertical"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/myToolbar"
app:layout_constraintBottom_toTopOf="#+id/mRecyclerViewWithToolbarH"/>
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/mRecyclerViewWithToolbarH"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:scrollbars="horizontal"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
Neither the toolbar nor the bottom RecyclerView specifies constraints against the middle RecyclerView. The effect should be to pin the toolbar to the top of the screen and the bottom RecyclerView to the bottom of the screen.
(Note that it's okay to use wrap_content for the height of the bottom RV, because the "scrolling"/"recycling" axis is horizontal.)
Then, you can have the middle RecyclerView constrain all four of its edges to the parent, the toolbar, and the bottom RecyclerView. This will cause the middle RV to "stretch" to fill all remaining space on the screen.

Related

How to make a grid recycler view with different item sizes adjusted to different sizes in Android?

I need to create this kind of grid recycler view:
Where first item is biggest than others. Grid might have only 6 items and sizes might be this one:
The first one will have width = 320 and height = 220.
Others will have width = 100 and height = 150.
My recyclerView item XML:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="#dimen/home_items_space">
<ImageView
android:id="#+id/lookImage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="4dp"
android:scaleType="centerCrop"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
My recyclerView XML:
<?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="#dimen/looks_grid_height"
android:paddingHorizontal="12dp">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/looksGrid"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layoutManager="androidx.recyclerview.widget.StaggeredGridLayoutManager"
app:layout_constraintTop_toTopOf="parent"
app:spanCount="2"
tools:itemCount="6" />
</androidx.constraintlayout.widget.ConstraintLayout>
My Adapter code:
class LooksAdapter :
ListAdapter<HomeLook, LooksAdapter.LooksViewHolder>(DiffCallback()) {
companion object {
private val FIRST_ITEM_INDEX = 0
}
var listener: ((HomeLook) -> Unit)? = null
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): LooksViewHolder {
return LooksViewHolder(
ItemHomeLooksBinding.inflate(LayoutInflater.from(parent.context), parent, false)
)
}
override fun onBindViewHolder(holder: LooksViewHolder, position: Int) {
holder.bind(getItem(position), position)
}
class LooksViewHolder(private val binding: ItemHomeLooksBinding) :
RecyclerView.ViewHolder(binding.root) {
fun bind(look: HomeLook, index: Int) {
if (index == FIRST_ITEM_INDEX) {
binding.root.updateLayoutParams {
width = binding.root.width / 2
height = 310
}
} else {
binding.root.updateLayoutParams {
width = 100
height = 150
}
}
binding.lookImage.load(look.lookImage) {
fallback(R.drawable.ic_camera_placeholder)
error(R.drawable.ic_camera_placeholder)
}
}
}
My ViewHolder code:
class LooksHomeViewHolder(
val binding: LooksGridViewBinding
) : RecyclerView.ViewHolder(binding.root) {
companion object {
fun from(parent: ViewGroup): LooksHomeViewHolder {
return LooksHomeViewHolder(
LooksGridViewBinding.inflate(LayoutInflater.from(parent.context), parent, false),
)
}
}
private val adapter = LooksAdapter().apply {
stateRestorationPolicy = RecyclerView.Adapter.StateRestorationPolicy.PREVENT_WHEN_EMPTY
}
init {
binding.looksGrid.adapter = adapter
binding.looksGrid.itemAnimator = DefaultItemAnimator().apply {
supportsChangeAnimations = false
}
}
fun bind(
lookBookEntry: HomeEntity.LookBookEntry,
listener: (HomeLook) -> Unit,
addPhotoListener: () -> Unit
) {
adapter.submitList(lookBookEntry.looks)
adapter.listener = listener
binding.addLookButton.setOnClickListener { addPhotoListener.invoke() }
binding.noLooksPlaceholder.isVisible = lookBookEntry.looks.isEmpty()
}
}
I tried to use StaggerManager and change imageView and root size. But it isn't help.
Basically you need to use StaggeredLayoutManager to achieve this output . You can check below mentioned links
example :-
https://www.geeksforgeeks.org/recyclerview-as-staggered-grid-in-android-with-example/
documentation :-
https://developer.android.com/reference/androidx/recyclerview/widget/StaggeredGridLayoutManager

I am using viewpager2 inside a recyclerview but the images are not outputting. Why?

No matter what I do the pictures are not showing up.
Even if I set the items to match parent, I still have the same problem, I've been dealing with it since the morning, if I find it, I will relax very well :D
This is my adapter for viewpager 2 :
class ViewPagerAdapter ( private val context : Context , private val album_id : Int , private val photo_list : ArrayList<Photos> ) : RecyclerView.Adapter<ViewPagerAdapter.PagerHolder>() {
inner class PagerHolder (view : View ) : RecyclerView.ViewHolder ( view ) {
var image_view : ImageView
init {
image_view = view.findViewById ( R.id.pager_imageview )
}
}
override fun onCreateViewHolder(parent : ViewGroup, viewType : Int) : PagerHolder {
val v = LayoutInflater.from ( parent.context ).inflate ( R.layout.viewpager_item , parent , false )
return PagerHolder ( v )
}
override fun onBindViewHolder (holder : ViewPagerAdapter.PagerHolder, position : Int ) {
val list = photo_list.filter { it.albumId == album_id }
for ( i in list [ position ].url ) {
Glide.with ( context ).load ( i.toString() ).diskCacheStrategy ( DiskCacheStrategy.ALL ).into ( holder.image_view )
}
}
override fun getItemCount ( ) : Int {
return photo_list.size
}
}
This is my xml code for my viewpager items :
<androidx.cardview.widget.CardView 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="match_parent"
app:cardCornerRadius="20dp">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="#+id/pager_imageview"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
This is my recyclerview defined codes:
class AlbumRecyclerAdapter ( private val context : Context , private val album_list : ArrayList<Albums> , private val photo_list : ArrayList<Photos> ) : RecyclerView.Adapter<AlbumRecyclerAdapter.Adapterholder>() {
inner class Adapterholder(view : View) : RecyclerView.ViewHolder(view) {
var album_title : TextView
var view_pager2 : ViewPager2
init {
album_title = view.findViewById(R.id.album_title)
view_pager2 = view.findViewById ( R.id.view_pager2 )
}
}
override fun onCreateViewHolder(parent : ViewGroup, viewType : Int) : Adapterholder {
val v = LayoutInflater.from ( parent.context ).inflate ( R.layout.album_recycler_list , parent , false )
return Adapterholder(v)
}
override fun onBindViewHolder ( holder : AlbumRecyclerAdapter.Adapterholder , position : Int) {
val pager_adapter = ViewPagerAdapter ( context , album_list [ position ].id , photo_list )
holder.view_pager2.orientation = ViewPager2.ORIENTATION_HORIZONTAL
holder.view_pager2.adapter = pager_adapter
holder.view_pager2.clipToPadding = false
holder.view_pager2.clipChildren = false
holder.view_pager2.offscreenPageLimit = 3
holder.view_pager2.getChildAt ( 0 ).overScrollMode = RecyclerView.OVER_SCROLL_NEVER
holder.album_title.text = album_list [ position ].title
}
override fun getItemCount ( ) : Int {
return album_list.size
}
}
Finally , this is my xml code for the recyclerview :
<androidx.cardview.widget.CardView 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="300dp"
android:layout_marginTop ="10dp"
android:layout_marginLeft ="5dp"
android:layout_marginRight="5dp"
app:cardCornerRadius="20dp">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent" >
<androidx.viewpager2.widget.ViewPager2
android:id="#+id/view_pager2"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginStart="8dp"
android:layout_marginTop="32dp"
android:layout_marginEnd="8dp"
android:layout_marginBottom="80dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/album_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:text="Album Title"
app:autoSizeTextType="uniform"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/view_pager2" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
I'm Java Developer so I cannot code with Kotlin but I'll show you how to show images on ViewPager.
First, remove for ( i in list [ position ].url ) from onBindViewHolder. And load direct from photo_list.get(position).getImage as below
override fun onBindViewHolder (holder : ViewPagerAdapter.PagerHolder, position : Int ) {
val list = photo_list.filter { it.albumId == album_id }
Glide.with ( context ).load ( photo_list.get(position).getImage // your imageModel ).diskCacheStrategy ( DiskCacheStrategy.ALL ).into ( holder.image_view )
}
Make sure to change JAVA to Kotlin in my code. If you any problem is causing, Let me know
Instead of passing the whole photo_list and then filtering it in ViewPager, pass only the filtered list to it. Because in getItemCount you are returning the size of the whole photo_list but in onBindViewHolder you're accessing the filtered list, this could lead to crashes as filtered list would be smaller than the original one.
In AlbumRecyclerAdapter's onBindViewHolder pass the filtered list to ViewPager adapter.
val pager_adapter = ViewPagerAdapter (
context ,
album_list [ position ].id ,
ArrayList(photo_list.filter { it.albumId == album_list[position].id }
)
In ViewPagerAdapter's onBindViewHolder(), why are you iterating over a url and I assume your url is a String and when you iterate over it, it loops through all the individual characters of the string, that is why you are not seeing any image in the first place.
override fun onBindViewHolder (holder : ViewPagerAdapter.PagerHolder, position : Int ) {
val photo = photo_list[position]
Glide.with ( context )
.load ( photo.url )
.diskCacheStrategy ( DiskCacheStrategy.ALL )
.into ( holder.image_view )
}

Kotlin Recyclerview row item selection background color change

I am able to change the color of the text and background of row clicked of my recyclerview in my recyclerview.
But my problem is after clicking for example on the 2th item,the 10st item also gets selected.Likewise after clicking my 5th item the 3nd item is selected.
How do i solve this?
in fact my question is that how to change background color of recyclerview item that click on it in Kotlin?
I also followed the instructions in this link. But it did not worked correctly!!
AllChanelAdapter.kt
class AllChanelAdapter(private val datalist:MutableList<AllChanelModel>, var clickListener: OnItemClickListener):RecyclerView.Adapter<AllChanelHolder>() {
private lateinit var context:Context
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): AllChanelHolder {
context = parent.context
return AllChanelHolder(LayoutInflater.from(context).inflate(R.layout.allchanel_singleitem,parent,false))
}
override fun getItemCount(): Int = datalist.size
override fun onBindViewHolder(holder: AllChanelHolder, position: Int) {
val data = datalist[position]
val txt_title = holder.itemView.txt_title
val txt_body = holder.itemView.txt_body
val img_chanel = holder.itemView.img_chanel
txt_title.setText(data.title)
txt_body.setText(data.body)
Glide
.with(context)
.load("...")
.centerCrop()
.into(img_chanel);
}
holder.initialize(datalist.get(position),clickListener)
}
interface OnItemClickListener {
fun onItemClick(item: AllChanelModel, position: Int, view: View)
}
AllChanelHolder.kt
class AllChanelHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
fun initialize(item:AllChanelModel,action:OnItemClickListener){
itemView.setOnClickListener {
action.onItemClick(item,adapterPosition,itemView)
}
}
}
MainPageActivity.kt
class MainPageActivity : AppCompatActivity(),OnItemClickListener {
private val datalist:MutableList<AllChanelModel> = mutableListOf()
lateinit var allchaneladapter : AllChanelAdapter
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main_page)
send_request()
allchaneladapter = AllChanelAdapter(datalist,this)
all_chanel_recycler.layoutManager = LinearLayoutManager(this)
all_chanel_recycler.adapter = allchaneladapter
}
private fun send_request(){
val url = "http://10.0.2.2:8000/getsamplejson" // localhost api
val que = Volley.newRequestQueue(this#MainPageActivity)
val req = JsonArrayRequest(Request.Method.GET,url,null,
Response.Listener {
response->
for(i in 0..response.length()-1){
var chanel_obj = response.getJSONObject(i)
datalist.add(
AllChanelModel(
chanel_obj.getString("body"),
chanel_obj.getString("title"),
chanel_obj.getString("userId")
)
)
}
allchaneladapter.notifyDataSetChanged()
}, Response.ErrorListener {
error->
Log.e("",error.message)
})
que.add(req)
}
override fun onItemClick(item: AllChanelModel, position: Int, view: View) {
view.setBackgroundColor(Color.YELLOW)
}
}
AllChanelModel.kt
data class AllChanelModel(
#SerializedName("body")
val body: String,
#SerializedName("title")
val title: String,
#SerializedName("userId")
val userId: String
)
activity_main_page.xml
<?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=".MainPageActivity">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/all_chanel_recycler"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
allchanel_singleitem.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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="horizontal">
<LinearLayout
android:id="#+id/linear_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="3"
android:orientation="vertical"
android:padding="5dp">
<TextView
android:id="#+id/txt_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="right"
android:text="TextView"
android:textColor="#000000" />
<TextView
android:id="#+id/txt_body"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center|right"
android:text="TextView"
android:textColor="#000000" />
</LinearLayout>
<ImageView
android:id="#+id/img_chanel"
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_weight="1"
app:srcCompat="#mipmap/ic_launcher" />
</LinearLayout>
please help me
thank you
After a thorough search on the Internet, I was finally able to solve this problem.
I put the code step by step and give explanations if needed.
1 - create new android studio project
2 - cods for activity_main.xml as below:
activity_main.xml
<?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=".MainPageActivity">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:drawable/screen_background_light_transparent"
tools:listitem="#layout/item_list" />
</androidx.constraintlayout.widget.ConstraintLayout>
3 - create a layout for recycler view row(item) with name item_list.xml as bellow
item_list.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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="horizontal">
<LinearLayout
android:id="#+id/linear_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="3"
android:background="#FFFFFF"
android:orientation="vertical"
android:padding="5dp">
<TextView
android:id="#+id/tv_label"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="right"
android:text="TextView"
android:textColor="#000000" />
<TextView
android:id="#+id/tv_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center|right"
android:text="TextView"
android:textColor="#000000" />
</LinearLayout>
<ImageView
android:id="#+id/img_chanel"
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_weight="1"
app:srcCompat="#mipmap/ic_launcher" />
</LinearLayout>
4 - create data class(Based on the data you want to bind in RecyclerView) as bellow
My Model(UserModel.kt)
public data class UserModel(var title:String,var name:String,var isSelected:Boolean=false)
5 - create Adapter for your RecyclerView as bellow
CustomAdapter.kt
class CustomAdapter(private val context: Context, private val list: ArrayList<UserModel>,
private val listener: OnItemClickListener
) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
private inner class ViewHolder internal constructor(itemView: View) : RecyclerView.ViewHolder(itemView),View.OnClickListener {
internal var tvLabel: TextView
internal var tvName: TextView
init {
tvLabel = itemView.findViewById(R.id.tv_label) // Initialize your All views prensent in list items
tvName = itemView.findViewById(R.id.tv_name) // Initialize your All views prensent in list items
itemView.setOnClickListener(this)
}
internal fun bind(position: Int) {
// This method will be called anytime a list item is created or update its data
//Do your stuff here
tvLabel.text = list[position].title
tvName.text = list[position].name
}
override fun onClick(v: View?) {
val position:Int = adapterPosition
if(position != RecyclerView.NO_POSITION) {
listener.onItemClick(position,this#CustomAdapter,itemView)
}
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return ViewHolder(LayoutInflater.from(context).inflate(R.layout.item_list, parent, false))
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
if(list[position].isSelected){
holder.itemView.setBackgroundColor(Color.YELLOW)
holder.itemView.findViewById<LinearLayout>(R.id.linear_content).setBackgroundColor(Color.YELLOW)
} else{
holder.itemView.setBackgroundColor(Color.WHITE)
holder.itemView.findViewById<LinearLayout>(R.id.linear_content).setBackgroundColor(Color.WHITE)
}
(holder as ViewHolder).bind(position)
}
override fun getItemCount(): Int {
return list.size
}
interface OnItemClickListener{
fun onItemClick(position: Int,adapter:CustomAdapter,v:View)
}
}
6 - codes for MainActivity.kt as bellow:
MainActivity.kt
class MainActivity : AppCompatActivity(),CustomAdapter.OnItemClickListener {
private val data = arrayListOf<UserModel>()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main_page)
val recyclerview = findViewById<RecyclerView>(R.id.recycler_view)
data.add(UserModel(title = "item 1",name = "name 1"))
data.add(UserModel(title = "item 2",name = "name 2"))
data.add(UserModel(title = "item 3",name = "name 3"))
data.add(UserModel(title = "item 4",name = "name 4"))
data.add(UserModel(title = "item 5",name = "name 5"))
data.add(UserModel(title = "item 6",name = "name 6"))
data.add(UserModel(title = "item 1",name = "name 1"))
data.add(UserModel(title = "item 2",name = "name 2"))
data.add(UserModel(title = "item 3",name = "name 3"))
data.add(UserModel(title = "item 4",name = "name 4"))
data.add(UserModel(title = "item 5",name = "name 5"))
data.add(UserModel(title = "item 6",name = "name 6"))
val adapter = CustomAdapter(this,data,this)
recyclerview.layoutManager = LinearLayoutManager(this)
recyclerview.adapter = adapter
recyclerview.setHasFixedSize(true)
}
override fun onItemClick(position: Int,adapter: CustomAdapter,v:View) {
val clicked_item:UserModel = data[position]
clicked_item.title = "clicked"
clicked_item.isSelected = !clicked_item.isSelected
if(clicked_item.isSelected){
recycler_view.getChildAt(recycler_view.indexOfChild(v)).setBackgroundColor(Color.YELLOW)
recycler_view.getChildAt(recycler_view.indexOfChild(v)).findViewById<LinearLayout>(R.id.linear_content).setBackgroundColor(Color.YELLOW)
}else{
recycler_view.getChildAt(recycler_view.indexOfChild(v)).setBackgroundColor(Color.WHITE)
recycler_view.getChildAt(recycler_view.indexOfChild(v)).findViewById<LinearLayout>(R.id.linear_content).setBackgroundColor(Color.WHITE)
}
}
}
I hope you find it useful
You have to set color for other items when you cal

Recyclerview - onCreateViewHolder called for each list item

I have implemented a simple adapter but it is causing RecyclerView not to recycler views and calls onCreateViewHolder() for every list item when scrolled. This causes jank
whenever I scroll the list. Few points listed below are not related to excessive calls of onCreateViewHolder(), but I tried them to improve scroll performance and avoid jank. Things I have tried so far:
recyclerView.setHasFixedSize(true)
recyclerView.recycledViewPool.setMaxRecycledViews(1, 10) with recyclerView.setItemViewCacheSize(10)
recyclerView.setDrawingCacheEnabled(true) with recyclerView.setDrawingCacheQuality(View.DRAWING_CACHE_QUALITY_HIGH)
setting RecyclerView height to "match_parent"
Was previously using Kotlin's synthetic, now moved to Android's ViewBinding
Rewrite complex nested layouts to Constraint Layout
override onFailedToRecycleView() to see if it is called, but it was never called
Here is my adapter:
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.example.suppstore.R
import com.example.suppstore.common.Models.Brand
import com.example.suppstore.databinding.LiBrandBinding
import com.google.firebase.perf.metrics.AddTrace
class BrandsAdapter(list: ArrayList<Brand>, var listener: BrandClickListener?) :
RecyclerView.Adapter<RecyclerView.ViewHolder>() {
private val VIEW_TYPE_LOADING = 0
private val VIEW_TYPE_NORMAL = 1
private var brandsList: ArrayList<Brand> = list
#AddTrace(name = "Brands - onCreateViewHolder", enabled = true)
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return if (viewType == VIEW_TYPE_NORMAL) {
ViewHolder(
LiBrandBinding.inflate(
LayoutInflater.from(parent.context),
parent, false
)
)
} else {
LoaderHolder(
LayoutInflater.from(parent.context)
.inflate(R.layout.li_loader, parent, false)
)
}
}
#AddTrace(name = "Brands - onBindViewHolder", enabled = true)
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
if (holder is ViewHolder)
holder.setData(brandsList[position], listener!!)
}
class ViewHolder(itemView: LiBrandBinding) : RecyclerView.ViewHolder(itemView.root) {
private val binding: LiBrandBinding = itemView
#AddTrace(name = "Brands - ViewHolder-setData", enabled = true)
fun setData(brand: Brand, listener: BrandClickListener) {
binding.cardItem.setOnClickListener { listener.onItemClick(brand) }
binding.tvBrandName.text = brand.name
binding.tvCount.text = brand.count.toString() + " Products"
}
}
class LoaderHolder(itemView: View) : RecyclerView.ViewHolder(itemView.rootView) {
}
#AddTrace(name = "Brands - addLoader", enabled = true)
fun addLoader() {
brandsList.add(Brand())
notifyItemInserted(brandsList.size - 1)
}
#AddTrace(name = "Brands - setData", enabled = true)
fun setData(newList: ArrayList<Brand>) {
this.brandsList = newList
notifyDataSetChanged()
}
#AddTrace(name = "Brands - removeLoader", enabled = true)
fun removeLoader() {
if (brandsList.size == 0)
return
val pos = brandsList.size - 1
brandsList.removeAt(pos)
notifyItemRemoved(pos)
}
override fun getItemViewType(position: Int): Int {
return if (brandsList.get(position).count == -1) {
VIEW_TYPE_LOADING
} else
VIEW_TYPE_NORMAL
}
interface BrandClickListener {
fun onItemClick(brand: Brand)
}
override fun getItemCount(): Int {
return brandsList.size
}
}
Here is the list item (li_brand):
<?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"
android:id="#+id/cardItem"
android:layout_width="match_parent"
android:layout_height="85dp"
android:background="#color/app_black">
<TextView
android:id="#+id/tvBrandName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="15dp"
android:textColor="#color/app_yellow"
android:textSize="18sp"
android:textStyle="bold"
app:layout_constraintBottom_toTopOf="#id/tvCount"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_chainStyle="packed" />
<TextView
android:id="#+id/tvCount"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="15dp"
android:layout_marginTop="2dp"
android:textColor="#color/app_grey"
android:textSize="12sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="#id/tvBrandName" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="20dp"
android:layout_gravity="center_vertical"
android:layout_marginEnd="15dp"
android:src="#drawable/ic_baseline_arrow_forward_ios_24"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<View
android:layout_width="match_parent"
android:layout_height="3dp"
android:background="#color/app_bg"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
Here are related functions in Fragment
class BrandsFragment : Fragment() {
private val adapter = BrandsAdapter(ArrayList(), brandClickListener())
fun brandClickListener(): BrandsAdapter.BrandClickListener {
return object : BrandsAdapter.BrandClickListener {
override fun onItemClick(brand: Brand) {
activityViewModel?.setSelectedBrand(brand)
}
}
}
fun setupRecyclerView() {
val llManager = LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false)
binding.recyclerView.layoutManager = llManager
binding.recyclerView.setHasFixedSize(true)
binding.recyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
if (dy > 0) { //check for scroll down
val visibleItemCount = llManager.childCount
val totalItemCount = llManager.itemCount
val firstVisibleItemPos = llManager.findFirstVisibleItemPosition()
if (loadWhenScrolled
&& visibleItemCount + firstVisibleItemPos >= totalItemCount
&& firstVisibleItemPos >= 0
) {
//ensures that last item was visible, so fetch next page
loadWhenScrolled = false
viewModel.nextPage()
}
}
}
})
binding.recyclerView.adapter = adapter
}
}
And here is the fragment xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:background="#color/app_black"
android:focusableInTouchMode="true"
android:orientation="vertical"
tools:context=".Brands.BrandsFragment">
<androidx.appcompat.widget.SearchView
android:id="#+id/searchView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:layout_marginBottom="5dp"
android:background="#drawable/bottom_line_yellow"
android:theme="#style/SearchViewTheme"
app:closeIcon="#drawable/ic_baseline_close_24"
app:iconifiedByDefault="false"
app:queryBackground="#android:color/transparent"
app:queryHint="Atleast 3 characters to search"
app:searchIcon="#drawable/ic_baseline_search_24" />
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
Have you tried RecyclerView Diffutil class? Hope it will resolve smooth scrolling issue and overwhelm recreation of items.
https://developer.android.com/reference/androidx/recyclerview/widget/DiffUtil
"DiffUtil is a utility class that calculates the difference between two lists and outputs a list of update operations that converts the first list into the second one."

how to binding correctly recyclerview items in kotlin?

I am developing a news app and I am following MVVM with data binding in recycler view I am trying to bind items but I am just stuck below my recyclerview items xml file
<?xml version="1.0" encoding="utf-8"?>
<layout>
<data>
<variable
name="article"
type="yodgorbek.komilov.musobaqayangiliklari.model.Article">
</variable>
</data>
<androidx.cardview.widget.CardView 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">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:layout_marginBottom="16dp">
<ImageView
android:text="#{article.urlToImage}"
android:id="#+id/imageView"
android:layout_width="100dp"
android:layout_height="85dp"
android:layout_marginStart="16dp"
android:layout_marginLeft="16dp"
android:contentDescription="bbc"
tools:background="#color/colorPrimary" />
<TextView
android:id="#+id/articleTitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:layout_toEndOf="#id/imageView"
android:layout_toRightOf="#id/imageView"
android:ellipsize="end"
android:lines="3"
android:maxLines="3"
android:text="#{article.title}" />
<ImageView
android:id="#+id/imageCategory"
android:layout_width="32dp"
android:layout_height="32dp"
android:layout_below="#id/articleTitle"
android:layout_marginStart="16dp"
android:layout_marginLeft="16dp"
android:layout_toEndOf="#id/imageView"
android:layout_toRightOf="#id/imageView"
android:src="#drawable/ic_espn"
tools:background="#color/colorPrimary" />
<TextView
android:id="#+id/articleSourceName"
android:layout_width="wrap_content"
android:layout_height="32dp"
android:layout_below="#id/articleTitle"
android:layout_marginStart="16dp"
android:layout_marginLeft="16dp"
android:layout_toEndOf="#id/imageCategory"
android:layout_toRightOf="#id/imageCategory"
android:gravity="center|start"
android:text="#{article.source.name}" />
<TextView
android:id="#+id/articleTime"
android:layout_width="wrap_content"
android:layout_height="32dp"
android:layout_below="#id/articleTitle"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:layout_toEndOf="#id/articleSourceName"
android:layout_toRightOf="#id/articleSourceName"
android:gravity="center|start"
android:text="#{article.publishedAt}"
android:textColor="#android:color/darker_gray"
tools:ignore="NotSibling" />
</RelativeLayout>
</androidx.cardview.widget.CardView>
</layout>
below TopHeadlinesAdapter.kt where I am trying to implement data binding logic
#Suppress("NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS")
class TopHeadlinesAdapter(val context: Context, private val article: List<Article>) :
RecyclerView.Adapter<TopHeadlinesAdapter.MyViewHolder>() {
private var articleList: List<Article> by Delegates.observable(emptyList()) { _, _, _ ->
notifyDataSetChanged()
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
val inflater =
LayoutInflater.from(parent.context)//.inflate(R.layout.news_list, parent, false)
// val binding = Article.inflate(inflater)
return MyViewHolder(article, parent)
}
override fun getItemCount(): Int {
return articleList.size
}
#SuppressLint("NewApi")
override fun onBindViewHolder(holder: MyViewHolder, position: Int) =
holder.bind(articleList[position])
//holder.articleTitle.text = articleList.get(position).title
//holder.articleSourceName.text = articleList.get(position).source.name
//Picasso.get().load(articleList.get(position).urlToImage).into(holder.image)
// val input = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssX")
// val output = SimpleDateFormat("dd/MM/yyyy")
// var d = Date()
// try {
// d = input.parse(articleList[5].publishedAt)
// } catch (e: ParseException) {
// try {
// val fallback = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'")
// fallback.timeZone = TimeZone.getTimeZone("UTC")
// d = fallback.parse(articleList[5].publishedAt)
// } catch (e2: ParseException) {
// // TODO handle error
// val formatted = output.format(d)
// val timelinePoint = LocalDateTime.parse(formatted)
// val now = LocalDateTime.now()
//
// var elapsedTime = Duration.between(timelinePoint, now)
//
// println(timelinePoint)
// println(now)
// elapsedTime.toMinutes()
//
// holder.articleTime.text = "${elapsedTime.toMinutes()}"
//
//
fun updateData(newList: List<Article>) {
articleList = newList
Log.e("articleListSize", articleList?.size.toString())
}
inner class MyViewHolder(private val binding: Article) : RecyclerView.ViewHolder(binding.root) {
fun bind(article: Article) {
binding.article = article
// val image: ImageView = itemView!!.findViewById(R.id.imageView)
// val articleTitle: TextView = itemView!!.findViewById(R.id.articleTitle)
// val articleSourceName: TextView = itemView!!.findViewById(R.id.articleSourceName)
// val imageCategory: ImageView = itemView!!.findViewById(R.id.imageCategory)
// val articleTime: TextView = itemView!!.findViewById(R.id.articleTime)
}
}
}
below my Article.kt data class
data class Article(
val author: String,
val content: String,
val description: String,
val publishedAt: String,
val source: Source,
val title: String,
val url: String,
val urlToImage: String
)
below fragment_top_headlines.xml where I am hosting recyclerview
<androidx.constraintlayout.widget.ConstraintLayout 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="match_parent">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ProgressBar
android:id="#+id/pb"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
below TopHeadlinesFragment.kt
class TopHeadlinesFragment : Fragment() {
private val viewModel by viewModel<MainViewModel>()
private lateinit var topHeadlinesAdapter: TopHeadlinesAdapter
// private val newsRepository: NewsRepository by inject()
private lateinit var article:List<Article>
//3
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val view = inflater.inflate(
R.layout.fragment_top_headlines
, container, false
)
val recyclerView = view.findViewById(R.id.recyclerView) as RecyclerView
val pb = view.findViewById(R.id.pb) as ProgressBar
topHeadlinesAdapter = TopHeadlinesAdapter(recyclerView.context, article)
recyclerView.layoutManager = LinearLayoutManager(context)
recyclerView.adapter = topHeadlinesAdapter
initViewModel()
return view
}
private fun initViewModel() {
viewModel?.sportList?.observe(this, Observer { newList ->
topHeadlinesAdapter.updateData(newList)
})
viewModel?.showLoading?.observe(this, Observer { showLoading ->
pb.visibility = if (showLoading) View.VISIBLE else View.GONE
})
viewModel?.showError?.observe(this, Observer { showError ->
(showError)
})
viewModel?.loadNews()
}
}
I want to know what I have to do in order to bind correctly recyclerview items and show correctly in my app?
try this in
class yourAdapterName(val context: Context, var listData:
MutableList<Article>) :
RecyclerView.Adapter<LanguageAdapter.ViewHolder>() {
lateinit var bindind: YourBinding
fun onRefresh(listData: MutableList<Article>) {
this.listData = listData
notifyDataSetChanged()
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int):
ViewHolder {
bindind = YourBinding.inflate(LayoutInflater.from(parent.context), parent, false)
return ViewHolder(bindind)
}
override fun getItemCount(): Int {
return listData.size
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.setData(listData[position])
}
inner class ViewHolder(private val binding: LangugaeItemBinding) : RecyclerView.ViewHolder(binding.getRoot()) {
fun setData(model: Article) {
with(binding) {
artical = model
executePendingBindings()
}
}
}
}
and call these into onViewCreated in fragment
val recyclerView = view.findViewById(R.id.recyclerView) as
RecyclerView
val pb = view.findViewById(R.id.pb) as ProgressBar
topHeadlinesAdapter = TopHeadlinesAdapter(recyclerView.context,
article)
recyclerView.layoutManager = LinearLayoutManager(context)
recyclerView.adapter = topHeadlinesAdapter
initViewModel()

Categories

Resources