How to save and restore RecyclerView Items's positions using Json - java

I have a RecyclerView with 5 items and drag & drop feature. I want to save items's positions into SharedPreferences in order to restore them when the App is launched. Currently I'm able to save their positions into SharedPreferences using Json but the App crashes when I restore positions. Any solution? Thanks.
public static AppCompatActivity mActivity;
public static SharedPreferences SP;
public static SharedPreferences.Editor mEditor;
public static RecyclerView mRecyclerView;
public static RecyclerViewDragDropManager mRecyclerViewDragDropManager;
public static List<Long> mSaveItemsOrder;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mActivity = this;
SP = PreferenceManager.getDefaultSharedPreferences(getBaseContext());
mEditor = SP.edit();
mRecyclerView = (RecyclerView) findViewById(R.id.recycler_view);
mRecyclerViewDragDropManager = new RecyclerViewDragDropManager();
mRecyclerViewDragDropManager.setInitiateOnMove(false);
mRecyclerViewDragDropManager.setInitiateOnLongPress(true);
mRecyclerViewDragDropManager.setLongPressTimeout(300);
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
mRecyclerView.setAdapter(mRecyclerViewDragDropManager.createWrappedAdapter(new Adapter()));
mRecyclerViewDragDropManager.attachRecyclerView(mRecyclerView);
}
public static class Item {
public final long id;
public final String text;
public Item(long id, String text) {
this.id = id;
this.text = text;
}
}
public static class ViewHolder extends AbstractDraggableItemViewHolder {
Button mButton;
public ViewHolder(View itemView) {
super(itemView);
mButton = (Button) itemView.findViewById(R.id.button);
}
}
public static class Adapter extends RecyclerView.Adapter<ViewHolder> implements DraggableItemAdapter<ViewHolder> {
List<Item> mItems;
public Adapter() {
setHasStableIds(true);
mItems = new ArrayList<>();
if (SP.getString("items_order", null) == null) {
for (int mInt = 0; mInt < 5; mInt++) {
mItems.add(new Item(mInt, "Item " + mInt));
}
} else {
mItems = new Gson().fromJson(SP.getString("items_order", null), new TypeToken<Item>(){}.getType());
}
}
#Override
public long getItemId(int position) {
return mItems.get(position).id;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View mView = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_view, parent, false);
return new ViewHolder(mView);
}
#Override
public void onBindViewHolder(final ViewHolder holder, final int position) {
Item mItem = mItems.get(position);
holder.mButton.setText(mItem.text);
}
#Override
public int getItemCount() {
return mItems.size();
}
#Override
public void onMoveItem(int fromPosition, int toPosition) {
Item mMovedItem = mItems.remove(fromPosition);
mItems.add(toPosition, mMovedItem);
notifyItemMoved(fromPosition, toPosition);
}
#Override
public boolean onCheckCanStartDrag(ViewHolder holder, int position, int x, int y) {
return true;
}
#Override
public ItemDraggableRange onGetItemDraggableRange(ViewHolder holder, int position) {
return null;
}
#Override
public boolean onCheckCanDrop(int draggingPosition, int dropPosition) {
return true;
}
}
#Override
protected void onPause() {
super.onPause();
mSaveItemsOrder = new ArrayList<>();
for (int mInt = 0; mInt < mRecyclerView.getAdapter().getItemCount(); mInt++) {
mSaveItemsOrder.add(mRecyclerView.getAdapter().getItemId(mInt));
}
mEditor.putString("items_order", new Gson().toJson(mSaveItemsOrder)).commit();
}
This is the error:
https://www.dropbox.com/s/j2tf4n08depyynt/Error.txt?dl=0

The problem is with your JSON.
You the object you are serializing to JSON is mSaveItemsOrder which is an ArrayList. But on deserializing you give GSON the Class new TypeToken<Item>(){}.getType().
So you store an ArrayList in your JSON but trying to deserialzie a different Class, that won't work.
This should work:
mItems = new Gson().fromJson(SP.getString("items_order", null), new TypeToken<ArrayList>(){}.getType(););

Related

Attempt to invoke virtual method 'void.estate.view.adapter.plucking.EmployeePluckingSessionAdapter.setList(java.util.List)' on a null object reference

I am getting this error but I cannot find the reason.
This is my code of Adapter.
public class EmployeePluckingSessionAdapter extends RecyclerView.Adapter<EmployeePluckingSessionAdapter.EmployeePluckingSessionAdapterHolder> {
private SubSessionListActivity.AdapterEvents adapterEvents;
private List<EmployeePluckingCollectionSummary> employeePluckingCollectionSummaries = new ArrayList<>();
public EmployeePluckingSessionAdapter(SubSessionListActivity.AdapterEvents adapterEvents){
this.adapterEvents = adapterEvents;
}
public void setList(List<EmployeePluckingCollectionSummary> employeePluckingCollectionSummaries){
this.employeePluckingCollectionSummaries = employeePluckingCollectionSummaries;
}
public void setAdapterEvents(SubSessionListActivity.AdapterEvents adapterEvents) {
this.adapterEvents = adapterEvents;
}
#NonNull
#Override
public EmployeePluckingSessionAdapterHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.plucking_summary_data, parent, false);
return new EmployeePluckingSessionAdapterHolder(view);
}
#Override
public void onBindViewHolder(#NonNull EmployeePluckingSessionAdapterHolder holder, int position) {
EmployeePluckingCollectionSummary employeePluckingCollectionSummary = employeePluckingCollectionSummaries.get(position);
holder.userName.setText(String.valueOf(employeePluckingCollectionSummary.getEmployeeName()));
holder.userId.setText(String.valueOf(employeePluckingCollectionSummary.getEmployeeId()));
holder.session.setText(String.valueOf(employeePluckingCollectionSummary.getSessionName()));
holder.sessionTotal.setText(String.valueOf(employeePluckingCollectionSummary.getWeight()));
}
#Override
public int getItemCount() {
return 0;
}
class EmployeePluckingSessionAdapterHolder extends RecyclerView.ViewHolder {
private final LinearLayout plucking_data;
private final TextView userName;
private final TextView userId;
private final TextView session;
private final TextView sessionTotal;
public EmployeePluckingSessionAdapterHolder(View view) {
super(view);
this.plucking_data = view.findViewById(R.id.plucking_data);
this.userName = view.findViewById(R.id.userName);
this.userId =view.findViewById(R.id.userId);
this.session = view.findViewById(R.id.session);
this.sessionTotal = view.findViewById(R.id.sessionTotal);
}
}
}
This is my code of Activity.
public class PluckingChecklistReportActivity extends AppCompatActivity {
private PluckingCollectionViewModel pluckingCollectionViewModel;
RecyclerView recyclerView;
List<EmployeePluckingCollectionSummary> pluckingSummary = new ArrayList<>();
LinearLayoutManager linearLayoutManager;
EmployeePluckingSessionAdapter employeePluckingSessionAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_plucking_checklist_report);
pluckingCollectionViewModel = new ViewModelProvider(this).get(PluckingCollectionViewModel.class);
recyclerView = findViewById(R.id.plucking_data);
linearLayoutManager = new LinearLayoutManager(this);
recyclerView.setAdapter(employeePluckingSessionAdapter);
recyclerView.setLayoutManager(linearLayoutManager);
pluckingCollectionViewModel.getEmployeePluckingSessionSummary().observe(this, new Observer<List<EmployeePluckingCollectionSummary>>() {
#Override
public void onChanged(List<EmployeePluckingCollectionSummary> employeePluckingCollectionSummaries) {
pluckingSummary = employeePluckingCollectionSummaries;
employeePluckingSessionAdapter.setList(pluckingSummary);
}
});
}
}
I found that "pluckingSummary" list is null. I don't know how to set values to the list. I tried to set the values to arrayList after convert it into JSONObject but it did not work as well. I get values correctly when I use System.out.println(new Gson().toJson(employeePluckingCollectionSummaries));

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);
}
//.......
}

Android RecyclerView With EditText Shuffling Problem

I Am Trying to Implement RecyclerView With EditText. First I Am Fetching Members List From Database And then for each member I want to get value from user input(EditText).
But when I submit data, values for the members are getting shuffled.
I Am Using TextWatcher Class, When Text Get changed it adds value in the model class.
Values are getting shuffled when I scroll the RecyclerView.
I tried all the solutions on the stack overflow but none of it worked
following is my code:
For Fetching the data:
public class MainActivity extends AppCompatActivity {
RecyclerView recyclerView;
ProgressBar progressBar;
LinearLayoutManager manager;
String URL = "members_fetch.php?club_id=98";
List<MemberListDetails> memberListDetailsList = new ArrayList<>();
private LinearLayoutManager layoutManager;
MemberListDetails memberListDetails;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
progressBar = findViewById(R.id.progress);
Button button = findViewById(R.id.button);
recyclerView = findViewById(R.id.my_recycler_view);
manager = new LinearLayoutManager(this);
initRecyclerView();
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String z = ((Adapter) recyclerView.getAdapter()).getValue().toString();
Log.wtf("aaa", z);
}
});
getMembersDetails();
}
private void initRecyclerView() {
layoutManager = new LinearLayoutManager(this);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(layoutManager);
}
private void getMembersDetails() {
final ProgressDialog pd = new ProgressDialog(this);
pd.setMessage("Loading Members Details");
pd.show();
pd.setCancelable(false);
pd.setCanceledOnTouchOutside(false);
RequestQueue queue = Volley.newRequestQueue(MainActivity.this);
StringRequest stringRequest = new StringRequest(Request.Method.GET, URL,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
pd.dismiss();
try {
JSONArray jsonArray = new JSONArray(response);
for (int i = 0; i < jsonArray.length(); i++) {
Log.d("ssdf", "fsdf" + response);
JSONObject o = jsonArray.getJSONObject(i);
memberListDetails = new MemberListDetails();
memberListDetails.setStatus(o.getString("status"));
memberListDetails.setMembership_id(o.getString("membership_id"));
memberListDetails.setFirst_name(o.getString("first_name"));
memberListDetails.setMiddle_name(o.getString("middle_name"));
memberListDetails.setLast_name(o.getString("last_name"));
memberListDetails.setClub_post(o.getString("club_post"));
memberListDetails.setDistrict_post(o.getString("district_post"));
memberListDetails.setGender(o.getString("gender"));
memberListDetails.setPost_name(o.getString("post_name"));
memberListDetailsList.add(memberListDetails);
Log.d("hhhhh", "xxxx" + memberListDetailsList);
}
recyclerView.setAdapter(new Adapter(memberListDetailsList, MainActivity.this));
} catch (Exception e) {
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(MainActivity.this, error.getMessage(), Toast.LENGTH_SHORT).show();
Log.d("errorMsg", "dddd" + error.getMessage());
pd.dismiss();
}
});
queue.add(stringRequest);
}
}
For Adapter Class :
public class Adapter extends RecyclerView.Adapter<Adapter.VHolder> {
private List<MemberListDetails> data;
Context context;
EditText text;
Integer pos;
public Adapter(List<MemberListDetails> data, Context context) {
this.data = data;
this.context = context;
}
#NonNull
#Override
public Adapter.VHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
LayoutInflater inflater = LayoutInflater.from(context);
View view = inflater.inflate(R.layout.item, viewGroup, false);
return new VHolder(view);
}
#Override
public int getItemCount() {
return data.size();
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public int getItemViewType(int position) {
return position;
}
public List<MemberListDetails> getItems() {
return data;
}
#Override
public void onBindViewHolder(#NonNull Adapter.VHolder vHolder, int i) {
vHolder.setIsRecyclable(false);
vHolder.textView.setText(data.get(i).getFirst_name());
text = vHolder.editText;
pos = i;
text.setText(data.get(i).getValue());
text.addTextChangedListener(new TextWatcher() {
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
// text.setError(null);
data.get(pos).setValue(s.toString());
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
// TODO Auto-generated method stub
}
#Override
public void afterTextChanged(Editable s) {
// text.setError(null);
data.get(pos).setValue(s.toString());
}
});
}
public class VHolder extends RecyclerView.ViewHolder {
TextView textView;
EditText editText;
public VHolder(View itemView) {
super(itemView);
textView = itemView.findViewById(R.id.tv_textView);
editText = itemView.findViewById(R.id.editText2);
}
}
String getValue() {
StringBuffer x = new StringBuffer();
for (MemberListDetails a : data) {
x.append(a.getValue()+",");
}
return x.substring(0,x.length()-1);
}
}
I think you need to remove global edit text and position. Also, add text watcher in holder class. Please check below code. it may help you.
public class Adapter extends RecyclerView.Adapter<Adapter.VHolder> {
private List<MemberListDetails> data;
Context context;
public Adapter(List<MemberListDetails> data, Context context) {
this.data = data;
this.context = context;
}
#NonNull
#Override
public Adapter.VHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
LayoutInflater inflater = LayoutInflater.from(context);
View view = inflater.inflate(R.layout.item, viewGroup, false);
return new VHolder(view);
}
#Override
public int getItemCount() {
return data.size();
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public int getItemViewType(int position) {
return position;
}
public List<MemberListDetails> getItems() {
return data;
}
#Override
public void onBindViewHolder(#NonNull Adapter.VHolder vHolder, int i) {
vHolder.setIsRecyclable(false);
vHolder.textView.setText(data.get(i).getFirst_name());
vHolder.editText.removeTextChangedListener(vHolder.textWatcher);
vHolder.editText.setText(data.get(i).getValue());
vHolder.editText.addTextChangedListener(vHolder.textWatcher);
}
public class VHolder extends RecyclerView.ViewHolder {
TextView textView;
EditText editText;
TextWatcher textWatcher;
public VHolder(View itemView) {
super(itemView);
textView = itemView.findViewById(R.id.tv_textView);
editText = itemView.findViewById(R.id.editText2);
textWatcher = new TextWatcher() {
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
// TODO Auto-generated method stub
}
#Override
public void afterTextChanged(Editable s) {
// text.setError(null);
data.get(getAdapterPosition()).setValue(s.toString());
}
};
}
}
String getValue() {
StringBuffer x = new StringBuffer();
for (MemberListDetails a : data) {
x.append(a.getValue()+",");
}
return x.substring(0,x.length()-1);
}
Here is the solution. It may contain some error because I am not able to compile if due unavailable of resources like xml file and Model class But it definitely works for you. Because I have implemented the same in my project and working fine
public class Adapter extends RecyclerView.Adapter<Adapter.VHolder> {
private List<MemberListDetails> data;
Context context;
Integer pos;
public Adapter(List<MemberListDetails> data, Context context) {
this.data = data;
this.context = context;
}
#NonNull
#Override
public Adapter.VHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
LayoutInflater inflater = LayoutInflater.from(context);
View view = inflater.inflate(R.layout.item, viewGroup, false);
return new VHolder(view);
}
#Override
public int getItemCount() {
return data.size();
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public int getItemViewType(int position) {
return position;
}
public List<String> getItems() {
return data;
}
#Override
public void onBindViewHolder(#NonNull Adapter.VHolder vHolder, int i) {
vHolder.setIsRecyclable(false);
vHolder.textView.setText(data.get(i).getFirst_name());
pos = i;
vHolder.myCustomEditTextListener.updatePosition(vHolder.getAdapterPosition());
vHolder.editText.setText(data.get(vHolder.getAdapterPosition()));
}
public class VHolder extends RecyclerView.ViewHolder {
TextView textView;
EditText editText;
public MyCustomEditTextListener myCustomEditTextListener;
public VHolder(View itemView, MyCustomEditTextListener myCustomEditTextListener) {
super(itemView);
textView = itemView.findViewById(R.id.tv_textView);
editText = itemView.findViewById(R.id.editText2);
this.editText.addTextChangedListener(myCustomEditTextListener);
}
}
String getValue() {
StringBuffer x = new StringBuffer();
for (MemberListDetails a : data) {
x.append(a.getValue() + ",");
}
return x.substring(0, x.length() - 1);
}
private class MyCustomEditTextListener implements TextWatcher {
private int position;
public void updatePosition(int position) {
this.position = position;
}
#Override
public void beforeTextChanged(CharSequence charSequence, int i, int i2, int i3) {
// no op
}
#Override
public void onTextChanged(CharSequence charSequence, int i, int i2, int i3) {
data.set(position, charSequence.toString());
}
#Override
public void afterTextChanged(Editable editable) {
// no op
}
}
}

How to pass id instead of position using recyclerView in android

I have pass position in recyclerView click but some kind of problem pass to position to display wrong data so how can i pass people id in recyclerView.
I m new in android programming
recyclerView Item Click
recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
buildCustomAdapter = new BuildCustomAdapter(this, peopleList);
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getApplicationContext());
recyclerView.setLayoutManager(mLayoutManager);
buildCustomAdapter.notifyDataSetChanged();
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setAdapter(buildCustomAdapter);
buildCustomAdapter.setOnItemClickListener(new BuildCustomAdapter.OnItemClickListener() {
#Override
public void onItemClick(View view, int position) {
detailPeople(position);
}
});
private void detailPeople(int position) {
Intent intent = new Intent(this, AddDetail.class);
intent.putExtra("peopleID", position);
startActivity(intent);
}
Model.class
public class People implements Serializable {
private String peopleImage;
private String peopleName;
private String id;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public void setPeopleName(String peopleName) {
this.peopleName = peopleName;
}
public String getPeopleName() {
return peopleName;
}
public void setPeopleImage(String peopleImage) {
this.peopleImage = peopleImage;
}
public String getPeopleImage() {
return peopleImage;
}
}
Adapter code
public class BuildCustomAdapter extends RecyclerView.Adapter<BuildCustomAdapter.MyViewHolder> implements Filterable {
private List<People> peopleList;
private List<People> peopleListCopy;
private ItemFilter mFilter = new ItemFilter();
private OnItemClickListener mOnItemClickListener;
private Context mContext;
public BuildCustomAdapter(Context context, List<People> buildList) {
mContext = context;
this.peopleList = buildList;
this.peopleListCopy = new ArrayList<>();
peopleListCopy.addAll(buildList);
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.build_list_row, parent, false);
return new MyViewHolder(itemView);
}
#Override
public void onBindViewHolder(final MyViewHolder holder, final int position) {
People people = peopleList.get(position);
byte[] decodedString = Base64.decode(people.getPeopleImage(), Base64.DEFAULT);
Bitmap decodedByte = BitmapFactory.decodeByteArray(decodedString, 0, decodedString.length);
holder.ivPeopleImage.setImageBitmap(decodedByte);
holder.tvPersonName.setText(people.getPeopleName());
holder.button.setSelected(people.getStatus() == 1);
holder.button.setOnClickListener(new onSelectListener(position));
}
#Override
public int getItemCount() {
return peopleList.size();
}
#Override
public Filter getFilter() {
if (mFilter == null) {
mFilter = new ItemFilter();
}
return mFilter;
}
public class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
public TextView tvPersonName;
public Button button;
public CircularImageView ivPeopleImage;
public MyViewHolder(View itemView) {
super(itemView);
mContext = itemView.getContext();
ivPeopleImage = (CircularImageView) itemView.findViewById(R.id.ivPerson);
tvPersonName = (TextView) itemView.findViewById(R.id.tvPersonName);
button = (Button) itemView.findViewById(R.id.addbn);
tvPersonName.setOnClickListener(this);
ivPeopleImage.setOnClickListener(this);
}
#Override
public void onClick(View v) {
if (mOnItemClickListener != null)
mOnItemClickListener.onItemClick(v, getPosition());
}
}
public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
mOnItemClickListener = onItemClickListener;
}
public interface OnItemClickListener {
void onItemClick(View view, int position);
}
private class ItemFilter extends Filter {
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new FilterResults();
if (constraint != null && constraint.length() > 0) {
List<People> filterList = new ArrayList<>();
for (int i = 0; i < peopleListCopy.size(); i++) {
if ((peopleListCopy.get(i).getPeopleName().toUpperCase())
.contains(constraint.toString().toUpperCase())) {
People peopleName = peopleListCopy.get(i);
filterList.add(peopleName);
}
}
results.count = filterList.size();
results.values = filterList;
} else {
results.count = peopleListCopy.size();
results.values = peopleListCopy;
}
return results;
}
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
peopleList = (List<People>) results.values;
notifyDataSetChanged();
}
}
private class onSelectListener implements View.OnClickListener {
int mPosition;
public onSelectListener(int position) {
mPosition = position;
}
#Override
public void onClick(View view) {
People people = peopleList.get(mPosition);
view.setSelected(!view.isSelected());
people.setStatus(view.isSelected() ? 1 : 0);
notifyDataSetChanged();
}
}
}
Next Activity to get intent
Bundle bundle = getIntent().getExtras();
if (bundle != null) {
int peopleID = bundle.getInt("peopleID");
peopleList.clear();
BuildDataa();
People peopleDetailsObj = peopleList.get(peopleID);
}
Please replace
#Override
public void onClick(View v) {
if (mOnItemClickListener != null)
mOnItemClickListener.onItemClick(v, getPosition());
}
to
#Override
public void onClick(View v) {
if (mOnItemClickListener != null)
mOnItemClickListener.onItemClick(v, peopleList.get(getPosition()).getId());
}
in your adapter. And change signature of method onItemClick from
onItemClick(View v, int position)
to
onItemClick(View v, String id)
and use this to get People according to ID
People peopleDetailsObj=null;
for(People ple:peopleList)
{
if(ple.getId().equals(peopleID)){
peopleDetailsObj=ple;
break;
}}
Take the id from position.
String id=peopleList.get(position).getId();
detailPeople(id);
Pass that id in your method and you are done.
Use position to get People object from ArrayList. Change detailPeople() method with below code.
private void detailPeople(int position) {
Intent intent = new Intent(this, AddDetail.class);
intent.putExtra("peopleID", peopleList.get(position).getId());
startActivity(intent);
}
intent.putExtra("id", peopleList.get(position).getId());

onClickListener in RecyclerView.ViewHolder

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
}
})
);

Categories