Changing Background Color of Selected Item in Recyclerview

Changing background color of selected item in recyclerview

Finally, I got the answer.

public void onBindViewHolder(final ViewHolder holder, final int position) {
holder.tv1.setText(android_versionnames[position]);

holder.row_linearlayout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
row_index=position;
notifyDataSetChanged();
}
});
if(row_index==position){
holder.row_linearlayout.setBackgroundColor(Color.parseColor("#567845"));
holder.tv1.setTextColor(Color.parseColor("#ffffff"));
}
else
{
holder.row_linearlayout.setBackgroundColor(Color.parseColor("#ffffff"));
holder.tv1.setTextColor(Color.parseColor("#000000"));
}

}

here 'row_index' is set as '-1' initially

public class ViewHolder extends RecyclerView.ViewHolder {
private TextView tv1;
LinearLayout row_linearlayout;
RecyclerView rv2;

public ViewHolder(final View itemView) {
super(itemView);
tv1=(TextView)itemView.findViewById(R.id.txtView1);
row_linearlayout=(LinearLayout)itemView.findViewById(R.id.row_linrLayout);
rv2=(RecyclerView)itemView.findViewById(R.id.recyclerView1);
}
}

How to change the background color of selected item in RecyclerView

Call notifyDataSetChanged

holder.itemView.setOnClickListener { 
rowindex = position
mListener?.onItemClick(holder.itemView, categories[position])
notifyDataSetChanged()
}

if (rowindex == position) {
holder.itemView.setBackgroundColor(Color.parseColor("#FED07A"))
} else {
holder.itemView.setBackgroundColor(Color.parseColor("#ffffff"))
}

Change background color of selectedItem in recyclerView android databinding

Here an example:

This video might give you an overview: https://youtu.be/g8GDLOMt600 (You are not going to find a solution for this question in this video. It just gives you a nice overview about data binding, RecyclerView and ClickListener)

You need the following files:
YourFragment, fragment_your.xml, list_item

class YourFragment : Fragment(){

override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {

// Get a reference to the binding object and inflate the fragment views.
val binding: FragmentYoutFragmentBinding = DataBindingUtil.inflate(
inflater, R.layout.fragment_your, container, false
)

binding.lifecycleOwner = this

// Very important! Otherwise the layout of the recycler view wont work
binding.yourList.layoutManager = LinearLayoutManager(this.context)

// Adapter for the RecyclerView in order to show all items
val adapter = YourAdapter(YourListener{youtItemObeject: YourItemObject, view:
View ->

// THIS IS THE SOLUTION
// change selected item image, if user selects this item in the list
view.ok_image.setImageResource(R.drawable.ok_green)
})

}
}

in list_item.xml

<?xml version="1.0" encoding="utf-8"?>
<layout 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">

<data>

<variable
name="your_object"
type="your_package_name.your_folder.YourObject" />

<variable
name="clickListener"
type="your_package_name.your_folder.YourListener" />
</data>

<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/constraint_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/item_margin_horizontal"
android:layout_marginTop="@dimen/item_margin_vertical"
android:layout_marginEnd="@dimen/item_margin_horizontal"
android:layout_marginBottom="@dimen/item_margin_vertical"
android:onClick="@{(thisView) -> clickListener.onClick(your_object, thisView)}">

<ImageView
android:id="@+id/ok_image"
... />

</androidx.constraintlayout.widget.ConstraintLayout>
</layout>

And add YourListener class into the adapter-File

class YourAdapter(val clickListener: YourListener) :
ListAdapter<YourObject, YourAdapter.ViewHolder>(YourDiffCallback()) {

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
return ViewHolder.from(parent)
}

override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.bind(getItem(position)!!, clickListener)
}

class ViewHolder private constructor(val binding: ListItemYourObjectBinding) :
RecyclerView.ViewHolder(binding.root) {

companion object {
fun from(parent: ViewGroup): ViewHolder {
val layoutInflater = LayoutInflater.from(parent.context)

val binding =
ListItemYourObjectBinding.inflate(layoutInflater, parent, false)
return ViewHolder(binding)
}
}

fun bind(item: YourObject, clickListener: YourListener) {
binding.yourObject = item
binding.clickListener = clickListener

// for example
binding.okImage.setImageRessouce(R.drawable.ok_gray)

binding.executePendingBindings()
}
}
}

/**
* Callback for calculating the diff between two non-null items in a list.
*
* Used by ListAdapter to calculate the minimum number of changes between and old list
* and a new list that's been passed to `submitList`.
*/
class YourObjectDiffCallback : DiffUtil.ItemCallback<YourObject>() {
override fun areItemsTheSame(oldItem: YourObject, newItem: YourObject): Boolean {
return oldItem.yourObjectValue == newItem.yourObjectValue
}

override fun areContentsTheSame(oldItem: YourObject, newItem: YourObject): Boolean {
return oldItem == newItem
}
}

/**
* Listener for your list items
*/

class YourListener(val clickListener: (yourObject: YourObject,
view: View) -> Unit) {
fun onClick(yourObject: YourObject, view: View) =
clickListener(yourObject, view)
}

Kotlin:change background color of RecyclerView item by click on it

it's quite easy to do :) You need to just remember how the RecyclerView works:

  1. It creates few ViewHolders
  2. When you scroll your list, the ViewHolders are reused.
  3. If you have for example 100 items on the list, it will create 5-6 ViewHolders and will reuse them.

So having that in mind, when onBindViewHolder() is called, the easiest thing you can do is to check some state of the item, and then choose background color of the item. In this scenario you can select/deselect multiple items in the list. If you want to have only one checked, you will need to change the items.map {} function a little bit:

Please keep in mind that I wrote below from my head, you will also need to override some more functions in adapter etc.

class MyAdapter(private val onItemClick: (YouItem) -> Unit): RecyclerView.Adapter() {

private var items: List<YourItem>

fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
val payload = items[holder.adapterPosition]
holder.itemView.setOnClickListener {
onItemClick(payload)
}
holder.itemView.background = if(payload.someState) firstBackground else otherBackground
}

fun updateItems(updatedItems: List<YourItem>) {
items = updatedItems
notifyDataSetChanged()
}
}
class YourActivity: Activity() {

private lateinit var items: List<YourItem>

fun onCreate(savedInstanceState: Bundle) {
super.onCreate(savedInstanceState)
...
items: List<YourItem> = getItemsFromSomewhere()
val adapter = MyAdapter { clickedItem ->
val updatedItems = items.map {
if(it == clickedItem) {
it.copy(someState = !it.someState)
} else {
it
}
items = updatedItems
adapter.updateItems(updatedItems)
}
}
}
data class YourItem(val someState: Boolean)

Change background color of selected item in recyclerview

in your model,
take a boolean variable, and create getter setter methods

private boolean isSelected = false

public boolean isSelected() {
return isSelected;
}

public void setSelected(boolean selected) {
isSelected = selected;
}

in your OnBindViewHolder

viewHolder.MainLinearLayout.SetBackgroundColor(list[position].isSelected()?v.Resources.GetColor(Resource.Color.white):v.Resources.GetColor(Resource.Color.black));

in your onClick event, // Code below is edited

Note: For Best practice setTag(position) with your position to your view that is getting clicked and use that tag value as a position.

int pos = (int) view.getTag(); 
list[pos].setSelected(!list[pos].isSelected());
notifyItemChanged(position);

Recyclerview row item selection color change

Change the onBindViewHolder method of your NavigationDrawerAdapter.java into this:

@Override
public void onBindViewHolder(MyViewHolder holder, int position) {
if(position == selected_item) {
holder.title.setTextColor(Color.parseColor("#00aaff"));
holder.imgViewIcon.setBackgroundResource(R.drawable.ic_circle);
} else {
holder.title.setTextColor(Color.parseColor("#00000")); //actually you should set to the normal text color
holder.imgViewIcon.setBackgroundResource(0);
}
NavDrawerItem current = data.get(position);
holder.title.setText(current.getTitle());
holder.imgViewIcon.setImageResource(current.getIcon());

}

Change background of RecyclerView selected item

Put global int variable into your adapter class like int selectedPosition = 9999; Check comments for more info

   public void onBindViewHolder(final DateHolder holder, final int position
{
final String monthDate = arrayListDate.get(position);
final GradientDrawable gd = new GradientDrawable();
gd.setShape(GradientDrawable.OVAL);
final GradientDrawable drawable=new GradientDrawable();
drawable.setShape(GradientDrawable.OVAL);
// if its selected position change background;
if(selectedPosition == position){

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
drawable.setColor(Color.parseColor("#006EB9"));
drawable.setSize(width,height);
holder.tvDate.setTextColor(getResources().getColor(R.color.white));
holder.tvDate.setBackground(drawable);
}
}
ViewTreeObserver viewTreeObserver = relativeLayout.getViewTreeObserver();
viewTreeObserver.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { holder.tvDate.getViewTreeObserver().removeOnGlobalLayoutListener(this);
width = holder.tvDate.getMeasuredWidth();
height = holder.tvDate.getLineHeight();
} else {
//noinspection deprecation
holder.tvDate.getViewTreeObserver().removeGlobalOnLayoutListener(this);
width = holder.tvDate.getMeasuredWidth();
height= holder.tvDate.getLineHeight();
}

}
});

holder.tvDate.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//notify position if there was previous position
if(selectedPosition != 9999){
int temp= selectedPosition;
selectedPosition = position;
notifyItemChanged(temp);
}
else{
selectedPosition= position;
}
// put new selected position

//notify new position
notifyItemChanged(position);

}
});
}

Kotlin Recyclerview row item selection background color change

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



Related Topics



Leave a reply



Submit