wrong recyclerview item position - java

my recyclerview is great in scrolling but when it contains more than two items and click on last item or the one before it gives me the wrong position this is
and throws a NullPointerException this is my whole code from adapter to the listener.
my code :
public class ListAdapter extends RecyclerView.Adapter<ViewHolder> {
private List<ItemView> items;
private Context context;
public ListAdapter(List<ItemView> items, Context context) {
this.items = items;
this.context = context;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.item_style, parent, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
ItemView i = items.get(position);
ViewHolder.setHeadText(i.getHead());
ViewHolder.setScoreText(i.getContent());
}
#Override
public int getItemCount() {
return items.size();
}
}
class ViewHolder extends RecyclerView.ViewHolder {
private RecyclerViewOnTouchItemListener.ClickListener clickListener;
private static TextView headText, urlText;
private ConstraintLayout itemLayout;
public ViewHolder(View itemView) {
super(itemView);
headText = (TextView) itemView.findViewById(R.id.list_item_header);
urlText = (TextView) itemView.findViewById(R.id.list_item_content);
itemLayout = (ConstraintLayout) itemView.findViewById(R.id.item_list);
// itemLayout.setOnClickListener(this);
}
public static void setHeadText(String headText) {
ViewHolder.headText.setText(headText);
}
public static void setScoreText(String scoreText) {
ViewHolder.urlText.setText(scoreText);
}
public static String getHeadText(){return headText.getText().toString();}
public static String getUrlText(){return urlText.getText().toString();}
}
class RecyclerViewOnTouchItemListener implements RecyclerView.OnItemTouchListener {
private GestureDetector gestureDetector;
private ClickListener clickListener;
public RecyclerViewOnTouchItemListener(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.getChildAdapterPosition(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.getChildAdapterPosition(child));
}
return false;
}
#Override
public void onTouchEvent(RecyclerView rv, MotionEvent e) { }
#Override
public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) { }
interface ClickListener {
void onClick(View view, int position);
void onLongClick(View view, int position);
}
}
and this is the activity that holds the recyclerview :
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_url_list);
context = getApplicationContext();
database = new DatabaseHelper(context);
listOfUrl = (RecyclerView) findViewById(R.id.url_list);
find = (Button) findViewById(R.id.findBtn);
cancel = (Button) findViewById(R.id.cancelBtn);
makeItPopUp();
listOfUrl.setLayoutManager(new LinearLayoutManager(this));
listOfUrl.setHasFixedSize(true);
listOfUrl.addItemDecoration(new DividerItemDecoration(this, LinearLayoutManager.VERTICAL));
adapter = new ListAdapter(fillList(), context);
listOfUrl.setAdapter(adapter);
adapter.notifyDataSetChanged();
selectedItems = new ArrayList<Boolean>(Arrays.asList(new Boolean[listOfUrl.getAdapter().getItemCount()]));
Collections.fill(selectedItems, Boolean.FALSE);
listOfUrl.addOnItemTouchListener(
new RecyclerViewOnTouchItemListener(this, listOfUrl
, new RecyclerViewOnTouchItemListener.ClickListener() {
#Override
public void onClick(View view, int position) {
if (selectedItems.get(position))
setItemSelectedState(false, position, Color.WHITE);
else
setItemSelectedState(true, position, Color.LTGRAY);
}
#Override
public void onLongClick(View view, int position) {}
private void setItemSelectedState(boolean isSelected, int position, int color) {
try {
listOfUrl.getChildAt(position).setBackgroundColor(color);
selectedItems.add(position, isSelected);
} catch (NullPointerException e) {
e.printStackTrace();
}
}
})
);
find.setOnClickListener(this);
cancel.setOnClickListener(this); }
any on can tell me what i did wrong.

Simple solution, create interface class:
public interface ListListener {
void onClick(int pos);
void onLongClick(int pos);
}
Adjust the content of your RecyclerViewAdapter class:
public class ListAdapter extends RecyclerView.Adapter<ViewHolder> {
private ListListener listener;
private List<ItemView> items;
private Context context;
public ListAdapter(List<ItemView> items, Context context) {
this.items = items;
this.context = context;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.item_style, parent, false);
return new ViewHolder(view);
}
public ItemView getItem(int pos) {
return items.get(pos);
}
public void setListener(ListListener listener) {
this.listener = listener;
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
ItemView i = items.get(position);
holder.setHeadText(i.getHead());
holder.setScoreText(i.getContent());
holder.itemLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int pos = holder.getAdapterPosition();
if (listener != null && pos != RecyclerView.NO_POSITION) {
listener.onClick(pos);
}
}
});
holder.itemLayout.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View view) {
int pos = holder.getAdapterPosition();
if (pos != -1) {
if (listener != null) {
listener.onLongClick(getItem(pos));
}
}
return true;
}
});
}
And in your Activity class I edited some parts:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_url_list);
context = getApplicationContext();
database = new DatabaseHelper(context);
listOfUrl = (RecyclerView) findViewById(R.id.url_list);
find = (Button) findViewById(R.id.findBtn);
cancel = (Button) findViewById(R.id.cancelBtn);
makeItPopUp();
listOfUrl.setLayoutManager(new LinearLayoutManager(this));
listOfUrl.setHasFixedSize(true);
listOfUrl.addItemDecoration(new DividerItemDecoration(this, LinearLayoutManager.VERTICAL));
adapter = new ListAdapter(fillList(), context);
adapter.setListener(new SelectCountryDialogListener() {
#Override
public void onClick(int pos) {
ItemView item = adapter.getItem(pos);
}
#Override
public void onLongClick(int pos) {
ItemView item = adapter.getItem(pos);
}
});
listOfUrl.setAdapter(adapter);
selectedItems = new ArrayList<Boolean>(Arrays.asList(new Boolean[listOfUrl.getAdapter().getItemCount()]));
Collections.fill(selectedItems, Boolean.FALSE);
find.setOnClickListener(this);
cancel.setOnClickListener(this);
}
I'm pretty sure, that now it is very easy for you. Just to implement the functionality in onClick and onLongClick methods.

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

Single and Double Tap on recycleview

I have a problem with my code, when i do a single or double tap on item both onDoubleTap and onSingleTapConfirmed are actived while i dont have problem with onLongClick.
In my activity:
mRecyclerView.addOnItemTouchListener(new RecyclerTouchListener(getContext(), mRecyclerView, new RecyclerTouchListener.ClickListener() {
#Override
public void onSingleTapConfirmed(View view, int position) {}
#Override
public void onDoubleTap(View view, int position){}
#Override
public void onLongClick(View view, int position) {}
}));
In my custom listener class:
public class RecyclerTouchListener implements recyclerView.OnItemTouchListener{
private GestureDetector gestureDetector;
private ClickListener clickListener;
public RecyclerTouchListener(Context context, final RecyclerView recyclerView, final ClickListener clickListener) {
this.clickListener = clickListener;
gestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
#Override
public boolean onSingleTapConfirmed(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 onDoubleTap(MotionEvent e) {
return true;
}
});
}
#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.onSingleTapConfirmed(child, rv.getChildPosition(child));
}
return false;
}
public interface ClickListener {
void onSingleTapConfirmed(View view, int position);
void onDoubleTap(View view, int position);
void onLongClick(View view, int position);
}}
add this listener as OnDoubleClickListener.java:
public abstract class OnDoubleClickListener implements View.OnClickListener {
private final int doubleClickTimeout;
private Handler handler;
private long firstClickTime;
public OnDoubleClickListener() {
doubleClickTimeout = ViewConfiguration.getDoubleTapTimeout();
firstClickTime = 0L;
handler = new Handler(Looper.getMainLooper());
}
#Override
public void onClick(final View v) {
long now = System.currentTimeMillis();
if (now - firstClickTime < doubleClickTimeout) {
handler.removeCallbacksAndMessages(null);
firstClickTime = 0L;
onDoubleClick(v);
} else {
firstClickTime = now;
handler.postDelayed(new Runnable() {
#Override
public void run() {
onSingleClick(v);
firstClickTime = 0L;
}
}, doubleClickTimeout);
}
}
public abstract void onDoubleClick(View v);
public abstract void onSingleClick(View v);
public void reset() {
handler.removeCallbacksAndMessages(null);
}
}
and then add ItemClickSupport.java
public class ItemClickSupport {
private final RecyclerView mRecyclerView;
private OnItemClickListener mOnItemClickListener;
private OnDoubleClickListener mOnDoubleClickListener = new OnDoubleClickListener() {
#Override
public void onDoubleClick(View v) {
if (mOnItemClickListener != null) {
RecyclerView.ViewHolder holder = mRecyclerView.getChildViewHolder(v);
mOnItemClickListener.onItemDoubleClicked(mRecyclerView, holder.getAdapterPosition(), v);
}
}
#Override
public void onSingleClick(View v) {
if (mOnItemClickListener != null) {
RecyclerView.ViewHolder holder = mRecyclerView.getChildViewHolder(v);
mOnItemClickListener.onItemClicked(mRecyclerView, holder.getAdapterPosition(), v);
}
}
};
private RecyclerView.OnChildAttachStateChangeListener mAttachListener
= new RecyclerView.OnChildAttachStateChangeListener() {
#Override
public void onChildViewAttachedToWindow(View view) {
if (mOnItemClickListener != null) {
view.setOnClickListener(mOnDoubleClickListener);
}
}
#Override
public void onChildViewDetachedFromWindow(View view) {
}
};
private ItemClickSupport(RecyclerView recyclerView) {
mRecyclerView = recyclerView;
mRecyclerView.setTag(R.id.item_click_support, this);
mRecyclerView.addOnChildAttachStateChangeListener(mAttachListener);
}
public static ItemClickSupport addTo(RecyclerView view) {
ItemClickSupport support = (ItemClickSupport) view.getTag(R.id.item_click_support);
if (support == null) {
support = new ItemClickSupport(view);
}
return support;
}
public static ItemClickSupport removeFrom(RecyclerView view) {
ItemClickSupport support = (ItemClickSupport) view.getTag(R.id.item_click_support);
if (support != null) {
support.detach(view);
}
return support;
}
public ItemClickSupport setOnItemClickListener(OnItemClickListener listener) {
mOnItemClickListener = listener;
return this;
}
private void detach(RecyclerView view) {
view.removeOnChildAttachStateChangeListener(mAttachListener);
view.setTag(R.id.item_click_support, null);
}
public interface OnItemClickListener {
void onItemClicked(RecyclerView recyclerView, int position, View v);
void onItemDoubleClicked(RecyclerView recyclerView, int position, View v);
}
}
and use it :
mRecyclerView = (RecyclerView) rootView.findViewById(R.id.recyclerView);
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setLayoutManager(new GridLayoutManager(getActivity(),
2, GridLayoutManager.VERTICAL, false));
// Make sure your recyler view adapter implements getItemAt(position), which return the item from the dataset placed at position
// in this case I use getProductId() from my POJO Product class
ItemClickSupport.addTo(mRecyclerView)
.setOnItemClickListener(new ItemClickSupport.OnItemClickListener() {
#Override
public void onItemClicked(RecyclerView recyclerView, int position, View v) {
Log.d("ITEM CLICK", "Item single clicked " + mRecyclerViewAdapter.getItemAt(position).getProductId());
}
#Override
public void onItemDoubleClicked(RecyclerView recyclerView, int position, View v) {
Log.d("ITEM CLICK", "Item double clicked " + mRecyclerViewAdapter.getItemAt(position).getProductId());
}
});
source
or check this gist

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

dynamically added items to recycler view not showing up when the application is restarted

I am using a recycler view and items are added to it programatically on user's requirement. When I install the application on my device, the programmatically added items are shown up. But when I kill the app and open it again, the items added programmatically are not showing up. I have maintained an arraylist of items which initially contains 3 items. Any further additions to the llistt are not retained once the app is killed.
Any help is appreciated. Please help!
I am attaching my adapter class and fragment class containing the recycler view.
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {
List<MyItem> items;
private LayoutInflater inflater;
private Context context;
public MyAdapter(Context context, List<MyItem> items){
this.items = items;
this.context = context;
inflater = LayoutInflater.from(context);
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = inflater.inflate(R.layout.item_my_list, parent, false);
MyViewHolder myHolder= new MyViewHolder(view);
return myHolder;
}
#Override
public void onBindViewHolder(MyAdapter.MyViewHolder holder, int position) {
MyItem item = items.get(position);
holder.name.setText(item.get_Name());
holder.number.setText(item.get_Number());
}
#Override
public int getItemCount() {
return items.size();
}
public void delete(int position) {
items.remove(position);
notifyItemRemoved(position);
}
public void add(MyItem item, int position){
items.add(position, item);
notifyItemInserted(position);
notifyItemRangeChanged(0, getItemCount());
}
class MyViewHolder extends RecyclerView.ViewHolder{
TextView number, name;
public MyViewHolder(View itemView){
super(itemView);
number =(TextView) itemView.findViewById(R.id.number);
name = (TextView) itemView.findViewById(R.id.name);
}
}
}
nd here's my fragment class:
public class RecyclerViewFragment extends Fragment {
RecyclerView myRecyclerView;
RecyclerView.Adapter adapter;
TextView addItem;
TextView nameText, numberText;
private static List<MyItem> items;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_recycler_view, container, false);
myRecyclerView = (RecyclerView) view.findViewById(R.id.my_list);
adapter = new MyAdapter(getActivity(), getData());
Log.i("DATA ITEMS", getData().get(0).get_contactName());
Log.i("DATA ITEMS", getData().get(0).get_contactName());
Log.i("DATA ITEMS", getData().get(0).get_contactName());
addItem = (TextView) view.findViewById(R.id.add_new_item);
myRecyclerView.setAdapter(adapter);
myRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
myRecyclerView.addOnItemTouchListener(new RecyclerViewTouchListener(getActivity(), myRecyclerView, new ClickListener() {
#Override
public void onClick(View view, int position) {
Log.i("MY INFO", "item of recycler view clicked" + position);
}
#Override
public void onLongClick(View view, int position) {
}
}));
addItem.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
addNewItem();
}
});
return view;
}
public static List<MyItem> getData(){
items = new ArrayList<>();
items.add(new MyItem("7341973", "xyzabc"));
items.add(new MyItem("86218", "qwerty"));
items.add(new MyItem("178581", "bnmlkjh"));
return items;
}
public void addNewItem(){
LayoutInflater li = LayoutInflater.from(this.getActivity());
View view = li.inflate(R.layout.dialog_add_item, null);
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this.getActivity());
alertDialogBuilder.setView(view);
nameText = (TextView) view.findViewById(R.id.new_name);
numberText = (TextView) view.findViewById(R.id.new_number);
alertDialogBuilder
.setCancelable(false)
.setNegativeButton("Cancel",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
})
.setPositiveButton("Add", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
if(numberText.getText() != null && nameText.getText() != null){
MyItem item = new MyItem(numberText.getText().toString(), nameText.getText().toString());
((MyAdapter) adapter).add(item, 0);
}
else
Toast.makeText(getActivity(), "Add name and number", Toast.LENGTH_SHORT).show();
}
});
AlertDialog dialog = alertDialogBuilder.create();
dialog.show();
}
public interface ClickListener{
void onClick(View view, int position);
void onLongClick(View view, int position);
}
static class RecyclerViewTouchListener implements RecyclerView.OnItemTouchListener{
private GestureDetector detector;
private ClickListener listener;
public RecyclerViewTouchListener (Context context, final RecyclerView recyclerView, final ClickListener clickListener){
this.listener = clickListener;
detector = 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.getChildAdapterPosition(child));
}
}
});
}
#Override
public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
View child = rv.findChildViewUnder(e.getX(), e.getY());
if (child != null && listener != null && detector.onTouchEvent(e)) {
listener.onClick(child, rv.getChildAdapterPosition(child));
}
return false;
}
#Override
public void onTouchEvent(RecyclerView rv, MotionEvent e) {
}
#Override
public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
}
}
}

Categories