onClickListener in RecyclerView.ViewHolder - java

I've got a RecyclerView.ViewHolder and RecyclerView.Adapter, I need after click on item and then send information about this item to another Activity.
PlacesAdapter.java
public class PlacesAdapter extends RecyclerView.Adapter<PlacesViewHolder> {
private PlacesActivity placesActivity;
Context context;
private int position;
List<Places> places;
public PlacesAdapter(List<Places> places) {
this.places = places;}
#Override
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
super.onAttachedToRecyclerView(recyclerView);
}
#Override
public PlacesViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.places_view, viewGroup, false);
PlacesViewHolder pvh = new PlacesViewHolder(v);
return pvh;
}
#Override
public void onBindViewHolder(PlacesViewHolder personViewHolder, int i) {
personViewHolder.name.setText(places.get(i).name);
personViewHolder.address.setText(places.get(i).address);
Picasso.with(personViewHolder.itemView.getContext())
.load(places.get(i).photo)
.into(personViewHolder.getPhoto());
}
#Override
public int getItemCount() {
return places.size();
}
}
PlacesViewHolder.java
In this line "intent.putExtra(PlacesDetail.PLACES_NAME,);" How can I send name?
public class PlacesViewHolder extends RecyclerView.ViewHolder {
CardView cv;
public TextView name;
public TextView address;
public ImageView photo;
public PlacesViewHolder(final View itemView) {
super(itemView);
cv = (CardView)itemView.findViewById(R.id.cv);
name = (TextView)itemView.findViewById(R.id.person_name);
address = (TextView)itemView.findViewById(R.id.person_age);
photo = (ImageView)itemView.findViewById(R.id.person_photo);
itemView.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v) {
Context context = v.getContext();
Intent intent = new Intent(context, PlacesDetail.class);
intent.putExtra(PlacesDetail.PLACES_NAME,);
context.startActivity(intent);
}
});
}
public TextView getAddress() {
return address;
}
public TextView getName() {
return name;
}
public ImageView getPhoto() {
return photo;
}
}

This is the complete example of custom Adapter where i'm able to get the details of particular items. In MainActivity you need to set the adapter :
adapter = new MyAdapter(getApplicationContext(), account_no, title, aFN1, aLN1,aFN2, aLN2,aFN3, aLN3,isavilable,waitlist,flag);
adapter.notifyDataSetChanged();
mRecyclerView.setAdapter(adapter);
Now see the code for the custom Adapter :
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
String TAG = "MyAdapter";
Context context;
private String[] accountNo;
private String[] title;
private String[] afn1;
private String[] aln1;
private String[] afn2;
private String[] aln2;
private String[] afn3;
private String[] aln3;
private String[] isAvailable;
private String[] waitlist;
private int flag;
public static class ViewHolder extends RecyclerView.ViewHolder {
public TextView account_no,title,afn1,afn2,aln1,aln2,color,is_available;
private ImageView img_android;
CardView cardView;
public ViewHolder(CardView v) {
super(v);
account_no = (TextView)v.findViewById(R.id.acctno);
title = (TextView)v.findViewById(R.id.title);
afn1 = (TextView) v.findViewById(R.id.afn1);
cardView = v;
}
}
// Provide a suitable constructor (depends on the kind of dataset)
public MyAdapter(Context context, String[] accountNo,String[] title,String[] afn1,String[] aln1,String[] afn2,String[] aln2,String[] afn3,String[] aln3,String[] isAvailable, String[] waitlist,int flag) {
this.context = context;
this.accountNo = accountNo;
this.title = title;
this.afn1 = afn1;
this.aln1 = aln1;
this.afn2 = afn2;
this.aln2 = aln2;
this.afn3 = afn3;
this.aln3 = aln3;
this.isAvailable = isAvailable;
this.waitlist = waitlist;
this.flag = flag;
Log.d(TAG,afn1.toString() +aln1+afn2+aln2+afn3+aln3.toString()+waitlist);
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent,int viewType) {
CardView cv = (CardView) LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item, parent, false);
return new ViewHolder(cv);
}
#Override
public void onBindViewHolder(final ViewHolder holder, final int position) {
final CardView cardView = holder.cardView;
final TextView accountno = (TextView)cardView.findViewById(R.id.acctno);
accountno.setText(accountNo[position]);
final TextView titletxt = (TextView)cardView.findViewById(R.id.title);
titletxt.setText(title[position]);
final TextView afn1txt = (TextView) cardView.findViewById(R.id.afn1);
afn1txt.setText(afn1[position]+" "+aln1[position]);
Log.d(TAG,waitlist[position]);
cardView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int id = getItemViewType(position);
SharedPreferences sharedPreferences = context.getSharedPreferences(Constant.MYPREFERENCE,Context.MODE_PRIVATE);
SharedPreferences.Editor edit = sharedPreferences.edit();
edit.putString(Constant.ACCOUNT,accountNo[position]);
edit.putString(Constant.TITLE,title[position]);
edit.putString(Constant.AFN1,afn1[position]);
edit.putString(Constant.ALN1,aln1[position]);
edit.putString(Constant.AFN2,afn2[position]);
edit.putString(Constant.ALN2,aln2[position]);
edit.putString(Constant.AFN3,afn3[position]);
edit.putString(Constant.ALN3,aln3[position]);
edit.putBoolean(Constant.IS_AVAILABLE, Boolean.parseBoolean(isAvailable[position].toUpperCase()));
edit.putString(Constant.WAITLIST,waitlist[position]);
Log.d("WaitingNo2 :",""+String.valueOf(waitlist[position]));
edit.commit();
Intent intent = new Intent(v.getContext(), DetailsActivity.class);
v.getContext().startActivity(intent);
}
});
}
// Return the size of your dataset (invoked by the layout manager)
#Override
public int getItemCount() {
return accountNo.length;
}
}
After All that get the value from sharedPreferences in the Activity which is called on Card Click:
preferences = getSharedPreferences("myshared", Context.MODE_PRIVATE);
AccountNo = sharedPreferences.getString(Constant.ACCOUNT,null).toUpperCase();
title = sharedPreferences.getString(Constant.TITLE,null).toUpperCase();
afn1 = sharedPreferences.getString(Constant.AFN1,null).toUpperCase();
aln1 = sharedPreferences.getString(Constant.ALN1,null).toUpperCase();
afn2 = sharedPreferences.getString(Constant.AFN2,null).toUpperCase();
aln2 = sharedPreferences.getString(Constant.ALN2,null).toUpperCase();
afn3 = sharedPreferences.getString(Constant.AFN3,null).toUpperCase();
aln3 = sharedPreferences.getString(Constant.ALN3,null).toUpperCase();
isAvailable = sharedPreferences.getBoolean(Constant.IS_AVAILABLE,isAvailable);
waitlist = sharedPreferences.getString(Constant.WAITLIST,waitlist);
Now do whatever you want and enjoy the code.

You can achieve this by creating an interface inside your adapter for an itemclicklistener and then you can set onItemClickListener from your PlacesActivity.
Somewhere inside your PlacesAdapter you would need the following:
private onRecyclerViewItemClickListener mItemClickListener;
public void setOnItemClickListener(onRecyclerViewItemClickListener mItemClickListener) {
this.mItemClickListener = mItemClickListener;
}
public interface onRecyclerViewItemClickListener {
void onItemClickListener(View view, int position, String places_name);
}
Then inside your ViewHolder (which I've added as an inner class inside my adapter), you would apply the listener to the components you'd like the user to click, like so:
class PlacesViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
PlacesViewHolder(View view) {
super(view);
view.setOnClickListener(this);
}
#Override
public void onClick(View v) {
if (mItemClickListener != null) {
mItemClickListener.onItemClickListener(v, getAdapterPosition(), PlacesDetail.PLACES_NAME);
}
}
}
This example shows an onClickListener being applied to the view inside PlacesViewHolder.
recyclerView.setAdapter(adapter);// set adapter on recyclerview
adapter.notifyDataSetChanged();// Notify the adapter
adapter.setOnItemClickListener(new PlacesAdapter.onRecyclerViewItemClickListener() {
#Override
public void onItemClickListener(View view, int position, String places_name) {
//perform click logic here (places_name is passed)
}
});
To implement this code, you would setOnItemClickListener to your adapter inside PlacesActivity as shown above.

try this , it's work with me correctly
Create a new class and this code
public class RecyclerItemClickListener implements RecyclerView.OnItemTouchListener {
private OnItemClickListener mListener;
public interface OnItemClickListener {
public void onItemClick(View view, int position);
public void onLongItemClick(View view, int position);
}
GestureDetector mGestureDetector;
public RecyclerItemClickListener(Context context, final RecyclerView recyclerView, OnItemClickListener listener) {
mListener = listener;
mGestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
#Override
public boolean onSingleTapUp(MotionEvent e) {
return true;
}
#Override
public void onLongPress(MotionEvent e) {
View child = recyclerView.findChildViewUnder(e.getX(), e.getY());
if (child != null && mListener != null) {
mListener.onLongItemClick(child, recyclerView.getChildAdapterPosition(child));
}
}
});
}
#Override public boolean onInterceptTouchEvent(RecyclerView view, MotionEvent e) {
View childView = view.findChildViewUnder(e.getX(), e.getY());
if (childView != null && mListener != null && mGestureDetector.onTouchEvent(e)) {
mListener.onItemClick(childView, view.getChildAdapterPosition(childView));
return true;
}
return false;
}
#Override public void onTouchEvent(RecyclerView view, MotionEvent motionEvent) { }
#Override
public void onRequestDisallowInterceptTouchEvent (boolean disallowIntercept){}
}
And in your Activity add this to your adapter implementation
mRecyclerView.addOnItemTouchListener(
new RecyclerItemClickListener(getActivity(), mRecyclerView, new RecyclerItemClickListener.OnItemClickListener() {
#Override
public void onItemClick(View view, int position) {
// do something
}
}
}
#Override
public void onLongItemClick(View view, int position) {
// do whatever
}
})
);

Related

Recycleview cardview Onclick duplicate effects when scrolling

I'm making my first app (calendar),
clicking the cardview item applies the same effect (changing Textview text color and Imageview background) to other items when scrolling the recycleview
in the main activity
RecyclerView daysRecyclerView;
DaysAdapter daysAdapter;
private RecyclerView.LayoutManager horizontalLayout;
ArrayList<DaysModel> daysModels;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_calendar);
daysModels = getDaysList();
initDaysRecycleview();
}
private void initDaysRecycleview(){
daysRecyclerView = findViewById(R.id.daysRecyclerView);
daysRecyclerView.setHasFixedSize(true);
horizontalLayout = new LinearLayoutManager(this,RecyclerView.HORIZONTAL,false);
daysAdapter = new DaysAdapter(daysModels);
daysRecyclerView.setLayoutManager(horizontalLayout);
daysRecyclerView.setAdapter(daysAdapter);
daysAdapter.setOnItemClickListener(new DaysAdapter.OnItemClickListener() {
#Override
public void onItemClick(int position) {
dayClickHandler(position, 1);
}
});
}
public void dayClickHandler(int position, int change){
daysModels.get(position).changeDayHighlight(change);
daysAdapter.notifyItemChanged(position);
}
private ArrayList<DaysModel> getDaysList(){
//Not accurate used for testing
ArrayList<DaysModel> models = new ArrayList<DaysModel>();
String[] dayName ={"SAT","SUN","MON","TUE","WED","THU","FRI","SAT","SUN","MON","TUE","WED","THU","FRI","SAT","SUN","MON","TUE","WED","THU","FRI","SAT","SUN","MON","TUE","WED","THU","FRI","SAT","SUN","MON"};
int i,j;
for (i = 0;i <dayName.length;i++){
j =i+1;
models.add(new DaysModel(dayName[i], j, 0, false));
}
return models;
}
I'm using an interface for the onClickListener.
ViewHolder
public class DaysViewHolder extends RecyclerView.ViewHolder {
TextView hDayName,hDayNumber;
ImageView currentDayHighlight;
CardView dayCard;
public DaysViewHolder(View itemView, DaysAdapter.OnItemClickListener listener) {
super(itemView);
this.hDayName = itemView.findViewById(R.id.dayName);
this.hDayNumber = itemView.findViewById(R.id.dayNumber);
this.currentDayHighlight = itemView.findViewById(R.id.dayHihlight);
this.dayCard = itemView.findViewById(R.id.dayCard);
dayCard.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (listener != null) {
int position = getAdapterPosition();
if(position != RecyclerView.NO_POSITION){
listener.onItemClick(position);
}
}
}
});
}
}
Adapter
public class DaysAdapter extends RecyclerView.Adapter<DaysViewHolder> {
Context context;
ArrayList<DaysModel> daysModels;
OnItemClickListener mListener;
public interface OnItemClickListener{
void onItemClick(int position);
}
public void setOnItemClickListener(OnItemClickListener listener){
mListener = listener;
}
public DaysAdapter(ArrayList<DaysModel> daysModels) {
this.daysModels = daysModels;
}
#NonNull
#Override
public DaysViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.day_card,parent,false);
DaysViewHolder daysViewHolder = new DaysViewHolder(view, mListener);
return daysViewHolder;
}
#Override
public void onBindViewHolder(#NonNull DaysViewHolder holder, int position) {
DaysModel currentItem = daysModels.get(position);
holder.hDayName.setText(currentItem.getDayName());
holder.hDayNumber.setText(String.valueOf(currentItem.getDayNumber()));
if(currentItem.isDayHighlighted() == 1){
holder.currentDayHighlight.setBackgroundResource(R.drawable.tiny_background);
holder.hDayNumber.setTextColor(Color.BLACK);
}
}
#Override
public int getItemCount() {
return daysModels.size();
}
}
sorry for the long code text, I've just started and I am already struggling.
All you need is to set else part for you if condition in bind method of Adapter class.
So change your bind method to something like this:
#Override
public void onBindViewHolder(#NonNull DaysViewHolder holder, int position) {
DaysModel currentItem = daysModels.get(position);
holder.hDayName.setText(currentItem.getDayName());
holder.hDayNumber.setText(String.valueOf(currentItem.getDayNumber()));
if(currentItem.isDayHighlighted() == 1){
holder.currentDayHighlight.setBackgroundResource(R.drawable.tiny_background);
holder.hDayNumber.setTextColor(Color.BLACK);
}else{
holder.currentDayHighlight.setBackgroundResource(/*what ever you want for default situation*/);
holder.hDayNumber.setTextColor(/* for example Color.White*/);
}
}

How can I hide an ImageView on my RecyclerView for certain items based on a particular condition?

I have a RecyclerView with an ImageView being a part of the items. I want to hide the ImageView from an item in the RecyclerView if a certain condition is met. How can I do that? I am attaching the image of how I want it to look like.
I am just defining the ImageViews in my xml layout file, so I cannot figure out how to actually remove it based on a certain condition in my android activity. I am attaching the code for the adapter class and my activity as well.
Here is the code for my adapter class
Adapter Class
public class ReportAdapter extends RecyclerView.Adapter<ReportAdapter.ReportViewHolder> {
private ArrayList<ReportItem> reportlist;
private OnItemClickListener mListener;
private Context mContext;
public ReportAdapter(ArrayList<ReportItem> reportlist, Context context) {
this.reportlist = reportlist;
this.mContext = context;
}
public interface OnItemClickListener {
void onItemClick(int position);
}
public void setOnItemClickListener(OnItemClickListener listener) {
mListener = listener;
}
public static class ReportViewHolder extends RecyclerView.ViewHolder {
public TextView departureDate;
public TextView flightNumber;
public View relativelayout;
public ReportViewHolder(#NonNull View itemView, OnItemClickListener listener, Context context) {
super(itemView);
departureDate = itemView.findViewById(R.id.departureDaterecyclerview);
flightNumber = itemView.findViewById(R.id.flightnumberrecyclerview);
relativelayout = itemView.findViewById(R.id.relativeLayoutReports);
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(listener != null) {
int position = getAdapterPosition();
if(position != RecyclerView.NO_POSITION) {
listener.onItemClick(position);
}
}
}
});
}
}
#NonNull
#Override
public ReportViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.report_listing_item, parent, false);
ReportViewHolder rvh= new ReportViewHolder(v,mListener,mContext);
return rvh;
}
#SuppressLint("ResourceAsColor")
#Override
public void onBindViewHolder(#NonNull ReportViewHolder holder, int position) {
ReportItem currentItem = reportlist.get(position);
if(position%2==0){
holder.relativelayout.setBackgroundColor(mContext.getResources().getColor(R.color.reportlistingteal));
} else {
holder.relativelayout.setBackgroundColor(mContext.getResources().getColor(R.color.reportlistinglightteal));
}
holder.departureDate.setText((currentItem.getDepartureDate()));
holder.flightNumber.setText(currentItem.getFlightNumber());
}
Here is the code for my activity file
Activity file
public class ReportListingActivity extends AppCompatActivity {
private Button uploadAllBtn;
private EditText searchFlights;
private RecyclerView mRecyclerView;
private ReportAdapter mAdapter;
private RecyclerView.LayoutManager mLayoutManager;
ArrayList<ReportItem> reportitems = new ArrayList<>();
private FlightViewModel flightViewModel;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_report_listing);
uploadAllBtn = findViewById(R.id.uploadAllReports);
searchFlights = findViewById(R.id.searchFlightText);
mRecyclerView = findViewById(R.id.recyclerView);
flightViewModel = new ViewModelProvider(this).get(FlightViewModel.class);
flightViewModel.getAllFlights().observe(this, new Observer<List<Flight>>() {
#Override
public void onChanged(List<Flight> flight_list) {
if (flight_list.size() == 0) return;
String flightno = flight_list.get(0).getFlightNumber();
String flightdate = flight_list.get(0).getDate();
String[] flight_details = new String[2];
flight_details[0]= flightno;
flight_details[1] = flightdate;
Log.v("pp", flight_details[0]);
for(int i = 0; i <flight_list.size();i++){
String flightnumber = flight_list.get(i).getFlightNumber();
String departuredate = flight_list.get(i).getDate();
reportitems.add(new ReportItem(flightnumber,departuredate));
}
mRecyclerView.getAdapter().notifyDataSetChanged();
flightViewModel.getAllFlights().removeObservers(ReportListingActivity.this);
}
});
mLayoutManager = new LinearLayoutManager(ReportListingActivity.this);
mAdapter = new ReportAdapter(reportitems, ReportListingActivity.this);
mRecyclerView.setLayoutManager(mLayoutManager);
mRecyclerView.setAdapter(mAdapter);
}
Report Item
public class ReportItem {
private String departureDate;
private String flightNumber;
public ReportItem(String departureDate, String flightNumber) {
this.departureDate = departureDate;
this.flightNumber = flightNumber;
}
public String getDepartureDate() {
return departureDate;
}
public String getFlightNumber() {
return flightNumber;
}
}
Add a boolean flag to your ReportItem class for each RecyclerView item. You will need to specify which rows show or hide this field when each item is created:
public class ReportItem {
private String departureDate;
private String flightNumber;
private Boolean showMailIcon;
public ReportItem(String departureDate, String flightNumber, Boolean showMailIcon) {
this.departureDate = departureDate;
this.flightNumber = flightNumber;
this.showMailIcon = showMailIcon
}
public String getDepartureDate() {
return departureDate;
}
public String getFlightNumber() {
return flightNumber;
}
public String getShowMailIcon() {
return showMailIcon;
}
}
Then update the onBindViewHolder() method override to use this flag to show/hide the ImageView:
#Override
public void onBindViewHolder(#NonNull ReportViewHolder holder, int position) {
ReportItem currentItem = reportlist.get(position);
if (currentItem.getShowMailIcon() == true) {
holder.mailIcon.setVisibility(View.VISIBLE);
} else {
holder.mailIcon.setVisibility(View.GONE);
}
//.......
}

RecyclerView: different ViewType by different button

I have a recycler view to show an activity timeline and three floating buttons that click to add activity. How can I code three buttons to a different view? How can I pass the condition to the Adapter?
Now I can show only one viewType.
thx a lot.
Adapter.java
public class TripAdapter extends RecyclerView.Adapter<TripAdapter.TripHolder> {
private List<Trip> trips = new ArrayList<>();
private OnItemClickListener listener;
#NonNull
#Override
public TripHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.trip_item, parent, false);
return new TripHolder(itemView);
}
#Override
public void onBindViewHolder(#NonNull TripHolder holder, int position) {
Trip currentTrip = trips.get(position);
holder.textViewLodgingTitle.setText(currentTrip.getLodgingTitle());
holder.textTextViewLodgingCheckInDateTime.setText(currentTrip.getLodgingCheckInDateTime());
holder.textTextViewLodgingCheckOutDateTime.setText(currentTrip.getLodgingCheckOutDateTime());
holder.textViewLodgingAddress.setText(currentTrip.getLodgingAddress());
}
#Override
public int getItemCount() {
return trips.size();
}
public void setTrips(List<Trip> trips) {
this.trips = trips;
notifyDataSetChanged();
}
public Trip getTripAt(int position) {
return trips.get(position);
}
class TripHolder extends RecyclerView.ViewHolder {
//lodging
private TextView textViewLodgingTitle;
private TextView textTextViewLodgingCheckInDateTime;
private TextView textTextViewLodgingCheckOutDateTime;
private TextView textViewLodgingAddress;
private TextView textViewLodgingPhone;
private TextView textViewLodgingWebsite;
private TextView textViewLodgingEmail;
public TripHolder(#NonNull View itemView) {
super(itemView);
context = itemView.getContext();
textViewLodgingTitle = itemView.findViewById(R.id.text_view_title);
textTextViewLodgingCheckInDateTime = itemView.findViewById(R.id.text_view_start_date_time);
textTextViewLodgingCheckOutDateTime = itemView.findViewById(R.id.text_view_end_date_time);
textViewLodgingAddress = itemView.findViewById(R.id.text_view_description);
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
int position = getAdapterPosition();
if (listener != null && position != RecyclerView.NO_POSITION) {
listener.onItemClick(trips.get(position));
}
}
});
}
}
public interface OnItemClickListener {
void onItemClick(Trip trip);
}
public void setOnItemClickListener(OnItemClickListener listener) {
this.listener = listener;
}
}
MainActivity.java
//adapter
RecyclerView recyclerView = findViewById(R.id.recycler_view);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setHasFixedSize(true);
final TripAdapter adapter = new TripAdapter();
recyclerView.setAdapter(adapter );
tripViewModel = new ViewModelProvider(this, ViewModelProvider.AndroidViewModelFactory.getInstance(this.getApplication())).get(TripViewModel.class);
tripViewModel.getAllTrips().observe(this, new Observer<List<Trip>>() {
#Override
public void onChanged(#Nullable List<Trip> trips) {
adapter.setTrips(trips);
}
});
//this on onActivityResult()
else if (requestCode == ADD_LODGING && resultCode == Activity.RESULT_OK) {
//get data from lodging activity
String lodgingTitle = data.getStringExtra(LodgingEditActivity.EXTRA_LODGING_TITLE);
String lodgingCheckInDateTime = data.getStringExtra(LodgingEditActivity.EXTRA_LODGING_CHECK_IN_DATE_TIME);
String lodgingCheckOutDateTime = data.getStringExtra(LodgingEditActivity.EXTRA_LODGING_CHECK_OUT_DATE_TIME);
String lodgingDescription = data.getStringExtra(LodgingEditActivity.EXTRA_LODGING_DESCRIPTION);
String lodgingAddress = data.getStringExtra(LodgingEditActivity.EXTRA_LODGING_ADDRESS);
String lodgingPhone = data.getStringExtra(LodgingEditActivity.EXTRA_LODGING_PHONE);
String lodgingWebsite = data.getStringExtra(LodgingEditActivity.EXTRA_LODGING_WEBSITE);
String lodgingEmail = data.getStringExtra(LodgingEditActivity.EXTRA_LODGING_EMAIL);
String lodgingImagePath = "test";
Trip lodging = new Trip(lodgingTitle, lodgingCheckInDateTime, lodgingCheckOutDateTime,lodgingDescription, lodgingAddress, lodgingPhone, lodgingWebsite, lodgingEmail,lodgingImagePath);
tripViewModel.insert(lodging);
Toast.makeText(this, "lodging save", Toast.LENGTH_SHORT).show();
}
My application I adapt from codinginflow channel.
https://codinginflow.com/tutorials/android/room-viewmodel-livedata-recyclerview-mvvm/part-1-introduction

How to add OnitemClickListener in ArrayList without ListView

I want to make a dashboard in android studio.I use two xml for making dashboard main_activity and list_item activity.In the coding session i used model class adapter and also main class.
public class MainActivity extends AppCompatActivity {
ArrayList<DashModel> dashModelArrayList;
DashAdapter dashAdapter;
private RecyclerView recyclerView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView = findViewById(R.id.rv1);
dashModelArrayList = new ArrayList<>();
String heads[] = {"Jobs", "My Profile", "Messages", "Applied Jobs", "Resume", "Settings"};
String subs[] = {"12 new jobs found", "75% complete", "2 new messages", "3 applies jobs", "Edit resume", "Set preferences"};
int images[] = {R.drawable.find_jobs, R.drawable.profile, R.drawable.messages, R.drawable.applied_jobs,
R.drawable.resume, R.drawable.settings};
for (int count = 0; count < heads.length; count++) {
DashModel dashModel = new DashModel();
dashModel.setHead(heads[count]);
dashModel.setSub(subs[count]);
dashModel.setImage(images[count]);
dashModelArrayList.add(dashModel);
//this should be retrieved in our adapter
}
recyclerView.setLayoutManager(new GridLayoutManager(getApplicationContext(), 2));
dashAdapter = new DashAdapter(dashModelArrayList);
recyclerView.setHasFixedSize(true);
recyclerView.setAdapter(dashAdapter);
}}
Adapter class :
public class DashAdapter extends RecyclerView.Adapter<DashAdapter.ViewHolder> {
ArrayList<DashModel> dashModelArrayList;
public DashAdapter(ArrayList<DashModel> dashModelArrayList) {
this.dashModelArrayList = dashModelArrayList;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item,parent,false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
String ret_head = dashModelArrayList.get(position).getHead();
holder.setheader(ret_head);
String ret_sub = dashModelArrayList.get(position).getSub();
holder.set_sub(ret_sub);
int ret_image = dashModelArrayList.get(position).getImage();
holder.set_image(ret_image);
}
#Override
public int getItemCount() {
return dashModelArrayList.size();
}
public class ViewHolder extends RecyclerView.ViewHolder{
TextView header,sub_header;
ImageView images;
View myView;
public ViewHolder(View itemView) {
super(itemView);
myView = itemView;
}
public void setheader(String h)
{
header = myView.findViewById(R.id.header);
header.setText(h);
}
public void set_sub(String s)
{
sub_header = myView.findViewById(R.id.sub_header);
sub_header.setText(s);
}
public void set_image(int i)
{
images = myView.findViewById(R.id.dash_image);
images.setImageResource(i);
}
}}
How can i add onItemclickListener here?
I expect and want to add OnItemclickListener in the icon but i can't and don't know how to add.
To create a onClickListener for RecyclerView you have to create a class which implements the RecyclerView.OnItemTouchListener
import android.support.v7.widget.*;
import android.view.*;
import android.content.*;
public class RecyclerViewTouchListener implements RecyclerView.OnItemTouchListener {
private GestureDetector gestureDetector;
private ClickListener clickListener;
public RecyclerViewTouchListener(Context context, final RecyclerView recyclerView, final ClickListener clickListener) {
this.clickListener = clickListener;
gestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
#Override
public boolean onSingleTapUp(MotionEvent e) {
return true;
}
#Override
public void onLongPress(MotionEvent e) {
View child = recyclerView.findChildViewUnder(e.getX(), e.getY());
if (child != null && clickListener != null) {
clickListener.onLongClick(child, recyclerView.getChildPosition(child));
}
}
});
}
#Override
public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
View child = rv.findChildViewUnder(e.getX(), e.getY());
if (child != null && clickListener != null && gestureDetector.onTouchEvent(e)) {
clickListener.onClick(child, rv.getChildPosition(child));
}
return false;
}
#Override
public void onTouchEvent(RecyclerView rv, MotionEvent e) {
}
#Override
public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
}
public interface ClickListener{
public void onClick(View view,int position);
public void onLongClick(View view,int position);
}
}
After that you can attach it to your RecyclerView to listen for clicks.
recyclerView.addOnItemTouchListener(new RecyclerViewTouchListener(getActivity(), recyclerView, new RecyclerViewTouchListener.ClickListener(){
#Override
public void onClick(View view, int position)
{
// TODO: Implement this method
}
#Override
public void onLongClick(View view, int position)
{
// TODO: Implement this method
}
}));

getAdapterPosition not doing what it is supposed to do

I have a RecyclerView Fragment to which I added a Filter Search in an edit text. It works, but when I click in a Card of the Recycler, it goes to the wrong detail. My best guess is that it's getting the wrong position from the getAdapterPosition since let's say I have this list {a,b,c,d,e,f,g,h}. when I filter and get two itmes left like {d,g}. If I click d it redirects to a, if I click g it redirects to b.
This is my RecyclerView
public class RecyclerProfile extends Fragment implements
Adapter.AdapterListener, com.example.cake.profiling.Adapter.SearchListener
{
private RecyclerListener recyclerListener;
private List<Profile> profiles = (new DAOProfile()).getProfile();
private Adapter recyclerAdapter= new Adapter(profiles, this);
public RecyclerProfile() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view= inflater.inflate(R.layout.fragment_recycler_profile,
container, false);
RecyclerView recyclerView = view.findViewById(R.id.recyclerProfile);
EditText editText = view.findViewById(R.id.editText);
editText.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int
count) {
}
#Override
public void afterTextChanged(Editable s) {
filter(s.toString());
}
});
recyclerView.setHasFixedSize(true);
RecyclerView.LayoutManager layoutManager = new
LinearLayoutManager(getContext(), LinearLayoutManager.VERTICAL, false);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setAdapter(recyclerAdapter);
setHasOptionsMenu(true);
return view;
}
private void filter(String text){
ArrayList<Profile> filteredList = new ArrayList<>();
for (Profile profile: profiles){
if (profile.getName().toLowerCase().contains(text.toLowerCase())){
filteredList.add(profile);
}
}
recyclerAdapter.filterList(filteredList);
profiles = new ArrayList<>(filteredList);
}
#Override
public void listen(Profile profile, Integer position) {
recyclerListener.send(profile, position);
}
#Override
public void profileSelected(Profile profile) {
}
//INTERFACE
public interface RecyclerListener {
void send(Profile profile, Integer position);
}
//ON ATTACH
#Override
public void onAttach(Context context) {
super.onAttach(context);
this.recyclerListener = (RecyclerListener) context;
}
}
This is my Adapter
public class Adapter extends RecyclerView.Adapter<Adapter.ProfileViewHolder> {
private List<Profile> profiles;
private AdapterListener adapterListener;
//CONSTRUCTOR
public Adapter(List<Profile> profiles,AdapterListener adapterListener) {
this.profiles = profiles;
this.adapterListener = adapterListener;
}
#NonNull
#Override
public Adapter.ProfileViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
Context context = parent.getContext();
LayoutInflater layoutInflater = LayoutInflater.from(context);
View view = layoutInflater.inflate(R.layout.card_profile, parent, false);
ProfileViewHolder profileViewHolder = new ProfileViewHolder(view);
return profileViewHolder;
}
#Override
public void onBindViewHolder(#NonNull Adapter.ProfileViewHolder holder, int position) {
Profile profile = profiles.get(position);
holder.setter(profile);
}
#Override
public int getItemCount() {
return profiles.size();
}
public void filterList (ArrayList<Profile> filteredList){
profiles = filteredList;
notifyDataSetChanged();
}
//VIEWHOLDER
class ProfileViewHolder extends RecyclerView.ViewHolder{
private ImageView image;
private TextView name;
public ProfileViewHolder(View itemView) {
super(itemView);
name = itemView.findViewById(R.id.nameProfile);
image = itemView.findViewById(R.id.imageProfile);
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Profile profile = profile.get(getAdapterPosition());
adapterListener.receive(profile, getAdapterPosition());
}
});
}
public void setter (Profile profile){
name.setText(profile.getName());
image.setImageResource(profile.getImage());
}
}
public interface AdapterListener {
void receive(Profile profile, Integer position);
}
}
getAdapterPosition()
this will return the position of the item of current data set. This is what I'd do
class ProfileViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
private ImageView image;
private TextView name;
Profile mProfile;
public ProfileViewHolder(View itemView) {
super(itemView);
name = itemView.findViewById(R.id.nameProfile);
image = itemView.findViewById(R.id.imageProfile);
name.setOnClickListener(this);
image.setOnClickListener(this);
}
public void setter (Profile profile){
if(profile != null) {
mProfile = profile;
name.setText(mProfile.getName());
image.setImageResource(mProfile.getImage());
}
}
}
#Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.item_nameProfile:
case R.id.item_imageProfile:
for(int i = 0 ; i < profiles.size() ; i++) {
if(profiles.get(i).getName().equalsIgnoreCase(mProfile.getName()) {
adapterListener.receive(profiles.get(i), i);
break;
}
}
break;
}
}
public interface AdapterListener {
void receive(Profile profile, Integer position);
}
}

Categories