Reputation: 21
I am developing an android application in which I have a Horizontal Recyclerview
holds text of 12 month names. When app opens, the current month background will change to red. Till here everything is working fine and as expected.
Current behavior: Whenever I select the other month name, selected month name background color
is changing to red successfully but previous selected month name background
is not changing to white it still remains in red color.
Expected behavior: Now Whenever I select the other month name, I need to change the background color of selected month name to red and previous selected month name background to white.
below is my recyclerview adapter
class code:
public class MonthNamesAdapter extends RecyclerView.Adapter<MonthNamesAdapter.MonthNameViewHolder> {
List<MonthNamesModel> monthNamesModelList;
MonthNamesModel monthNamesModel;
Context context;
int lastPosition = -1;
Calendar calendar;
int month, year, date;
String[] monthName = {"January", "February",
"March", "April", "May", "June", "July",
"August", "September", "October", "November",
"December"};
String monthStr;
TextView monthNameTv, numberOfDaysTv;
LinearLayout monthNamesLinearLayout;
public MonthNamesAdapter(List<MonthNamesModel> monthNamesModelList, Context context) {
this.monthNamesModelList = monthNamesModelList;
this.context = context;
}
@Override
public MonthNameViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
calendar = Calendar.getInstance();
month = calendar.get(Calendar.MONTH);
monthStr = monthName[month];
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.month_name_list, parent, false);
return new MonthNameViewHolder(view);
}
@Override
public void onBindViewHolder(final MonthNameViewHolder holder, final int position) {
monthNamesModel = monthNamesModelList.get(position);
holder.monthNameTv.setText(monthNamesModel.getMonthName());
holder.numberOfDaysTv.setText(monthNamesModel.getNumberOfDays());
Log.d("MonthNameAdapter", "onBindViewHolder: Month Number"+month);
holder.monthNamesLinearLayout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
lastPosition = position;
notifyDataSetChanged();
}
});
if (lastPosition == position){
holder.monthNamesLinearLayout.setBackgroundColor(context.getResources().getColor(R.color.app_color));
holder.numberOfDaysTv.setTextColor(context.getResources().getColor(R.color.colorPrimary));
holder.monthNameTv.setTextColor(context.getResources().getColor(R.color.colorPrimary));
}else{
holder.monthNamesLinearLayout.setBackgroundColor(context.getResources().getColor(R.color.colorPrimary));
holder.numberOfDaysTv.setTextColor(context.getResources().getColor(R.color.colorBlack));
holder.monthNameTv.setTextColor(context.getResources().getColor(R.color.app_color));
}
if (lastPosition !=position){
if (month == position){
holder.monthNamesLinearLayout.setBackgroundColor(context.getResources().getColor(R.color.app_color));
holder.numberOfDaysTv.setTextColor(context.getResources().getColor(R.color.colorPrimary));
holder.monthNameTv.setTextColor(context.getResources().getColor(R.color.colorPrimary));
}
}
}
@Override
public int getItemCount() {
return monthNamesModelList.size();
}
public class MonthNameViewHolder extends RecyclerView.ViewHolder {
TextView monthNameTv, numberOfDaysTv;
LinearLayout monthNamesLinearLayout;
public MonthNameViewHolder(View itemView) {
super(itemView);
monthNameTv = itemView.findViewById(R.id.monthNameTv);
numberOfDaysTv = itemView.findViewById(R.id.numberOfDaysTv);
monthNamesLinearLayout = itemView.findViewById(R.id.monthNamesLinearLayout);
}
}
}
Any help would be very grateful!!! Thanks in advance...
Upvotes: 1
Views: 933
Reputation:
make one pojo class for two field month name and boolean for selected like below code ..
public class Month {
private String value;
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
private boolean selectedFlag;
public boolean isSelectedFlag() {
return selectedFlag;
}
public void setSelectedFlag(boolean selectedFlag) {
this.selectedFlag = selectedFlag;
}
}
then after make interface into adapter to handle click event for selected value like below..
List<Month> mStringList = new ArrayList<>();// hear you can pass any pojo class object.
Context mContext;
onItemClickListner onItemClickListner;
public void setOnItemClickListner(RecyclerViewAdpater.onItemClickListner onItemClickListner) {
this.onItemClickListner = onItemClickListner;
}
public interface onItemClickListner {
void onClick(Month str);//pass your object types.
}
@Override
public void onBindViewHolder(ItemViewHolder holder, int position) {
Month data = mStringList.get(position); // if you pass object of class then create that class object.
if (data.isSelectedFlag()){
holder.textView.setBackgroundColor(Color.RED);
}
else{
holder.textView.setBackgroundColor(Color.WHITE);
}
// below code handle click event on recycler view item.
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
onItemClickListner.onClick(data);
}
});
}
then after define all Month name into Month class object and selected value false then object add into list and bind into adapter. after adapter bind into recycler view then called below code ..
recyclerViewAdpater.setOnItemClickListner(new RecyclerViewAdpater.onItemClickListner() {
@Override
public void onClick(Month str) {
str.setSelectedFlag(true);
recyclerViewAdpater.notifyDataSetChanged();
}
});
Upvotes: 0
Reputation: 168
Try this
Add an Interface
public interface PositionCallBack {
void posChanged(int currentPos); //currentPos can also be boolean
}
In ModelClass add one more string or boolean or int as "isSelected", Initialize first setIsSelected("0") in the MainActivity// if boolean set it as false
In the adapter class
currentPos=Integer.parseInt(monthNamesModelList.get(position).getIsSelected());
if (currentPos==1){
holder.monthNamesLinearLayout.setBackgroundColor(context.getResources().getColor(R.color.colorRed));
}else {
holder.monthNamesLinearLayout.setBackgroundColor(context.getResources().getColor(R.color.colorWhite));
}
holder.monthNamesLinearLayout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
for (int i=0;i<monthNamesModelList.size();i++){
MonthNames monthNames=new MonthNames();
if (i==position){
monthNames.setIsSelected("1");
}else {
monthNames.setIsSelected("0");
}
monthNames.setMonthNames(monthStrins[i]);
}
notifyDataSetChanged();
notifyItemChanged(position);
positionCallBack.posChanged(position);
}
});
In MainActivity
monthNamess= new String[]{"January", "February",
"March", "April", "May", "June", "July",
"August", "September", "October", "November",
"December"};
Calendar calendar = Calendar.getInstance();
int month = calendar.get(Calendar.MONTH);
for (int i=0;i< monthNamess.length;i++){
MonthNames monthNames=new MonthNames();
if (i==month){
monthNames.setIsSelected("1");
}else {
monthNames.setIsSelected("0");
}
monthNames.setMonthNames(monthNamess[i]);
arrayList.add(monthNames);
}
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(context,
LinearLayoutManager.HORIZONTAL, false);
recycler_view.setLayoutManager(mLayoutManager);
monthNamesAdapter=new MonthNamesAdapter(arrayList,context,this,monthNamess);
recycler_view.setAdapter(monthNamesAdapter);
monthNamesAdapter.notifyDataSetChanged();
// Here arrayList is the list of Model Class
Implement the Interface in MainActivity
@Override
public void posChanged(int currentPos) {
arrayList=new ArrayList<>();
for (int i=0;i<monthNamess.length;i++){
MonthNames monthNames=new MonthNames();
if (i==currentPos){
monthNames.setCurrentPos("1");
}else {
monthNames.setCurrentPos("0");
}
monthNames.setMonthNames(monthNamess[i]);
arrayList.add(monthNames);
}
monthNamesAdapter=new MonthNamesAdapter(arrayList,context,this,monthNamess);
recycler_view.setAdapter(monthNamesAdapter);
monthNamesAdapter.notifyDataSetChanged();
}
Upvotes: 1
Reputation: 6107
Set a default property to views and changed the property if that position satisfy your condition:
//set a default property sot not selected state
holder.monthNamesLinearLayout.setBackgroundColor(context.getResources().getColor(R.color.colorPrimary));
holder.numberOfDaysTv.setTextColor(context.getResources().getColor(R.color.colorBlack));
holder.monthNameTv.setTextColor(context.getResources().getColor(R.color.app_color));
// if position satisfy you condition then set property for selected state.
if (lastPosition == position ){
holder.monthNamesLinearLayout.setBackgroundColor(context.getResources().getColor(R.color.app_color));
holder.numberOfDaysTv.setTextColor(context.getResources().getColor(R.color.colorPrimary));
holder.monthNameTv.setTextColor(context.getResources().getColor(R.color.colorPrimary));
}else if( month == position){
holder.monthNamesLinearLayout.setBackgroundColor(context.getResources().getColor(R.color.app_color));
holder.numberOfDaysTv.setTextColor(context.getResources().getColor(R.color.colorPrimary));
holder.monthNameTv.setTextColor(context.getResources().getColor(R.color.colorPrimary));
}
I think this way you don't have to think complex way.
Edit:
You can make it more simple if you assign calendar.get(Calendar.MONTH);
value to lastPosition
initially. Then you can ignore month == position
this condition if that didn't break you business logic.
Upvotes: 0
Reputation: 753
may be you can add one boolean variable in 'MonthNamesModel' with name isSelected
that will help with to maintain all you need just check that variable in onBindViewHolder
if(monthNamesModel .getIsSelected())
{holder.monthNamesLinearLayout.setBackgroundColor(context.getResources().getColor(R.color.app_color));
holder.numberOfDaysTv.setTextColor(context.getResources().getColor(R.color.colorPrimary));
holder.monthNameTv.setTextColor(context.getResources().getColor(R.color.colorPrimary));
}else {holder.monthNamesLinearLayout.setBackgroundColor(context.getResources().getColor(R.color.colorPrimary));
holder.numberOfDaysTv.setTextColor(context.getResources().getColor(R.color.colorBlack));
holder.monthNameTv.setTextColor(context.getResources().getColor(R.color.app_color));
}
and change that variable in
holder.monthNamesLinearLayout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if( monthNamesModel .getIsSelected())
{
monthNamesModelList.get(position).setIsSelected(false);
monthNamesModel .setIsSelected(false);
}
else
{
monthNamesModelList.get(position).setIsSelected(true);
monthNamesModel .setIsSelected(true) ;
}
notifyDataSetChanged();
}
});
Upvotes: 0
Reputation: 3455
Try this :
@Override
public void onBindViewHolder(final MonthNameViewHolder holder, final int position) {
monthNamesModel = monthNamesModelList.get(position);
holder.monthNameTv.setText(monthNamesModel.getMonthName());
holder.numberOfDaysTv.setText(monthNamesModel.getNumberOfDays());
Log.d("MonthNameAdapter", "onBindViewHolder: Month Number"+month);
if (lastPosition == position){
holder.monthNamesLinearLayout.setBackgroundColor(context.getResources().getColor(R.color.app_color));
holder.numberOfDaysTv.setTextColor(context.getResources().getColor(R.color.colorPrimary));
holder.monthNameTv.setTextColor(context.getResources().getColor(R.color.colorPrimary));
}else{
holder.monthNamesLinearLayout.setBackgroundColor(context.getResources().getColor(R.color.colorPrimary));
holder.numberOfDaysTv.setTextColor(context.getResources().getColor(R.color.colorBlack));
holder.monthNameTv.setTextColor(context.getResources().getColor(R.color.app_color));
}
holder.monthNamesLinearLayout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
notifyDataSetChanged();
}
});
Upvotes: 0