Reputation: 243
I want to make selction menu for profiles using RecyclerView. I created it with RecyclerView. Now i am getting problem in onItemClickListener. I want to change background of CardView and Text Color on item select. at a time only one item can be selected. And on next button click it should redirect to activity according to selection.
This is my screen looks like:
public class SelectProfile extends AppCompatActivity {
private String[] mTextData;
private int[] mImgData;
RecyclerView recyclerView;
private ProfileAdapter profileAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_select_profile);
recyclerView = findViewById(R.id.recycleProfile);
RecyclerView.LayoutManager layoutManager = new GridLayoutManager(this,2);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setHasFixedSize(true);
profileAdapter = new ProfileAdapter();
recyclerView.setAdapter(profileAdapter);
int imgData[] = {R.drawable.ic_college_icon,R.drawable.ic_parent,R.drawable.ic_student,R.drawable.ic_teaching,
R.drawable.ic_non_teaching,R.drawable.ic_other};
final String textData[] = {"School/College","Parent","Student","Teaching Staff","Non-Teaching Staff","Other"};
profileAdapter.setData(imgData,textData);
}
private class ProfileAdapter extends RecyclerView.Adapter<ProfileAdapter.ProfileAdapterViewHolder>{
int index = -1;
@NonNull
@Override
public ProfileAdapterViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
Context context = parent.getContext();
int layoutIdForListItem = R.layout.profile_item;
LayoutInflater layoutInflater = LayoutInflater.from(context);
boolean shouldAttachToParent = false;
View view = layoutInflater.inflate(layoutIdForListItem,parent,shouldAttachToParent);
return new ProfileAdapterViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull final ProfileAdapterViewHolder holder,final int position) {
int mImage = mImgData[position];
String mText = mTextData[position];
holder.img.setImageResource(mImage);
holder.txt.setText(mText);
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
index = position;
notifyDataSetChanged();
}
});
if (index == position){
holder.card.setBackground(getResources().getDrawable(R.drawable.bg_select_profile));
holder.txt.setTextColor(getResources().getColor(R.color.colorPrimary));
}else {
holder.card.setCardBackgroundColor(getResources().getColor(android.R.color.white));
holder.txt.setTextColor(getResources().getColor(R.color.gray));
}
}
@Override
public int getItemCount() {
if (null == mImgData) return 0;
return mImgData.length;
}
public class ProfileAdapterViewHolder extends RecyclerView.ViewHolder {
private final AppCompatImageView img;
private final TextView txt;
private final CardView card;
private ProfileAdapterViewHolder(@NonNull View itemView) {
super(itemView);
img = itemView.findViewById(R.id.img);
txt = itemView.findViewById(R.id.txt);
card = itemView.findViewById(R.id.card);
}
}
private void setData(int[] imgData,String[] txtData){
mImgData = imgData;
mTextData = txtData;
notifyDataSetChanged();
}
}
}
Upvotes: 1
Views: 3329
Reputation: 1968
You can pass a listener object in the constructor which implements by fragment OR activity
/**
* item click interface of adapter
*/
public interface ProfileAdapterListener {
void onItemClick(int position, ProfileAdapterViewHolder holder)
}
This interface implements by Fragment OR Activity
/**
* On item clicked Implement Method from adapter listener.
*
* @param position
*/
@Override
public void onItemClick(int position, ProfileAdapterViewHolder holder) {
// Here you can call that method
}
Then you pass this listener in the constructor of the adapter.
private void buildRecyclerView() {
profileAdapter = new ProfileAdapter(this);
recyclerView.setAdapter(profileAdapter);
}
In the constructor, you can assign like this
private ProfileAdapterListener mProfileAdapterListener;
public OfferAdapter(ProfileAdapterListener mProfileAdapterListener) {
this.mProfileAdapterListener = mProfileAdapterListener
}
}
Now you can use this listener by setting click listener on any Viwe like this
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
mProfileAdapterListener.onItemClick(position, holder);
}
});
It returns to call the method of onItemClick
which implements this method. This is the safe and sound method to click on each item or any view in the item.
Upvotes: 0
Reputation: 166
Your approach of using an Index variable is right, add getter and setter method for the index. But you can't set the onClickListener on the adapter. Instead, set the listener on the card view like this ->
holder.card.setOnItemClickListener(new ClickListener() {
@Override
public void onItemClick(int position, View v) {
index = position;
notifyDataSetChanged();
}
});
Add this method inside your adapter class ->
public int getSelectedIndex(){
return this.index; }
After that, from your Activity, inside your NEXT button's onClickListener do the following thing,
btnNext.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(profileAdapter.getSelectedIndex() == 1)
//goto activity of your desire and so on
}
});
Upvotes: 1
Reputation: 492
change and adjust your adapter like as below:
private class ProfileAdapter extends RecyclerView.Adapter<ProfileAdapter.ProfileAdapterViewHolder>{
int index = -1;
@NonNull
@Override
public ProfileAdapterViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
Context context = parent.getContext();
int layoutIdForListItem = R.layout.profile_item;
LayoutInflater layoutInflater = LayoutInflater.from(context);
boolean shouldAttachToParent = false;
View view = layoutInflater.inflate(layoutIdForListItem,parent,shouldAttachToParent);
return new ProfileAdapterViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull ProfileAdapterViewHolder holder, int position) {
int mImage = mImgData[position];
String mText = mTextData[position];
holder.img.setImageResource(mImage);
holder.txt.setText(mText);
if (index == position){
holder.card.setCardBackgroundColor(getResources().getColor(R.color.colorPrimary));
holder.txt.setTextColor(getResources().getColor(R.color.colorPrimary));
}else {
holder.card.setCardBackgroundColor(getResources().getColor(android.R.color.white));
holder.txt.setTextColor(getResources().getColor(R.color.gray));
}
}
@Override
public int getItemCount() {
if (null == mImgData) return 0;
return mImgData.length;
}
public class ProfileAdapterViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
private final AppCompatImageView img;
private final TextView txt;
private final CardView card;
private ProfileAdapterViewHolder(@NonNull View itemView) {
super(itemView);
img = itemView.findViewById(R.id.img);
txt = itemView.findViewById(R.id.txt);
card = itemView.findViewById(R.id.card);
itemView.setOnClickListener(this);
}
@Override
public void onClick(View v) {
setIndex(getAdapterPosition());
notifyDataSetChanged();
}
}
private void setData(int[] imgData,String[] txtData){
mImgData = imgData;
mTextData = txtData;
notifyDataSetChanged();
}
public void setOnItemClickListener(ClickListener clickListener){
mClickListener = clickListener;
}
private void setIndex(int index){
this.index=index;
}
}
you may not need the ClickListener.
Upvotes: 0
Reputation: 2835
Add OnClickListner on holder root view , best place to write listener is in onCreateViewHolder , so replace your onCreateViewHolder with following
public ProfileAdapterViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
Context context = parent.getContext();
int layoutIdForListItem = R.layout.profile_item;
LayoutInflater layoutInflater = LayoutInflater.from(context);
boolean shouldAttachToParent = false;
View view = layoutInflater.inflate(layoutIdForListItem,parent,shouldAttachToParent);
ViewHolder viewHolder = new ViewHolder(view);
view.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
postion=viewHolder.getAdapterPosition();
notifyDataSetChanged();
}
});
return viewHolder ;
}
Upvotes: 0
Reputation: 254
Use your card view as a parent layout for your recycler view item and apply on click listener to that card view in recycler view adapter.
holder.your_card_view.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// get you recyclerview item position here
}
});
Upvotes: 0