Create onClickListener in RecyclerView - java

I tried to make a setListener on adapter to make something Action on the app. But the problem was when using this line of code to call setClickListener
adapter.setClickListener(this);
it gives me this error when using (this)
Required type: ItemClickListener
Provided: HomeImagesFragment
Here are my codes
Picassotest "Adapter for RecyclerView"
public class Picassotest extends RecyclerView.Adapter<Picassotest.ViewHolder> {
private String[] mData;
private Context context;
private LayoutInflater mInflater;
private ItemClickListener mClickListener;
// data is passed into the constructor
public Picassotest(Context context, String[] data) {
this.mInflater = LayoutInflater.from(context);
this.mData = data;
this.context = context;
}
// inflates the cell layout from xml when needed
#Override
#NonNull
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = mInflater.inflate(R.layout.images_list, parent, false);
return new ViewHolder(view);
}
// binds the data to the TextView in each cell
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
Picasso
.with(context)
.load(mData[position])
.fit() // to resize the image to imageView
.placeholder(R.drawable.loading_image) // load image
.transform(new PicassoRoundedTransformation(20, 0)) // Add radius to the images
.noFade()
.into(holder.mimageView);
}
// total number of cells
#Override
public int getItemCount() {
return mData.length;
}
// stores and recycles views as they are scrolled off screen
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
ImageView mimageView;
ViewHolder(View itemView) {
super(itemView);
mimageView = itemView.findViewById(R.id.list_image);
itemView.setOnClickListener(this);
}
#Override
public void onClick(View view) {
if (mClickListener != null) mClickListener.onItemClick(view, getAdapterPosition());
}
}
// convenience method for getting data at click position
public String getItem(int id) {
return mData[id];
}
// allows clicks events to be caught
public void setClickListener(ItemClickListener itemClickListener) {
this.mClickListener = itemClickListener;
}
// parent activity will implement this method to respond to click events
public interface ItemClickListener {
void onItemClick(View view, int position);
}
}
HomeImagesFragment "Fragment"
public class HomeImagesFragment extends Fragment {
private Picassotest adapter;
String[] chooseImages;
public HomeImagesFragment(String[] chooseImages) {
this.chooseImages = chooseImages;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View rootView = inflater.inflate(R.layout.images_fragment_home, container, false);
/* ArrayList for chooseImages */
chooseImages = new String[]{
"https://quotess.cc/wp-content/uploads/2020/01/4688.jpg",
"https://whatt.cc/wp-content/uploads/2018/07/4443.jpg",
"https://quotess.cc/wp-content/uploads/2020/01/4688.jpg",
};
/* make new object and find the view "GridView" */
RecyclerView recyclerView = rootView.findViewById(R.id.recyclerview_image_choose);
// Calculate the items and auto-fit it on the screen
int mNoOfColumns = Utility.calculateNoOfColumns(getActivity(), 140);
recyclerView.setLayoutManager(new GridLayoutManager(getActivity(), mNoOfColumns));
adapter = new Picassotest(getActivity(), chooseImages);
adapter.setClickListener(this);
recyclerView.setAdapter(adapter);
return rootView;
}
public void onItemClick(int position) {
// get the image
String image = chooseImages[position];
Intent intent = new Intent(getActivity(), PicassoImageDisplayWallpaperAdapter.class);
intent.putExtra("imageUrl", image);
getActivity().startActivity(intent);
}

You need to create an interface like below code
interface ItemClickListener{
public void onItemClick(int position);
}
You need to implements ItemClickListener in your HomeImagesFragment
SAMPLE CODE
public class HomeImagesFragment extends Fragment implements ItemClickListener{
private Picassotest adapter;
String[] chooseImages;
public HomeImagesFragment(String[] chooseImages) {
this.chooseImages = chooseImages;
}
#Override
public void onItemClick(int position) {
// you will clikcked item position here
String image = chooseImages[position];
Intent intent = new Intent(getActivity(), PicassoImageDisplayWallpaperAdapter.class);
intent.putExtra("imageUrl", image);
getActivity().startActivity(intent);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View rootView = inflater.inflate(R.layout.images_fragment_home, container, false);
/* ArrayList for chooseImages */
chooseImages = new String[]{
"https://quotess.cc/wp-content/uploads/2020/01/4688.jpg",
"https://whatt.cc/wp-content/uploads/2018/07/4443.jpg",
"https://quotess.cc/wp-content/uploads/2020/01/4688.jpg",
};
/* make new object and find the view "GridView" */
RecyclerView recyclerView = rootView.findViewById(R.id.recyclerview_image_choose);
// Calculate the items and auto-fit it on the screen
int mNoOfColumns = Utility.calculateNoOfColumns(getActivity(), 140);
recyclerView.setLayoutManager(new GridLayoutManager(getActivity(), mNoOfColumns));
adapter = new Picassotest(getActivity(), chooseImages);
adapter.setClickListener(this);
recyclerView.setAdapter(adapter);
return rootView;
}
public void onItemClick(int position) {
// get the image
String image = chooseImages[position];
Intent intent = new Intent(getActivity(), PicassoImageDisplayWallpaperAdapter.class);
intent.putExtra("imageUrl", image);
getActivity().startActivity(intent);
}

(Additional) Another way if you use Kotlin:
Sample Code
In Adapter class (Picassotest):
class Picassotest : RecyclerView.Adapter<Picassotest.ViewHolder>{
internal var itemClickListener: (Int) -> Unit = {}
inner class ViewHolder(itemView:View):RecyclerView.ViewHolder(itemView){
init{
itemView.setOnClickListener{
itemClickListener.invoke(adapterPosition)
}
}
}
}
In HomeImagesFragment:
class HomeImagesFragment{
adapter = new Picassotest(getActivity(), chooseImages)
adapter.itemClickListener = { position->
//TODO handle item on click here
}
}

Related

Replace Instead Of Adding Item To Arraylist

I building an app to practice in arraylist and recyclerView.
In the main activity I have "Add" button than I can add things to the arraylit to display in the recyclerView,However,the first time I add new line its working fine,but when I try to add another one,its replacing the first line I added with the new line.
I will be glad if you can point what am I doing wrong,Thank you.
Add Line Activity:
public void AddButton(View view){
if (imageUri != null && !mEditText.getText().toString().isEmpty()){
Intent intent = new Intent(AddCompany.this,MainActivity.class);
intent.putExtra("isAddNewCompany", true);
intent.putExtra("CompanyImage", imageUri.toString());
intent.putExtra("CompanyName", mEditText.getText().toString());
startActivity(intent);
}
}
MainActivity OnCreate with the views:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent intent = getIntent();
ArrayList<String> listTitle = new ArrayList<>();
ArrayList<String> listPicture = new ArrayList<>();
if (intent.getBooleanExtra("isAddNewCompany",false)){
String CompanyImage = intent.getStringExtra("CompanyImage");
String companyName = intent.getStringExtra("CompanyName");
listTitle.add(companyName);
listPicture.add(CompanyImage);
}
// set up the RecyclerView
RecyclerView recyclerView = findViewById(R.id.recyclerView);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
RecyclerAdapter adapter = new RecyclerAdapter(this,listPicture,listTitle);
adapter.setClickListener(new RecyclerAdapter.ItemClickListener() {
#Override
public void onItemClick(View view, int position) {
Log.e("Position Number - ", String.valueOf(position));
Toast.makeText(MainActivity.this, adapter.getItem(position), Toast.LENGTH_SHORT).show();
}
});
recyclerView.setAdapter(adapter);
}
RecyclerView Adapter:
public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.ViewHolder> {
private final ArrayList<String> mData;
private final ArrayList<String> mImageView;
private final LayoutInflater mInflater;
private ItemClickListener mClickListener;
// data is passed into the constructor
RecyclerAdapter(Context context, ArrayList<String> imageView, ArrayList<String> data) {
this.mInflater = LayoutInflater.from(context);
this.mData = data;
this.mImageView = imageView;
}
// inflates the row layout from xml when needed
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = mInflater.inflate(R.layout.recyclerview_row, parent, false);
return new ViewHolder(view);
}
// binds the data to the TextView in each row
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
String animal = mData.get(position);
String picture = mImageView.get(position);
Picasso.get().load(picture).into(holder.myImageView);
holder.myTextView.setText(animal);
}
// total number of rows
#Override
public int getItemCount() {
return mData.size();
}
// stores and recycles views as they are scrolled off screen
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
TextView myTextView;
ImageView myImageView;
ViewHolder(View itemView) {
super(itemView);
myTextView = itemView.findViewById(R.id.tvAnimalName);
myImageView = itemView.findViewById(R.id.imageView);
itemView.setOnClickListener(this);
}
#Override
public void onClick(View view) {
if (mClickListener != null) mClickListener.onItemClick(view, getAdapterPosition());
}
}
// convenience method for getting data at click position
String getItem(int id) {
return mData.get(id);
}
// allows clicks events to be caught
void setClickListener(ItemClickListener itemClickListener) {
this.mClickListener = itemClickListener;
}
// parent activity will implement this method to respond to click events
public interface ItemClickListener {
void onItemClick(View view, int position);
}
}
When you start activity ,every time new list instance will be created that's why you got only one value.if you want already added value, use same list instance.
List<String> listTitle;
List<String> listPicture;
public List<String> getLisPictureInstance(){
if(listPicture ==null)
listPicture = new ArrayList<>();
return listPicture ;
}
public List<String> getListTitleInstance(){
if(listTitle ==null)
listTitle = new ArrayList<>()
return listTitle ;
}
if (intent.getBooleanExtra("isAddNewCompany",false)){
String CompanyImage = intent.getStringExtra("CompanyImage");
String companyName = intent.getStringExtra("CompanyName");
getListTitleInstance().add(companyName);
getLisPictureInstance().add(CompanyImage);
}

Onclick to open activity from adapter of fragment not working

I am trying to run some code I got from some online tutorial of writing a fragment with a recyclerview in it but I am experiencing some difficulty in opening an activity from the onclick event. My adapter is below
public class ItemAdapter extends RecyclerView.Adapter<ItemAdapter.MyViewHolder> {
private final ArrayList<ItemModel> mArrayList;
private Context mcontext;
ItemAdapter(ArrayList<ItemModel> mArrayList) {
this.mArrayList = mArrayList;
}
#NonNull
#Override
public MyViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
mcontext = parent.getContext();
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.listing_item, parent, false);
return new MyViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull MyViewHolder holder, int position) {
//Glide.with(mcontext).load(mArrayList.get(position).getImage()).into(holder.item_image);
holder.item_name.setText(mArrayList.get(position).getTitle());
holder.item_description.setText(mArrayList.get(position).getDescription());
holder.item_tags.setText(mArrayList.get(position).getTags());
Log.d("MyAdapter", "position: " + position);
}
#Override
public int getItemCount() {
return mArrayList.size();
}
class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
private final ImageView item_image;
private final TextView item_name;
private final TextView item_description;
private final TextView item_tags;
private final LinearLayout cardViewLayout;
MyViewHolder(View view) {
super(view);
item_image = view.findViewById(R.id.item_image);
item_name = view.findViewById(R.id.item_name);
item_description = view.findViewById(R.id.item_description);
item_tags = view.findViewById(R.id.item_tags);
cardViewLayout = view.findViewById(R.id.cardViewLayout);
cardViewLayout.setOnClickListener(this);
}
#Override
public void onClick(View view) {
Intent intent = new Intent(mcontext, ItemView.class);
mcontext.startActivity(intent);
}
}
}
When I run the code nothing happens when i click on a item and neither do I see any error in the logcat
Instead, try like this,
ItemAdapter(Context context, ArrayList<ItemModel> mArrayList) {
this.mArrayList = mArrayList;
this.mContext = context;
}
#NonNull
#Override
public MyViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.listing_item, parent, false);
return new MyViewHolder(view);
}
In your fragment, while setting adapter
ItemAdapter itemAdapter=new ItemAdapter(getActivity(),itemList);
You can have a listener sent from the fragment to adapter. Instead of trying to start an activity from the adapter, you can send it back to the fragment to open the activity.
1. Define an interface
public interface MyAdapterListener {
void openActivity(/*any values to be sent*/);
}
2. The fragment should implement MyAdapterListener
3. send the listener object to an adapter in a constructor
ItemAdapter(ArrayList<ItemModel> mArrayList, MyAdapterListener listener) {..
mListener = listener;
}
4. On Adapter - View Holder: in onClick() return to fragment
public void onClick(View view) {
mListener.openActivity(/*any values to be sent*/);
}
I was of the idea that on your application of the adapter in some activity you simply call the activity on the setOnItemClickListener of the adapter
private void loadItemsData() {
RecyclerView itemsRecyclerView = view.findViewById(R.id.posts_recycler_view);
itemsRecyclerView.setHasFixedSize(true);
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getActivity(), LinearLayoutManager.VERTICAL, false);
itemsRecyclerView.setLayoutManager(layoutManager);
ItemAdapter myadapter = new ItemAdapter(new ArrayList<MyItem>(), getContext());
myadapter.setOnItemClickListener(new ItemAdapter.OnItemClickListener() {
#Override
public void onItemClick(View view, PostItems items) {
ViewItem.passingIntent(getActivity(), items.postid);
}
});
itemsRecyclerView.setAdapter(ListAdapter );
}
then once done that you come to the receiver activity and make way to get the variables being passed on to it
public static void passingIntent(Activity activity, Integer postid){
Intent intent = new Intent(activity, ViewItem.class);
intent.putExtra(MY_ITEM, postid);
activity.startActivity(intent);
}
I have used this approach in one of my apps lately
Try setting your click listener in onBindViewHolder like below
#Override
public void onBindViewHolder(#NonNull MyViewHolder holder, int position) {
//Glide.with(mcontext).load(mArrayList.get(position).getImage()).into(holder.item_image);
holder.item_name.setText(mArrayList.get(position).getTitle());
holder.item_description.setText(mArrayList.get(position).getDescription());
holder.item_tags.setText(mArrayList.get(position).getTags());
holder.setOnClickListener(this) // put this line
Log.d("MyAdapter", "position: " + position);
}
Then of course you will override onClick in adapter rather than viewholder

notifyDataSetChanged didn't work on adapter

I have activity and 3 fragments in ViewPage.
In last fragment I have recycleView, if i move to this page i want to refresh recycle view and its work only if I call:
mAdapter = new LocationAdapter(mListener.loadLocationList());
mRecyclerView.setAdapter(mAdapter);
This should work aswell after call notifyDataSetChanged but didn't.
What can we wrong ?
in last fragment:
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
mRecyclerView.setHasFixedSize(true);
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getActivity());
mRecyclerView.setLayoutManager(mLayoutManager);
mAdapter = new LocationAdapter(mListener.loadLocationList());
mRecyclerView.setAdapter(mAdapter);
}
private class HistoryFragmentReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (HISTORY_FRAGMENT_SELECTED.equals(intent.getAction())){
updateLocationList();
}
}
}
private void updateLocationList() {
mAdapter = new LocationAdapter(mListener.loadLocationList());
mRecyclerView.setAdapter(mAdapter);
}
i wanted notifydatasetchanged instead of 2 lines in updatelocationlist()
LocationAdapter:
public class LocationAdapter extends RecyclerView.Adapter<LocationAdapter.LocationViewHolder> {
private LinkedList<LatLng> mDataset;
public static class LocationViewHolder extends RecyclerView.ViewHolder {
// each data item is just a string in this case
public View mTextView;
public LocationViewHolder(View v) {
super(v);
mTextView = v;
}
}
public LocationAdapter(LinkedList<LatLng> myDataset) {
mDataset = myDataset;
}
#NonNull
#Override
public LocationAdapter.LocationViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int i) {
LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
View v = layoutInflater.inflate(R.layout.my_text_view, parent, false);
LocationViewHolder vh = new LocationViewHolder(v);
return vh;
}
#Override
public void onBindViewHolder(#NonNull LocationAdapter.LocationViewHolder locationViewHolder, int position) {
TextView textView = locationViewHolder.mTextView.findViewById(R.id.textView3);
textView.setText(String.valueOf(mDataset.get(position)));
}
#Override
public int getItemCount() {
return mDataset.size();
}
}
The problem is you set data only in your adapter's constructor.
When you call notifyDataSetChanged you can't expect that your adapter will take new data magically. You have to set it by yourself.
My suggestion would be add a setData method in your adapter and call it before notifyDataSetChanged.
Something like this in your adapter:
public void setData(LinkedList<LatLng> myDataset) {
mDataset = myDataset
}
and in your caller:
private void updateLocationList() {
mAdapter.setData(mListener.loadLocationList());
mAdapter.notifyDataSetChanged();
}

add Onclick on adapter for each item to open new different activity

I have Adapter in my project and few fragments where I populate fragments with celebrity names and date of birth as it is given in below image
I will like to call a different url to launch for each item
For First Item
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.stackoverflow.com")));
For Second Item
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.youtube.com")));
and so on
Below is my Adapter Class
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
private List<Model> mDataset;
private ImageLoader mImageLoader;
// Provide a reference to the views for each data item
// Complex data items may need more than one view per item, and
// you provide access to all the views for a data item in a view holder
public static class ViewHolder extends RecyclerView.ViewHolder {
// each data item is just a string in this case
public TextView nameText;
public TextView phoneText;
public NetworkImageView image;
#SuppressLint("WrongViewCast")
public ViewHolder(View v) {
super(v);
nameText = v.findViewById(R.id.name_text);
phoneText = v.findViewById(R.id.phone_text);
image = v.findViewById(R.id.imgAvatar);
image.setDefaultImageResId(R.mipmap.ic_launcher);
v.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(v.getContext(),"Position: "+getAdapterPosition(), Toast.LENGTH_SHORT).show();
}
});
}
}
// Provide a suitable constructor (depends on the kind of dataset)
public MyAdapter(List<Model> myDataset, Context mCOntext) {
Log.d("TEST",myDataset.get(0).getName());
mDataset = myDataset;
mImageLoader = MySingleton.getInstance(mCOntext).getImageLoader();
}
// Create new views (invoked by the layout manager)
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
// create a new view
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.card_view, parent, false);
// set the view's size, margins, paddings and layout parameters
ViewHolder vh = new ViewHolder(v);
return vh;
}
public interface ItemClickListener {
void onItemClick(View view, int position);
}
// Replace the contents of a view (invoked by the layout manager)
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
// - get element from your dataset at this position
// - replace the contents of the view with that element
//holder.mTextView.setText(mDataset.get(position).getName());
Log.d("TEST","Printing Names onBindView Holder"+mDataset.get(position).getName());
holder.nameText.setText(mDataset.get(position).getName());
holder.phoneText.setText(mDataset.get(position).getPhone());
holder.image.setImageUrl(mDataset.get(position).getImage(),mImageLoader);
}
// Return the size of your dataset (invoked by the layout manager)
#Override
public int getItemCount() {
return mDataset.size();
}
}
and my Fragment is
public class english extends Fragment implements Response.Listener , Response.ErrorListener {
View view;
RecyclerView mRecyclerView;
private RecyclerView.LayoutManager mLayoutManager;
private Context context;
private List<Model> contactList = new ArrayList<>();
private String url ="https://api.androidhive.info/json/contacts.json";
Button btn;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
view = inflater.inflate(R.layout.home_fragment,container,false);
context = getContext();
mLayoutManager = new GridLayoutManager(context,2);
mRecyclerView = (RecyclerView)view.findViewById(R.id.my_recycler_view);
mRecyclerView.setLayoutManager(mLayoutManager);
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setLayoutManager(mLayoutManager);
getContactList();
return view;
}
private void getContactList(){
Log.d("TEST","Getting Contact list");
Controller.getInstance(context).makeNetworkCalls(Request.Method.GET,url,this,this);
}
#Override
public void onErrorResponse(VolleyError error) {
Log.e(TAG, "Error: " + error.getMessage());
Toast.makeText(context, "Error: " + error.getMessage(), Toast.LENGTH_SHORT).show();
}
#Override
public void onResponse(Object response) {
Log.d("TEST","Got The response" +response);
if (response == null) {
Toast.makeText(context, "Couldn't fetch the contacts! Pleas try again.", Toast.LENGTH_LONG).show();
return;
}
List<Model> items = new Gson().fromJson(response.toString(), new TypeToken<List<Model>>(){}.getType());
contactList.addAll(items);
MyAdapter rcAdapter = new MyAdapter(contactList,context);
mRecyclerView.setAdapter(rcAdapter);
}
}
Please Help.
its Simple
First Create URL Array
in The Adapter Classs
ArrayList<String> UrlsToTran=new ArrayList<>();
in The Adapter Class Constructor
MyAdapter(Context mContext)
{
//Assing Context
//Assign The Urls
UrlsToTran.add("www.stackoverflow.com");
UrlsToTran.add("www.facebook.com");
//And Add More Values As U need
}
Then Add OnClick Listener
public void onBindViewHolder(ViewHolder holder, int position) {
// - get element from your dataset at this position
// - replace the contents of the view with that element
//holder.mTextView.setText(mDataset.get(position).getName());
Log.d("TEST","Printing Names onBindView
Holder"+mDataset.get(position).getName());
holder.nameText.setText(mDataset.get(position).getName());
holder.phoneText.setText(mDataset.get(position).getPhone());
holder.image.setImageUrl(mDataset.get(position).getImage(),mImageLoader);
holder.image.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v)
{
context.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(UrlsToTran.get(position).toString())));
}
});
}
First, for every item in your adapter create an OnClickListener like this:
holder.image.setOnClickListener(v->{
});
Now Create an interface between the adapter and the fragment/activity that shows the list
public interface ModelListener {
void onModelClicked(Model model);
}
In your activity/fragment listen to an item click and send the intent
new ModelListener(){
public void onModelClicked(Model model){
startActivity(new Intent(.., model.getUrl()));
}
}

Handling onClicks of RecyclerView inside a Fragment

I am trying to implement RecyclerView inside a Fragment. I have designed a CustomAdapter(StateAdapter) class to load the contents of RecyclerView and an interface StateAdapterOnClickHandler to handle onClicks of the items inside RecyclerView but clicking on item doesn't work.
Here's my HomeFragment.java which extends Fragment. I am unable to figure out how to initialize the StateAdapterOnClickHandler and where to call its method onItemClick()
public class HomeFragment extends Fragment implements StateAdapter.StateAdapterOnClickHandler {
private View homeFragment;
private RecyclerView recyclerView;
private StateAdapter stateAdapter;
private List<String> states;
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
public static HomeFragment newInstance() {
HomeFragment homeFragment = new HomeFragment();
return homeFragment;
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
homeFragment = inflater.inflate(R.layout.fragment_home,container,false);
recyclerView = homeFragment.findViewById(R.id.recyclerview_states);
states = Arrays.asList(getResources().getStringArray(R.array.india_states));
LinearLayoutManager layoutManager = new LinearLayoutManager(container.getContext(),LinearLayoutManager.VERTICAL,false);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setHasFixedSize(true);
stateAdapter = new StateAdapter();
stateAdapter.setStateNames(states);
recyclerView.setAdapter(stateAdapter);
return homeFragment;
}
#Override
public void onItemClick(String state) {
Intent intent = new Intent(getActivity(),DetailActivity.class);
intent.putExtra("State",state);
startActivity(intent);
}
}
Here's my StateAdapter class
public class StateAdapter extends RecyclerView.Adapter<StateAdapter.StateViewHolder> {
private List<String> stateNames;
private final StateAdapterOnClickHandler stateAdapterOnClickHandler;
StateAdapter(StateAdapterOnClickHandler stateAdapterOnClickHandler){
this.stateAdapterOnClickHandler = stateAdapterOnClickHandler;
}
public interface StateAdapterOnClickHandler {
void onItemClick(String state);
}
#Override
public StateAdapter.StateViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
Context context = parent.getContext();
int idForListItem = R.layout.state_layout;
LayoutInflater inflater = LayoutInflater.from(context);
View view = inflater.inflate(idForListItem,parent,false);
return new StateViewHolder(view);
}
#Override
public void onBindViewHolder(StateAdapter.StateViewHolder holder, int position) {
String stateName = stateNames.get(position);
holder.mTextView.setText(stateName);
}
#Override
public int getItemCount() {
if(stateNames == null) return 0;
return stateNames.size();
}
public class StateViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
public final TextView mTextView;
public StateViewHolder(View itemView) {
super(itemView);
mTextView = (TextView) itemView.findViewById(R.id.tv_state_name);
itemView.setOnClickListener(this);
}
#Override
public void onClick(View v) {
int clickedPostion = getAdapterPosition();
String state = stateNames.get(clickedPostion);
stateAdapterOnClickHandler.onItemClick(state);
}
}
public void setStateNames(List<String> states) {
stateNames = states;
notifyDataSetChanged();
}
}
Please, tell me what's wrong with the code while handling the clicks. I am new to Android Programming and this is first time I am working with Fragments. Thanks for helping.

Categories