I wrote this code using recyclerview and I got the image that I got from the url why, my picture didn't appear
this is my activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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=".MainActivity">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/rvMain"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:listitem="#layout/item_hero"
/>
</RelativeLayout>
this is my tools:listitem
<?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="horizontal"
android:padding="8dp">
<ImageView
android:id="#+id/imgHeroes"
android:layout_width="80dp"
android:layout_height="80dp"
android:scaleType="centerCrop"/>
<TextView
android:id="#+id/txtHeroName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginLeft="16dp" />
</LinearLayout>
this is my MainActivity.kt
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val listHeroes = listOf(
Hero(
name = "Thor",
image = "https://media.skyegrid.id/wp-content/uploads/2019/06/Thor-4-1.jpg"
),
Hero(
name = "Captain America",
image = "https://i.annihil.us/u/prod/marvel/i/mg/1/c0/537ba2bfd6bab/standard_xlarge.jpg"
),
Hero(
name = "Iron Man",
image = "https://i.annihil.us/u/prod/marvel/i/mg/6/a0/55b6a25e654e6/standard_xlarge.jpg"
)
)
val heroesAdapter = HeroAdapter(listHeroes) {hero ->
Toast.makeText(this, "hero clicked ${hero.name}", Toast.LENGTH_SHORT).show()
}
rvMain.apply {
layoutManager = LinearLayoutManager(this#MainActivity)
adapter = heroesAdapter
}
}
}
this is my adapter
class HeroAdapter(
private val heroes: List<Hero>,
private val adapterOnclick: (Hero) -> Unit
) : RecyclerView.Adapter() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): HeroAdapter.HeroHolder {
return HeroHolder(
LayoutInflater.from(parent.context).inflate(
R.layout.item_hero,
parent,
false
)
)
}
override fun getItemCount(): Int = heroes.size
override fun onBindViewHolder(holder: HeroAdapter.HeroHolder, position: Int) {
holder.binHero(heroes[position])
}
inner class HeroHolder(view: View) : RecyclerView.ViewHolder(view) {
fun binHero(hero: Hero) {
itemView.apply {
txtHeroName.text = hero.name
Picasso.get().load(hero.image).into(imgHeroes)
setOnClickListener {
adapterOnclick(hero)
}
}
}
}
}
this is my emulator
https://i.stack.imgur.com/0ePUC.png
I wrote this code using recyclerview and I got the image that I got from the url, why my image didn't appear, I wrote this code using the kotlin programming language
please help me
Related
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'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.
[enter image description here][1]
[enter image description here][2]VHFV.png
strong text
[2]: https://i.stack.imgur.com/YJOpm.png
activity_main
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#170628"
android:orientation="vertical"
tools:context=".MainActivity">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/rv_images"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
image_layout.xml
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto">
<androidx.cardview.widget.CardView
android:layout_width="100dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:layout_margin="5dp"
app:cardCornerRadius="10dp"
android:layout_height="100dp">
<ImageView
android:id="#+id/big_image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
android:src="#drawable/zone_images" />
</androidx.cardview.widget.CardView>
</androidx.constraintlayout.widget.ConstraintLayout>
MainActivity
class MainActivity : AppCompatActivity() {
private lateinit var zoneBinding: ActivityMainBinding
var image = ArrayList<String>()
lateinit var zoneAdapter:ZoneImagesAdapter
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
zoneBinding= DataBindingUtil.setContentView(this,R.layout.activity_main)
buildData()
setRecyclerView()
}
private fun buildData() {
image.add("https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQzx__blVU5FWJAUCU4d9-E095_n3Fgy1tuxA&usqp=CAU")
image.add("https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQh90iDDn5BoUnZqANXUszd17_Q-RhfRo8V6Q&usqp=CAU")
image.add("https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQzx__blVU5FWJAUCU4d9-E095_n3Fgy1tuxA&usqp=CAU")
image.add("https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQh90iDDn5BoUnZqANXUszd17_Q-RhfRo8V6Q&usqp=CAU")
image.add("https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQzx__blVU5FWJAUCU4d9-E095_n3Fgy1tuxA&usqp=CAU")
image.add("https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQh90iDDn5BoUnZqANXUszd17_Q-RhfRo8V6Q&usqp=CAU")
}
private fun setRecyclerView() {
zoneAdapter = ZoneImagesAdapter(image)
val flexboxLayoutManager = FlexboxLayoutManager(this)
flexboxLayoutManager.flexDirection =FlexDirection.ROW
flexboxLayoutManager.flexWrap = FlexWrap.WRAP
flexboxLayoutManager.justifyContent = JustifyContent.CENTER
flexboxLayoutManager.alignItems = AlignItems.STRETCH
zoneBinding.rvImages.apply {
adapter=zoneAdapter
layoutManager=flexboxLayoutManager
}
}
Adapter
class ZoneImagesAdapter (var listOfImageUrl:ArrayList<String>):
RecyclerView.Adapter<ZoneImagesAdapter.ImageViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ImageViewHolder {
val view: View = LayoutInflater.from(parent.context)
.inflate(R.layout.big_image_layout, parent, false)
return ImageViewHolder(view)
}
override fun onBindViewHolder(holder: ImageViewHolder, position: Int) {
val image = listOfImageUrl[position]
holder.setImages(image)
}
override fun getItemCount(): Int {
return listOfImageUrl.size
}
class ImageViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
var zoneImage:ImageView=itemView.findViewById(R.id.big_image)
fun setImages(images: String) {
Glide.with(zoneImage).load(images).into(zoneImage)
val layoutParams:ViewGroup.LayoutParams = zoneImage.layoutParams
if (layoutParams is FlexboxLayoutManager.LayoutParams){
val flexboxLp:FlexboxLayoutManager.LayoutParams= layoutParams as FlexboxLayoutManager.LayoutParams
flexboxLp.flexGrow= 1.0f
}
}
}
}
How can I achieve this layout that is showing inside image using recyclerView, ?? I use flexboxLayoutManager for this but I do not know how can I used, Can anyone help me to make this layout that is showing inside image
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
I have an exisitng code which I integrate with Live data by using retrofit.
Now if I want to integrate databinding, where are all changes to be done to make the code looks perfect?
Here is my code.
activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.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:background="#000000"
android:layout_height="match_parent"
tools:context=".MainActivity">
<LinearLayout
android:id="#+id/linearLayout2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="vertical"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="Android Versions"
android:textColor="#ffffff"
android:textSize="20sp" />
<android.support.v7.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
items.xml:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.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:background="#445566"
android:layout_margin="5dp"
android:layout_height="wrap_content">
<TextView
android:id="#+id/tvFname"
android:padding="5dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="top|start"
android:layout_marginTop="8dp"
android:textColor="#ffffff"
android:layout_weight="1"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<TextView
android:id="#+id/tvLname"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center|start"
android:padding="5dp"
android:layout_marginTop="10dp"
android:layout_weight="1"
android:ellipsize="end"
android:textColor="#ffffff"
android:maxLines="5"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/tvFname"/>
</android.support.constraint.ConstraintLayout>
Here is view model class which I integrated
class AndroidViewModel:ViewModel() {
private val mService = RetrofitService()
fun getAndroidData():MutableLiveData<List<AndroidData>>?{
return mService.loadAndroidData()
}
}
Pojo class generated is just a simple one:
data class AndroidData (val name:String, val apiLevel:String)
Service integration:
class RetrofitService {
val liveUserResponse:MutableLiveData<List<AndroidData>> = MutableLiveData()
companion object Factory {
var gson = GsonBuilder().setLenient().create()
fun create(): ApiInterface {
Log.e("retrofit","create")
val retrofit = Retrofit.Builder()
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create(gson))
.baseUrl("https://learn2crack-json.herokuapp.com/api/")
.build()
return retrofit.create(ApiInterface::class.java)
}
}
fun loadAndroidData(): MutableLiveData<List<AndroidData>>? {
Log.e("loadAndroidData","yes")
val retrofitCall = create().getAndroid()
retrofitCall.enqueue(object : Callback<List<AndroidData>> {
override fun onFailure(call: Call<List<AndroidData>>, t: Throwable?) {
Log.e("on Failure :", "retrofit error")
}
override fun onResponse(call: Call<List<AndroidData>>, response: retrofit2.Response<List<AndroidData>>) {
val list = response.body()
for (i in list.orEmpty()){
Log.e("on response 1:", i.name)
}
liveUserResponse.value = list
Log.e("hasActiveObservers 1", liveUserResponse.hasActiveObservers().toString()+" check")
Log.e("on response 2 :", liveUserResponse.toString()+" check")
}
})
return liveUserResponse
}
Main Activity:
class MainActivity : AppCompatActivity(){
private lateinit var linearLayoutManager: LinearLayoutManager
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
linearLayoutManager = LinearLayoutManager(this)
recyclerView.setHasFixedSize(true)
getAndroidVersion()
}
private fun getAndroidVersion() {
Log.e("getAndroidVersion", "yes")
val mAndroidViewModel = ViewModelProviders.of(this#MainActivity).get(AndroidViewModel::class.java)
mAndroidViewModel.getAndroidData()?.observe(this, Observer<List<AndroidData>> { androidList ->
Log.e("list", androidList?.size.toString())
recyclerView.adapter = EmpAdapter(this#MainActivity, androidList as ArrayList<AndroidData>, object :
ItemClickListener {
override fun onItemClick(pos: Int, name:String) {
Toast.makeText(applicationContext, "item "+pos+ "clicked"+ name, Toast.LENGTH_LONG).show()
}
})
})
}
}
Adapter class:
class EmpAdapter(
var context: MainActivity,
var mEmpList: ArrayList<AndroidData>,
private val itemClick:ItemClickListener
) :
RecyclerView.Adapter<EmpAdapter.EmpHolder>() {
override fun getItemCount(): Int {
return mEmpList.size
}
companion object {
var mItemClickListener : ItemClickListener? = null
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): EmpHolder {
val view = LayoutInflater.from(context).inflate(R.layout.items, parent, false)
return EmpHolder(view)
}
override fun onBindViewHolder(holder: EmpHolder, position: Int) {
mItemClickListener = itemClick
holder.tvFname?.text = mEmpList[position].name
holder.tvLname?.text = mEmpList[position].apiLevel
RxView.clicks(holder.mView).subscribe {
mItemClickListener!!.onItemClick(position,mEmpList[position].name)
}
}
class EmpHolder(view: View) : RecyclerView.ViewHolder(view) {
val tvFname = view.tvFname
val tvLname = view.tvLname
val mView = view
}
}
interfaces for retrofit:
interface ApiInterface {
#GET("android")
fun getAndroid(): Call<List<AndroidData>>
}
Now my question is, if I integrate tag and in xml, which variable i need to specify for textview to integrate to connect for textview in adapter? Kindly guide me where are all I need to change to apply, if I use live data
First of all, i strongly recommend to use a Retrofit Adapter that converts the response into LiveData automatically for you. See this example
https://github.com/yasiralijaved/android-architecture-components/blob/master/component_http/src/main/java/com/yasiralijaved/android/arc/component/http/BackendService.java
Secondly there are detailed tutorials out there which can surely help you how to implement Data Bindings in RecyclerView Adapter. A few tutorials are:
https://medium.com/androiddevelopers/android-data-binding-recyclerview-db7c40d9f0e4
https://android.jlelse.eu/how-to-bind-a-list-of-items-to-a-recyclerview-with-android-data-binding-1bd08b4796b4
Do let me know if it is still not clear and i will share some more details.
Happy coding!!