How to make checkbox in CardView behave like RadioGroup? - android

I want to make my CardView CheckBox behave like a RadioGroup so that whenever I check another Card the previous will be unchecked. I now have successfully create a CardView with checkboxes but I am not sure how to make them behave like I want to.
cardview.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clickable="true"
android:layout_margin="#dimen/activity_horizontal_margin"
android:background="?android:selectableItemBackground"
android:id="#+id/suggest_time_card_view"
>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="#dimen/activity_horizontal_margin"
android:background="#drawable/back"
android:gravity="center"
android:padding="#dimen/activity_horizontal_margin"
android:id="#+id/tvSuggestTime"
/>
<CheckBox
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/cbSuggestTime"
android:visibility="invisible"
android:checked="false"
android:padding="#dimen/activity_horizontal_margin"
android:layout_alignBottom="#+id/tvSuggestTime"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true" />
</RelativeLayout>
</android.support.v7.widget.CardView>
CardViewAdapter:
public class SuggestTimeCardAdapter extends RecyclerView.Adapter<SuggestTimeCardAdapter.ViewHolder> {
private Context context;
private List<SuggestTimeList> suggestTimeLists;
private Integer selected_position = -1;
public SuggestTimeCardAdapter(List<SuggestTimeList> suggestTimeLists, Context context){
super();
this.suggestTimeLists = suggestTimeLists;
this.context = context;
}
#Override
public SuggestTimeCardAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.suggest_time_card, parent, false);
SuggestTimeCardAdapter.ViewHolder viewHolder = new SuggestTimeCardAdapter.ViewHolder(v);
return viewHolder;
}
#Override
public void onBindViewHolder(final SuggestTimeCardAdapter.ViewHolder holder, final int position) {
final SuggestTimeList suggestTimeList = suggestTimeLists.get(position);
holder.tvSuggestTime.setText(suggestTimeList.getSuggestTime());
holder.cbSuggestTime.setChecked(position==selected_position);
holder.cbSuggestTime.setVisibility(View.VISIBLE);
holder.suggest_time_card_view.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v){
//implement the click
Boolean CheckTime = suggestTimeList.getCheckTime();
String reservationTime = holder.tvSuggestTime.getText().toString();
Integer ItemId = suggestTimeList.getTimeId();
holder.cbSuggestTime.setChecked(true);
selected_position = position;
for(SuggestTimeList s : suggestTimeLists) {
s.setChecked(false);
}
suggestTimeList.setChecked(true);
//notifyDataSetChanged();
}
});
}
#Override
public int getItemCount() {
return suggestTimeLists.size();
}
class ViewHolder extends RecyclerView.ViewHolder {
public TextView tvSuggestTime;
public CheckBox cbSuggestTime;
public CardView suggest_time_card_view;
public ViewHolder(View itemView) {
super(itemView);
tvSuggestTime = (TextView) itemView.findViewById(R.id.tvSuggestTime);
cbSuggestTime = (CheckBox) itemView.findViewById(R.id.cbSuggestTime);
suggest_time_card_view = (CardView) itemView.findViewById(R.id.suggest_time_card_view);
}
}
}

Make checkbox in CardView behave like RadioGroup?
You can modify your model by add a field (to store state of checkbox ) like
boolean isSelected;
public boolean isSelected() {
return isSelected;
}
public void setSelected(boolean selected) {
isSelected = selected;
}
And in your onBindViewHolder, you can use this field to set checkbox. like this:
// suggestTimeList is an item of list.
holder.cbSuggestTime.setCheck(suggestTimeList.isSelected());
holder.suggest_time_card_view.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v){
// your code ....
// UnSelected all
for (int i = 0; i < suggestTimeLists.size(); i++) {
suggestTimeLists.get(i).setSelected(false);
}
// Only select card you have clicked
suggestTimeLists.get(position).setSelected(true);
notifyDataSetChanged();
}
});

Related

not getting id of a clicked child item inside RecyclerView item layout

I have implemented a RecyclerView inside a ConstraintLayout. I am having one child image element inside the layout. But when I click the child image, it always returns the ConstraintLayout, not the clicked image.
Could you please tell me why this is happening, what is the solution for this ?
I separately did bind listener to image, it is working but not able to get the RecyclerItem object. I need RecyclerItem object for the position to proceed.
I implemented it by binding elements via onBindViewholder method in Adapter. Below are the codes
customAdapter = new GridViewAdapter(recyclerItems, 1, this.getContext().getPackageName(),
new GridViewAdapter.OnItemClickListener(){
#Override
public void onItemClick(RecyclerItem item) {
CommonUtil.addFragment("REP", Constants.CONTAINER_HOME,
new ModifyFragment(), getActivity(), null);
}
}, R.layout.rec_view_item_stock, Constants.V_SPAN_LIST_8);
RecyclerView recyclerView = view.findViewById(R.id.stockListRecView);
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setLayoutManager(new GridLayoutManager(this.getContext(), 1));
recyclerView.setAdapter(customAdapter);
//Adapter
public class GridViewAdapter extends RecyclerView.Adapter<GridViewAdapter.ViewHolder>{
private List<RecyclerItem> dataItems;
private int hSpan = 1;
private String packageName;
private final OnItemClickListener listener;
private int inflator;
private int vSpan;
public interface OnItemClickListener {
void onItemClick(RecyclerItem item);
}
public static class ViewHolder extends RecyclerView.ViewHolder {
private final ConstraintLayout constraintLayout;
private final TextView textView;
private final ImageView imageView;
private Object obj;
public ViewHolder(View view) {
super(view);
constraintLayout = (ConstraintLayout) view.findViewById(R.id.rec_content_layout);
textView = constraintLayout.findViewById(R.id.recTextView);
imageView = constraintLayout.findViewById(R.id.recImage);
}
public void bind(final RecyclerItem item, final OnItemClickListener listener) {
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
listener.onItemClick(item);
}
});
}
public TextView getTextView() {
return textView;
}
public ImageView getImageView() {
return imageView;
}
public Object getObj() {
return obj;
}
public void setObj(Object obj) {
this.obj = obj;
}
}
public GridViewAdapter(List<RecyclerItem> items, int spanCount, String packageName, OnItemClickListener listener,
int inflator, int vSpan) {
dataItems = items;
this.hSpan = spanCount;
this.packageName = packageName;
this.listener = listener;
this.inflator = inflator;
this.vSpan = vSpan;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int gridType) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(inflator, viewGroup, false);
ViewGroup.LayoutParams layoutParams = view.getLayoutParams();
layoutParams.width = (viewGroup.getResources().getDisplayMetrics().widthPixels / hSpan) - 24;
if(Constants.V_SPAN_GRID == vSpan) {
layoutParams.height = layoutParams.width;
} else {
layoutParams.height = (viewGroup.getResources().getDisplayMetrics().widthPixels / vSpan);
}
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(ViewHolder viewHolder, final int position) {
viewHolder.getTextView().setText(dataItems.get(position).getText());
int imgId = viewHolder.getImageView().getResources().getIdentifier(
dataItems.get(position).getImageName(), "drawable", packageName);
viewHolder.getImageView().setImageResource(imgId);
viewHolder.setObj(dataItems.get(position));
viewHolder.bind(dataItems.get(position), listener);
}
#Override
public int getItemCount() {
return dataItems.size();
}
//item 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/rec_content_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:layout_marginTop="8dp"
android:layout_marginLeft="4dp"
android:padding="8dp"
android:background="#drawable/border_top_bottom" >
<androidx.constraintlayout.widget.Guideline
android:id="#+id/viewstock_gline_1_v"
android:layout_width="1dp"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.6"/>
<ImageView
android:id="#+id/recImage"
android:background="#color/colorPrimaryDark"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="8dp" />
<TextView
android:id="#+id/recTextView"
app:layout_constraintLeft_toRightOf="#+id/recImage"
app:layout_constraintTop_toTopOf="parent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="8dp" />
<ImageView
android:id="#+id/editstock_image"
android:src="#drawable/ic_edit_stock"
android:background="#color/colorPrimaryDark"
app:layout_constraintRight_toLeftOf="#+id/deletestock_image"
app:layout_constraintTop_toTopOf="parent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="8dp" />
<ImageView
android:id="#+id/deletestock_image"
android:src="#drawable/ic_delete_stock"
android:background="#color/colorPrimaryDark"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="8dp" />
</androidx.constraintlayout.widget.ConstraintLayout>```
Try this!
public void bind(final RecyclerItem item, final OnItemClickListener listener, TextView itemTextView) {
itemTextView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
listener.onItemClick(item);
}
});
}
Pass every item text view instance from the view holder or fro onBindViewHolder itself implement onclick listener

Wrong behavior when click on item in recyclerView to change its color?

I'm trying to change the background color of the clicked item in RecyclerView from the adapter and it works, but the problem is when I click on position 1 it changes the color of position 1 and 7, and when I click on position 2 it changes the color of position 2 and 8 and so on ...
public class RecyclerViewAdapter extends
RecyclerView.Adapter<RecyclerViewAdapter.viewHolder> {
private ArrayList<String> name = new ArrayList<>();
private Context context;
boolean added = false;
public RecyclerViewAdapter(ArrayList<String> name, Context context) {
this.name = name;
this.context = context;
}
#Override
public viewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_horizontal_listview, parent, false);
return new viewHolder(view);
}
#Override
public void onBindViewHolder(final viewHolder holder, final int position) {
holder.cardView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(final View view) {
final Dialog dialog = new Dialog(view.getContext());
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
dialog.setCancelable(false);
dialog.setContentView(R.layout.add_item_dialog_small);
Window window = dialog.getWindow();
window.setLayout(500, 450);
Button addToList = (Button) dialog.findViewById(R.id.addToList);
addToList.setOnClickListener(new View.OnClickListener() {
#SuppressLint("ResourceAsColor")
#Override
public void onClick(View v) {
holder.cardView.setBackgroundColor(R.color.layer4);
dialog.dismiss();
}
});
dialog.show();
}
});
}
Edit:
here is the cardView :
<android.support.v7.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:id="#+id/cardView"
android:layout_width="300dp"
android:layout_height="320dp"
android:layout_margin="10dp"
android:background="#color/layer2"
card_view:cardCornerRadius="2dp">
<LinearLayout
android:id="#+id/linear"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="2dp"
android:background="#color/layer3"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="horizontal"
android:padding="5dp">
<TextView
android:id="#+id/textViewItemName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Test Item"
android:textColor="#color/add_button"
android:textSize="25sp" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="left"
android:orientation="horizontal"
android:padding="5dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/item_number"
android:textColor="#color/text_view_color"
android:textSize="20sp" />
<TextView
android:id="#+id/textViewItemNumber"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginLeft="10dp"
android:textColor="#color/second_color"
android:textSize="20sp" />
</LinearLayout>
</LinearLayout>
</android.support.v7.widget.CardView>
In case of implementing options (such as favorite icon, checkbox, highlight or ...) to each row of a recyclerview, i think the best way is to create an object with your arbitrary parameter. for example for favorite a boolean parameter is best choice.
In your case you should create an object with a string and a boolean parameter with their setters and getters like below:
public class mObject {
private String name;
private boolean clicked;
// setters and getters
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public boolean isClicked() {
return clicked;
}
public void setClicked(boolean clicked) {
this.clicked = clicked;
}
}
and then set your data in a list of this object then pass it to the adapter.
In onBindViewHolder, first check click value, if is true change the color. then in onClick method do both change the boolean value and background color and finally use notifyDataSetChanged(); for updating view.
Your adapter onBindViewHolder should looks like below:
#Override
public void onBindViewHolder(RecyclerView.ViewHolder view,final int position) {
final MVH holder = (MVH) view;
holder.tv.setText(name.get(position).getName());
if (name.get(position).isClicked()){
holder.tv.setBackgroundColor(context.getResources().getColor(R.color.colorPrimary));
} else {
holder.tv.setBackgroundColor(context.getResources().getColor(R.color.colorAccent));
}
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(final View view) {
final Dialog dialog = new Dialog(context);
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
dialog.setCancelable(false);
dialog.setContentView(R.layout.add_item_dialog_small);
Window window = dialog.getWindow();
window.setLayout(500, 450);
Button addToList = (Button) dialog.findViewById(R.id.addToList);
addToList.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (name.get(position).isClicked()){
name.get(position).setClicked(false);
holder.tv.setBackgroundColor(context.getResources().getColor(R.color.colorPrimary));
} else {
name.get(position).setClicked(true);
holder.tv.setBackgroundColor(context.getResources().getColor(R.color.colorAccent));
}
dialog.dismiss();
notifyDataSetChanged();
}
});
dialog.show();
}
});
}
You can simplyfy your code using lambdas, that's for sure.
This:
addToList.setOnClickListener(new View.OnClickListener() {
#SuppressLint("ResourceAsColor")
#Override
public void onClick(View v) {
holder.cardView.setBackgroundColor(R.color.layer4);
}
dialog.dismiss();
}
});
You can change to:
addToList.setOnClickListener((View v) -> {
holder.cardView.setBackgroundColor(R.color.layer4);
}
dialog.dismiss();
}
});
store var positionClicked in your adapter so it will be
onClick{positionClicked = position)
and then in your onBindViewHolder put
if(positionClicked==position){
//change color of element here//
}
I face this problem also. What you can do is set the background colour before click in onBindViewHolder method.
#Override
public void onBindViewHolder(final viewHolder holder, final int position) {
holder.cardView.setBackgroundColor(R.color.defaultBackgroundColour);

RecyclerView onClick not working properly?

I am using RecyclerView in my fragment to show images with text in Grid format,the Recycler view grid_item.xml look like following:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.CardView
android:id="#id/card_view"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_gravity="center"
android:layout_margin="#dimen/card_margin_grid"
card_view:cardCornerRadius="#dimen/card_album_radius">
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<ImageView
android:id="#id/thumbnail"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:background="?selectableItemBackgroundBorderless"
android:clickable="true"
android:scaleType="fitCenter" />
<TextView
android:id="#id/title"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="#id/thumbnail"
android:layout_margin="#dimen/album_title_padding"
android:textColor="#color/album_title"
android:textSize="#dimen/album_title" />
</RelativeLayout>
</android.support.v7.widget.CardView>
</RelativeLayout>
I am using adapter to populate data in RecyclerView, the code for this is :
public class DataAdapter extends RecyclerView.Adapter<DataAdapter.ViewHolder> {
private ArrayList<Movie> movies;
private Context context;
public DataAdapter(Context context, ArrayList<Movie> movies) {
this.movies = movies;
this.context = context;
}
public void addItems(ArrayList<Movie> movies) {
this.movies.addAll(movies);
}
#Override
public DataAdapter.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.recycler_view_grid_item, viewGroup, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(DataAdapter.ViewHolder viewHolder, int i) {
viewHolder.title.setText(movies.get(i).getTitle());
Picasso.with(context).load(movies.get(i).getImage_url_medium()).placeholder(R.drawable.placeholder).into(viewHolder.thumbnail);
}
#Override
public int getItemCount() {
return movies.size();
}
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
private TextView title;
private ImageView thumbnail;
public ViewHolder(View view) {
super(view);
title = (TextView) view.findViewById(R.id.title);
thumbnail = (ImageView) view.findViewById(R.id.thumbnail);
view.setOnClickListener(this);
}
// Handles the row being being clicked
#Override
public void onClick(View view) {
int position = getAdapterPosition(); // gets item position
if (position != RecyclerView.NO_POSITION) { // Check if an item was deleted, but the user clicked it before the UI removed it
Movie movie = movies.get(position);
// start detail activity
Intent i = new Intent(context, MovieDetail.class);
i.putExtra(Constants.MOVIES_OBJECT, movie);
context.startActivity(i);
}
}
}
}
My problem is click listener is only working on the TextView and not on the image , although I have set click listener on whole view which contains both image and text.Is something wrong with my implementation ?
try setting android:focusableInTouchMode="false" to your imageview.
and remove android:clickable="true" or set it to false
Use viewHolder.itemView like :
viewHolder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//your action
});
This will enable click action on whole RecyclerView item.
Add android:clickable="true" to the root RelativeLayout.
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:id="#id/card_view"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_gravity="center"
android:layout_margin="#dimen/card_margin_grid"
android:clickable="true"
android:focusableInTouchMode="true"
card_view:cardCornerRadius="#dimen/card_album_radius">
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<ImageView
android:id="#id/thumbnail"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:background="?selectableItemBackgroundBorderless"
android:clickable="false"
android:focusableInTouchMode="false"
android:scaleType="fitCenter" />
<TextView
android:id="#id/title"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="#id/thumbnail"
android:layout_margin="#dimen/album_title_padding"
android:textColor="#color/album_title"
android:textSize="#dimen/album_title" />
</RelativeLayout>
</android.support.v7.widget.CardView>
public class OffersRecycleViewAdapter extends RecyclerView.Adapter {
private Activity mActivity;
private List<OfferShopModel> offerShopModels = new ArrayList<>();
ArrayList<String> allColors = new ArrayList<String>();
public OffersRecycleViewAdapter(List<OfferShopModel> offerShopModels, Activity activity, ArrayList<String> allColors) {
this.offerShopModels = offerShopModels;
this.mActivity = activity;
}
// String[] allColors = mActivity.getResources().getStringArray(R.array.colors);
#Override
public ItemViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.cardview_offers, viewGroup, false);
return new ItemViewHolder(v);
}
#TargetApi(Build.VERSION_CODES.M)
#Override
public void onBindViewHolder(ItemViewHolder itemViewHolder, final int position) {
itemViewHolder.mOffer.setText(offerShopModels.get(position).getOffer());
}
#Override
public int getItemCount() {
return offerShopModels.size();
}
class ItemViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
ImageView mLinearLayoutBack;
TextView mOffer;
ItemViewHolder(View itemView) {
super(itemView);
mOffer = (TextView) itemView.findViewById(R.id.offer);
mOffer.setOnClickListener(this);
}
#Override
public void onClick(View v) {
// call click event
}
}
}
remove android:clickable="true" from your ImageView or change it to android:clickable="false"

Android Recycler view with onClickListener not working

I'm trying to set an onClickListener on one of my image on my recyclerview but the click doesn't work.
It looks like it doesn't seems to see there is a onClickListener, because when I set a "point" for the debugger on my listener it doesn't go to the point.
What I have done wrong ?
public class Item_List_Adapter extends RecyclerView.Adapter<Item_List_Adapter.MyViewHolder> {
// declare array
private String[] mDataset;
private Context mContext;
public static class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
public TextView itemName;
public ImageView mAddBtn;
public MyViewHolder(View v){
super(v);
itemName = (TextView) v.findViewById(R.id.item_name);
mAddBtn = (ImageView) v.findViewById(R.id.action_add);
}
#Override
public void onClick(View v) {
System.out.println("TEST: ");
switch (v.getId()) {
case R.id.action_add:
System.out.println("TEST2: ");
break;
default:
break;
}
}
}
// constructor
public Item_List_Adapter(Context context, String[] myDataset) {
mDataset = myDataset;
mContext = context;
}
#Override
public int getItemCount() {
return mDataset.length;
}
#Override
public Item_List_Adapter.MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
// create a new view
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_list, parent, false);
MyViewHolder nv = new MyViewHolder(v);
return nv;
}
#Override
public void onBindViewHolder(Item_List_Adapter.MyViewHolder holder, final int position) {
holder.itemName.setText(mDataset[position]);
holder.mAddBtn.setOnClickListener(holder);
}
}
and my XML file the one inflate in the recycler view
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="10dp"
android:paddingBottom="10dp">
<LinearLayout
android:id="#+id/list_item"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginEnd="15dp"
android:layout_marginStart="15dp">
<ImageView
android:id="#+id/action_check"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_action_check"
android:alpha="0.3"
/>
<TextView
android:id="#+id/item_name"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight=".2"
android:hint="Wine"
android:alpha="0.3"
android:gravity="start|center"
android:paddingStart="5dp"
android:paddingLeft="5dp"/>
<ImageView
android:id="#+id/action_remove"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_action_remove_green"
android:onClick="item_remove"
/>
<ImageView
android:id="#+id/action_add"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_action_add_blue"
/>
<ImageView
android:id="#+id/action_chart"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_action_chart"
android:scaleType="centerInside"
android:onClick="chart_detail"
/>
</LinearLayout>
</LinearLayout>
Thanks in advance
you should use Log to output to the console
Log.d("TAG","TEST: );
for experimentation sake try this out in your ViewHolder constructor
mAddBtn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Log.d("TAG","TEST: );
}
});
If it doesn't work then something is blocking the click, this could be simply setting clickable="true" in the xml, or figuring out what is on front of the view
The following is how I used in my Adapter. Hope this help:
public class EventArrayAdapter extends RecyclerView.Adapter<ViewHolder> {
private OnItemClickListener onItemClickListener;
public OnItemClickListener getOnItemClickListener() {
return onItemClickListener;
}
public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
this.onItemClickListener = onItemClickListener;
}
public interface OnItemClickListener {
public void onItemClick(View view, int position);
}
#Override
public void onBindViewHolder(final ViewHolder holder, final int position) {
//Add your viewHolder.button.setOnClickListener here as normal
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int arg1) {
// TODO Auto-generated method stub
View v = LayoutInflater.from(context).inflate(
R.layout.layout_item_event, parent, false);
final EventViewHolder holder = new EventViewHolder(v);
v.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
onItemClickListener.onItemClick(v, holder.getAdapterPosition());
}
});
return holder;
}
}
update your constructor like this and try. It will work.
public MyViewHolder(View v){
super(v);
itemName = (TextView) v.findViewById(R.id.item_name);
mAddBtn = (ImageView) v.findViewById(R.id.action_add);
mAddBtn.setOnClickListener(this);
}
Basically assign onClick listener to your Imageview

I have a recyclerview where there is an image for a popup menu. I want to know how to determine on which recyclerview item the popup menu has clicked

Here is my recyclerview item_courses.xml:
<android.support.v7.widget.CardView
android:id="#+id/card_view"
android:layout_width="fill_parent"
android:layout_height="150dp"
android:layout_margin="5dp"
card_view:cardCornerRadius="2dp"
card_view:contentPadding="20dp">
<TableLayout
android:layout_width="match_parent"
android:layout_height="121dp"
android:stretchColumns="*">
<TableRow
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView
android:id="#+id/textView"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="left"
android:layout_column="0"
android:textColor="#color/testcolor"
android:textSize="18sp"
android:textStyle="bold"
android:layout_span="30"
android:text="Course Name"
android:paddingBottom="40dp"
android:paddingRight="20dp"
/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:src="#drawable/btn_course_menu"
android:layout_span="3"
android:id="#+id/person_photo"
android:onClick="CreatePopupMenu"
android:layout_column="28" />
</TableRow>
<TableRow
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView
android:id="#+id/textView2"
android:text="10 students"
android:layout_gravity="left"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#color/testcolor"
android:layout_column="0"
android:layout_span="13"
android:paddingTop="0dp"
android:paddingBottom="0dp"
/>
<TextView
android:id="#+id/textView3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="right"
android:textColor="#color/testcolor"
android:layout_span="13"
android:layout_column="20" />
</TableRow>
</TableLayout>
</android.support.v7.widget.CardView>
Here is my recyclerview adapter
public class MyRecyclerViewAdapter extends RecyclerView
.Adapter<MyRecyclerViewAdapter
.DataObjectHolder> {
private static String LOG_TAG = "MyRecyclerViewAdapter";
private ArrayList<Person> mDataset;
private static MyClickListener myClickListener;
public static class DataObjectHolder extends RecyclerView.ViewHolder
implements View
.OnClickListener {
TextView subject;
TextView studentno;
TextView classno;
public DataObjectHolder(View itemView) {
super(itemView);
subject = (TextView) itemView.findViewById(R.id.textView);
studentno = (TextView) itemView.findViewById(R.id.textView2);
classno = (TextView) itemView.findViewById(R.id.textView3);
Log.i(LOG_TAG, "Adding Listener");
itemView.setOnClickListener(this);
}
#Override
public void onClick(final View v) {
myClickListener.onItemClick(getPosition(), v);
}
}
public void setOnItemClickListener(MyClickListener myClickListener) {
this.myClickListener = myClickListener;
}
public MyRecyclerViewAdapter(ArrayList<Person> myDataset) {
mDataset = myDataset;
}
#Override
public DataObjectHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.item_courses, parent, false);
DataObjectHolder dataObjectHolder = new DataObjectHolder(view);
return dataObjectHolder;
}
#Override
public void onBindViewHolder(DataObjectHolder holder, int position) {
holder.subject.setText(mDataset.get(position).getmText1());
holder.studentno.setText(mDataset.get(position).getmText2());
holder.classno.setText(mDataset.get(position).getmText3());
}
public void addItem(Person dataObj, int index) {
mDataset.add(index, dataObj);
notifyItemInserted(index);
}
public void deleteItem(int index) {
mDataset.remove(index);
notifyItemRemoved(index);
}
#Override
public int getItemCount() {
return mDataset.size();
}
public interface MyClickListener {
public void onItemClick(int position, View v);
}
}
Suppose their is only one item named in popum menu (named : popup_menu.xml).
menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="#+id/option1"
android:title="Option 1" />
So when it was clicked on option1. how to determine on which recyclerview item it was clicked ?
Popup menu anchored to an ImageView (star) in a RecyclerView item:
Position of RecyclerView item displayed when a popup menu item is selected:
To achieve this we need to modify your DataObjectHolder to do two things:
Anchor a popup menu to the image view when it is clicked.
Handle popup menu item click.
We use a custom listener, PopupMenuListener to pass the RecyclerView item, its position in the adapter to be specific, hosting the popup menu that was just clicked.
Modified DataObjectHolder:
public static class DataObjectHolder extends RecyclerView.ViewHolder implements View
.OnClickListener, PopupMenu.OnMenuItemClickListener {
private final MyClickListener myClickListener;
private final PopupMenuListener popupMenuListener;
TextView subject;
TextView studentno;
TextView classno;
View imageView;
public interface MyClickListener {
void onItemClick(int position, View v);
}
public interface PopupMenuListener {
void onPopupMenuClicked(MenuItem menuItem, int adapterPosition);
}
public DataObjectHolder(View itemView, MyClickListener myClickListener, PopupMenuListener popupMenuListener) {
super(itemView);
this.myClickListener = myClickListener;
this.popupMenuListener = popupMenuListener;
subject = (TextView) itemView.findViewById(R.id.textView);
studentno = (TextView) itemView.findViewById(R.id.textView2);
classno = (TextView) itemView.findViewById(R.id.textView3);
imageView = itemView.findViewById(R.id.person_photo);
// Configure image view to show a popup menu when it is clicked:
imageView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
showPopupMenu(view);
}
});
Log.i(LOG_TAG, "Adding Listener");
itemView.setOnClickListener(this);
}
#Override
public void onClick(final View v) {
myClickListener.onItemClick(getAdapterPosition(), v);// IMPORTANT: 'getPosition()' is deprecated.
}
private void showPopupMenu(View view) {
PopupMenu popup = new PopupMenu(view.getContext(), view);
MenuInflater inflater = popup.getMenuInflater();
inflater.inflate(R.menu.popup_menu, popup.getMenu());
popup.setOnMenuItemClickListener(this);
popup.show();
}
/*
* Popup menu callback.
*/
#Override
public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()) {
case R.id.option1:
// Call popup menu listener passing the menu item that was clicked as well as the recycler view item position:
popupMenuListener.onPopupMenuClicked(item, getAdapterPosition());
return true;
default:
return false;
}
}
}
Just implement PopupMenuListener and pass it to DataObjectHolder's constructor and we're good to go!
public class MyAdapter extends RecyclerView.Adapter<MyAdapter. XInfoHolder > {
public MyAdapter(Context ctx,ArrayList<Data> dataInfo) {
..........
........
}
#Override
public PersonInfoHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
//* creating view from the layout for child element in the listview by using inflater*//*
View itemView = ........
return new ViewHolder(itemView);
}
#Override
public void onBindViewHolder(PersonInfoHolder personInfoHolder, int i) { ...
....
}
#Override
public int getItemCount() {
return data.size();
}
public class XInfoHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
protected ImageView popupMenu;
public XInfoHolder(View itemView) {
super(itemView);
popupMenu = (ImageView) itemView.findViewById(R.id.pop_up);
popupMenu.setOnClickListener(this);
}
#Override
public void onClick(View v) {
if (getLayoutPosition() == 0/something else && v.getId() == R.id.pop_up) {
//show your popup all other place view is invisible
//do whatever else here
}
}
}
}
}
This is how i solved this problem for my project. Thanks and best of luck.

Categories

Resources