Toast message onClick NOT SHOWING (RecycleView) - android

Im trying show a toast msg when clicked on a item from my RecycleView, Ive tried many examples,
but its not giving me anything. Can somebody give me a different example that i can follow, at the end i wanna set the onClick to show a new fragment. If I can get an example on that, it will be great.
Im using this code:
public class MovieAdapter extends RecyclerView.Adapter<MovieAdapter.ViewHolder> {
private List<Movie> movies;
private int card_layout;
private Context mContext;
public MovieAdapter(List<Movie> movies, int card_layout, Context context) {
this.movies = movies;
this.card_layout = card_layout;
this.mContext = context;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
final View itemView = LayoutInflater.from(viewGroup.getContext()).inflate(card_layout, viewGroup, false);
return new ViewHolder(itemView);
}
#Override
public void onBindViewHolder(ViewHolder viewHolder, int i) {
final Movie movie = movies.get(i);
viewHolder.movieImage.setImageDrawable(mContext.getDrawable(movie.getImageResourceId(mContext)));
viewHolder.movieName.setText(movie.mName);
viewHolder.currentMovie = movie;
}
#Override
public int getItemCount(){
return movies.size();
}
public static class ViewHolder extends RecyclerView.ViewHolder {
public TextView movieName;
public ImageView movieImage;
public Movie currentMovie;
public ViewHolder( View itemView) {
super(itemView);
movieName = (TextView) itemView.findViewById(R.id.movieName);
movieImage = (ImageView)itemView.findViewById(R.id.movieImage);
itemView.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View itemView){
Toast.makeText(itemView.getContext(),currentMovie.mName,Toast.LENGTH_SHORT ).show();
}
});
}
}
}
Do I have to implement something in my MainActivity as well?
and please dont get mad with me, Im just a starting with all this. All your help will be appriciated. thanks

Layout is not clickable by default. to make clickable add setClickable to true :
View itemView = LayoutInflater.from(viewGroup.getContext()).inflate(
card_layout, viewGroup, false);
itemView.setClickable(true);
itemView.setFocusableInTouchMode(true);

After wasting an hour of time, I found the most appropriate and simplest solution to this problem:
Try this, it will definitely work.No matters whether cards are used in grids or not.
RecyclerView Adapter:
ProductCardRecyclerViewAdapter.java
public class ProductCardRecyclerViewAdapter extends RecyclerView.Adapter<ProductCardViewHolder> {
public final String TAG=getClass().getSimpleName();
Context context;
private List<ProductEntry> productList;
private Integer[] cardImages;
String[] cardTitle;
String[] cardSubtitle;
public ProductCardRecyclerViewAdapter(Context context, Integer[] imageList, String[] cardTitle, String[] cardSubtitle) {
this.cardImages = imageList;
this.cardTitle = cardTitle;
this.cardSubtitle = cardSubtitle;
this.context = context;
}
#NonNull
#Override
public ProductCardViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View layoutView = LayoutInflater.from(parent.getContext()).inflate(R.layout.product_card, parent, false);
return new ProductCardViewHolder(layoutView);
}
#Override
public void onBindViewHolder(#NonNull ProductCardViewHolder holder, int position) {
// TODO: Put Recycler ViewHolder Cards binding code here in MDC-102
holder.imgCard.setImageResource(cardImages[position]);
holder.productTitle.setText(cardTitle[position]);
holder.productPrice.setText(cardSubtitle[position]);
holder.productCard.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.d(TAG, "onClick: Material Card clicked "+cardTitle[position]+" : "+context.getClass());
//TODO: Perform card clicked working
Context c = v.getContext();
Toast.makeText(c, cardTitle[position], Toast.LENGTH_SHORT).show();
}
});
}
#Override
public int getItemCount() {
return cardImages.length;
}
}
RecyclerViewHolder
ProductCardViewHolder.java
public class ProductCardViewHolder extends RecyclerView.ViewHolder {
CardView productCard;
ImageView imgCard;
public TextView productTitle;
public TextView productPrice;
public ProductCardViewHolder(#NonNull View itemView) {
super(itemView);
imgCard = itemView.findViewById(R.id.product_image);
productTitle = itemView.findViewById(R.id.product_title);
productPrice = itemView.findViewById(R.id.product_price);
productCard=itemView.findViewById(R.id.cardofproducts);
// TODO: Find and store views from itemView
}
}
Hope, it will help a lot.

Related

Merging two mostly similar adapters for recyclerview

I have two adapters that adapt to a recycler view depending on different conditions. I want to merge them.
The issue is that I created first in the same file as the activity where it is being used and the other is in a new file.
Take it as follows:
DefaultAdapter is in the file where it is being used.
AutoCompleteAdapter is also used in the same file but is declared in other file.
I want to get rid of Default Adapter and get its funtions into AutoCompleteAdapter.
There are some issues to it: I can no more use the ParentFiles' variables.
Below is the adapter that I want to get rid of.
public class DefaultAdapter extends RecyclerView.Adapter<DefaultAdapter.ViewHolder> {
private Context context;
private AdapterView.OnItemClickListener onItemClickListener;
List<String> searchList;
#NonNull #Override
public DefaultAdapter.ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = (View) LayoutInflater.from(parent.getContext())
.inflate(android.R.layout.simple_list_item_1, null);
ViewHolder holder = new ViewHolder(view);
return holder;
}
#Override public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
holder.txt.setText(
Html.fromHtml(getItem(position)).toString());///need to get rid of this error
}
#Override public int getItemCount() {
return searchList.size();
}
#NonNull public String getItem(int position) {
return searchList.get(position);
}
public class ViewHolder extends RecyclerView.ViewHolder {
TextView txt;
public ViewHolder(#NonNull View itemView) {
super(itemView);
txt = itemView.findViewById(android.R.id.text1);
itemView.setOnClickListener(new View.OnClickListener() {
#Override public void onClick(View v) {
String title = txt.getText().toString();
searchPresenter.saveSearch(title);
}
});
itemView.setOnLongClickListener(new View.OnLongClickListener() {
#Override public boolean onLongClick(View v) {
String searched = txt.getText().toString();
deleteSpecificSearchDialog(searched);
return true;
}
});
}
}
}
Please take note of the SearchPresenter. This is a variable in the parent file, that is causing major issues. Autocomplete adapter doesn't have to use it, but default have to.
This is the adapter I want it to merge into
public class AutoCompleteAdapter extends RecyclerView.Adapter<AutoCompleteAdapter.ViewHolder>
implements Filterable {
#Inject JNIKiwix currentJNIReader;
#Inject SharedPreferenceUtil sharedPreferenceUtil;
#Inject ZimReaderContainer zimReaderContainer;
private List<String> data;
private KiwixFilter kiwifilter;
private Context context;
public AutoCompleteAdapter(Context context) {
this.context = context;
data = new ArrayList<>();
kiwifilter = new KiwixFilter();
setupDagger();
}
private void setupDagger() {
CoreApp.getCoreComponent().inject(this);
}
#NonNull #Override public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = (View) LayoutInflater.from(parent.getContext())
.inflate(android.R.layout.simple_list_item_1, null);
ViewHolder holder = new ViewHolder(view);
return holder;
}
#Override public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
holder.title.setText(Html.fromHtml(getItem(position)).toString());
}
#Override
public String getItem(int index) {
String a = data.get(index);
if (a.endsWith(".html")) {
String trim = a.substring(2);
trim = trim.substring(0, trim.length() - 5);
return trim.replace("_", " ");
} else {
return a;
}
}
#Override public int getItemCount() {
return data.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
TextView title;
public ViewHolder(#NonNull View itemView) {
super(itemView);
title = itemView.findViewById(android.R.id.text1);
}
}
}
...
Note the similarity between the two, they are almost similar, autocompleteadapter is like superset of defaultadapter.
I just want to get rid of the default adapter.
Note: I have chopped off some other things from autocompeleteadapter, I think they are not required for the problem.
Noob here...
Thanks

The current post of Recycle View can not transfer correct data to another activity

I use recycle view to show posts of users. I create a button on each post of Recycle view. When user click on this button, every data of this post will be transferred to another activity. My problem is that when I click on the button of a post, the tranferred data is not the data of this post. For example, when I click the button of post 1, the data of post 2 is transferred to new activity instead of the data of post 1. Can anyone help me to solve this problem? Thank you in advance
Below is my Recycle View adapter:
public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.ImageViewHolder> {
private Context context;
private List<Upload> uploads;
Upload uploadCurrent;
private String userEmail, locationName, locationType, locationAddress,
userComment, downloadUrl, userLatitude, userLongitude;
public CustomAdapter(Context context, List<Upload> uploads) {
this.context = context;
this.uploads = uploads;
}
#NonNull
#Override
public ImageViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(context).inflate(R.layout.custom_view, parent, false);
return new ImageViewHolder(v);
}
#Override
public void onBindViewHolder(#NonNull ImageViewHolder holder, int position) {
uploadCurrent = this.uploads.get(position);
userEmail = uploadCurrent.getUserEmail();
locationName = uploadCurrent.getLocationName();
locationType = uploadCurrent.getLocationType();
locationAddress = uploadCurrent.getLocationAddress();
userComment = uploadCurrent.getUserComment();
downloadUrl = uploadCurrent.getDownloadUrl();
userLatitude = uploadCurrent.getUserLatitude();
userLongitude = uploadCurrent.getUserLongitude();
holder.emailCustom.setText(userEmail);
holder.nameCustom.setText(locationName);
holder.commentCustom.setText("Review: " + userComment );
holder.typeCustom.setText("Type: "+ locationType );
holder.addressCustom.setText("Address: " + locationAddress);
Picasso.get().load(downloadUrl).fit().centerCrop().into(holder.imageCustom);
//handle button
holder.saveCustomButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(context, SaveActivity.class);
intent.putExtra("adap_name", locationName);
intent.putExtra("adap_address", locationAddress);
intent.putExtra("adap_type", locationType);
intent.putExtra("adap_comment", userComment);
intent.putExtra("adap_image", downloadUrl);
intent.putExtra("adap_latitude", userLatitude);
intent.putExtra("adap_longitude", userLongitude);
context.startActivity(intent);
}
});
}
#Override
public int getItemCount() {
return this.uploads.size(); //how many items in our uploads list
}
public class ImageViewHolder extends RecyclerView.ViewHolder {
public TextView emailCustom;
public TextView nameCustom;
public TextView commentCustom;
public TextView typeCustom;
public TextView addressCustom;
public ImageView imageCustom;
public Button saveCustomButton;
public ImageViewHolder(#NonNull View itemView) {
super(itemView);
emailCustom = itemView.findViewById(R.id.emailCustom);
nameCustom = itemView.findViewById(R.id.nameCustom);
typeCustom = itemView.findViewById(R.id.typeCustom);
addressCustom = itemView.findViewById(R.id.addressCustom);
commentCustom = itemView.findViewById(R.id.commentCustom);
imageCustom = itemView.findViewById(R.id.imageCustom);
saveCustomButton = itemView.findViewById(R.id.saveCustomButton);
}
}
}
Just put your clicklistener from onBindViewHolder method to ImageViewHolder class and make use of adapterposition method:
holder.saveCustomButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
uploadCurrent = uploads.get(getAdapterPosition());
Intent intent = new Intent(context, SaveActivity.class);
intent.putExtra("adap_name", uploadCurrent.getlocationName());
context.startActivity(intent);
}
});
Repeat same for getting other attributes.
Cool! In your adapter, just do the below things
Kotlin
override fun getItemId(position: Int): Long {
return position.toLong()}
override fun getItemViewType(position: Int): Int {
return position}
Java
#Override
public Long getItemId(int position) {
return position;
}
#Override
public int getItemViewType(int position) {
return position;
}
Does it crash when you click the button on the last item in the recycler view? If so then it could be that your index is out of bound.
you are initialize string globally so they are taking last value from list initialize them in ImageViewHolder that will work for you
public class ImageViewHolder extends RecyclerView.ViewHolder {
public TextView emailCustom;
public TextView nameCustom;
public TextView commentCustom;
public TextView typeCustom;
public TextView addressCustom;
String userEmail, locationName, locationType, locationAddress,
userComment, downloadUrl, userLatitude, userLongitude;

Android RecyclerView onClick in different Activity

Everything works well and my onClick in my recyclerView is working in getting the positions of my items, but what my design calls for is to be able to click an item of the recyclerView and open up a new activity (as a popover or pop up). I can achieve this but my problems comes with the information I need to display on the popover. The information comes like this inside the activity (inside a Firebase value call)
attributeList.removeAll(attributeList);
for (DataSnapshot child : dataSnapshot.child("Attribute").getChildren()){
Attribute attribute = child.getValue(Attribute.class);
attribute_list newAttributeList = new attribute_list( attribute.Name + ": " + attribute.Value);
attributeList.add(newAttributeList);
}
attributeAdapter = new attribute_list_adapter(attributeList, getContext());
recyclerAttribute.setAdapter(attributeAdapter);
This works perfectly for displaying the information, but there's more then just a "value" and a "name" associated with the click.
Basically when I select an item, I need to get the position of the item clicked (which I have) and compare it to the position inside attributeList so I can call a Firebase call (or pass the data somehow) to the popover to display values from the "Attribute" class (such as Name, Value, Description, and another list (recyclerView).
My recyclerView:
public class attribute_list_adapter extends RecyclerView.Adapter<attribute_list_adapter.ViewHolder> {
private List<attribute_list> listItems;
private Context context;
public attribute_list_adapter(List<attribute_list> listItems, Context context) {
this.listItems = listItems;
this.context = context;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.attribute_list, parent, false);
return new ViewHolder(v);
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
attribute_list listItem = listItems.get(position);
holder.txtTitle.setText(listItem.getTxtTitle());
}
#Override
public int getItemCount() {
return listItems.size();
}
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
public TextView txtTitle;
public ViewHolder(View itemView) {
super(itemView);
itemView.setOnClickListener(this);
txtTitle = (TextView) itemView.findViewById(R.id.txtTitle);
}
#Override
public void onClick(View v) {
}
}
}
This is example:
public class attribute_list_adapter extends RecyclerView.Adapter<attribute_list_adapter.ViewHolder> {
private List<attribute_list> listItems;
private Context context;
public attribute_list_adapter(List<attribute_list> listItems, Context context) {
this.listItems = listItems;
this.context = context;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.attribute_list, parent, false);
return new ViewHolder(v);
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.itemView.setOnClickListener(new View.onClickListener() {
#Override
public void onClick(View v) {
onItemClickListener.onItemClick(position);
}
});
}
#Override
public int getItemCount() {
return listItems.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
TextView txtberita;
ImageView imgberita;
TextView txtnama;
public ViewHolder(View itemView) {
super(itemView);
txtnama = (TextView) itemView.findViewById(R.id.txtnama);
txtberita = (TextView) itemView.findViewById(R.id.txtberita);
imgberita = (ImageView) itemView.findViewById(R.id.imgberita);
}
}
public void setOnItemClickListener(OnItemClickListener onItemClickListener){
this.onItemClickListener = onItemClickListener;
}
OnItemClickListener onItemClickListener;
public interface OnItemClickListener{
void onItemClick(int position);
}
}
your Activity. in Oncreate()
public class TestActivity extends AppCompatActivity implements attribute_list_adapter.OnItemClickListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
attribute_list_adapter adapter = new attribute_list_adapter(listItems, this);
adapter.setOnItemClickListener(this);
}
#Override
public void onItemClick(int position) {
// code here
}
}
Create an interface something like
public interface OnSingleItemClickListener{
void onSingleItemClick(int position);
}
Then implement it on your ViewHolder like this
public class ViewHolder extends RecyclerView.ViewHolder implements OnSingleItemClickListener {
public ViewHolder(View itemView) {
super(itemView);
}
#Override
void onSingleItemClick(int position){
if(listItems.get(position) == listItems.get(getAdapterPosition)){
// TODO do something here
}
}
now on your OnBindViewHolder inside your adapter you must do this.
holder.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View view) {
holder.onSingleItemClick(position);
}
}):

One RecyclerAdapter for two activity

I make app with a couple of different categories of pictures. I want to display those pictures with RecyclerView.
I want to display button as a image when I clicked button before.
Can I make it in one adapter? Now I have two adapters, that code is as follow:
public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.ViewHolder> {
private int[] images = {
R.drawable.imageA1, .... R.drawable.imageA10
};
private int[] images2 = {
R.drawable.imageB1, .... R.drawable.imageB10
};
class ViewHolder extends RecyclerView.ViewHolder{
public int currentItem;
public ImageView itemImage, itemImage2;
public TextView itemTitle;
public ViewHolder(View itemView) {
super(itemView);
itemImage = (ImageView)itemView.findViewById(R.id.imageView);
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
View v = LayoutInflater.from(viewGroup.getContext())
.inflate(R.layout.article_layout, viewGroup, false);
ViewHolder viewHolder = new ViewHolder(v);
return viewHolder;
}
#Override
public void onBindViewHolder(ViewHolder viewHolder, int i) {
viewHolder.itemImage.setImageResource(images[i]);
}
#Override
public int getItemCount() {
return images.length;
}
}
You can set method in adapter that you will call when users clicks button:
// for button A
public void setImages() {
this.showImages = true;
}
// for button B
public void setImages2() {
this.showImages = false;
}
Then modify your on bind method to bind appropriate images:
#Override
public void onBindViewHolder(ViewHolder viewHolder, int i) {
if (this.showImages)
viewHolder.itemImage.setImageResource(images[i]);
else
viewHolder.itemImage.setImageResource(images2[i]);
}
You need to pass images array dynamically to your adapter as below
private int[] images = {
R.drawable.imageA1, .... R.drawable.imageA10
};
private int[] images2 = {
R.drawable.imageB1, .... R.drawable.imageB10
};
on click of button A
RecyclerAdapter myAdapter = new RecyclerAdapter(images)
yourRecyclerview.setAdapter(myAdapter )
on click of button B
RecyclerAdapter myAdapter = new RecyclerAdapter(images2)
yourRecyclerview.setAdapter(myAdapter )
change in your adapter as following
public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.ViewHolder> {
private int[] images = new int[];
public RecyclerAdapter(int[] imgs){
images = imgs;
}
class ViewHolder extends RecyclerView.ViewHolder{
public int currentItem;
public ImageView itemImage, itemImage2;
public TextView itemTitle;
public ViewHolder(View itemView) {
super(itemView);
itemImage = (ImageView)itemView.findViewById(R.id.imageView);
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
View v = LayoutInflater.from(viewGroup.getContext())
.inflate(R.layout.article_layout, viewGroup, false);
ViewHolder viewHolder = new ViewHolder(v);
return viewHolder;
}
#Override
public void onBindViewHolder(ViewHolder viewHolder, int i) {
viewHolder.itemImage.setImageResource(images[i]);
}
#Override
public int getItemCount() {
return images.length;
}
}
Yes possible. make constructor in adpater like that:
public RecyclerAdapter(Context context,int[] images)
{
this.diff_images=images;
this.context=context;
}
the diff_images is also int array in adapter class.
and make images array in your activity class. when you press button one then pass image1 array in adpater and if when press button2 then pass image2 array (if your want to show same view for both cases and if you want to show different view for both images)
if your adapter already set like:
recycleViewAdapter = new RecyclerAdapter(this, imageArray);
recyclerView.setAdapter(recycleViewAdapter);
then you can also make one more method in adapter class and only notify adapter for update image
public void setNewImageList(Context context, int[] imageArray) {
this.context = context;
this.diff_images = imageArray;
notifyDataSetChanged();
}
try this.

Selected image in recyclerview is get unselected upon scroll

In my recyclerview has one imageview and textview. I'm changing image of ImageView onn onClickListener. Now the problem is if i click on image of position 3 and scroll down... image of position 8 is also changed and again if i scroll up...image of position 2 is changed.
public class PortraitListviewAdapter extends RecyclerView.Adapter<PortraitListviewAdapter.ViewHolder> {
Context context;
static List<PortraitParentListAdapterBean> list;
static List<String> selectedPosition ;
public PortraitListviewAdapter(Context context, List<PortraitParentListAdapterBean> list) {
this.context = context;
this.list = list;
selectedPosition = new ArrayList<>();
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.listview_parent_portrait, parent, false);
return new ViewHolder(itemView);
}
#Override
public void onBindViewHolder(final ViewHolder holder, final int position) {
PortraitParentListAdapterBean portBean = list.get(position);
Log.i("pos",position+"");
holder.parentHeading.setText(portBean.getHeading());
if (selectedPosition.contains(list.get(position).getHeading())){
holder.parentImage.setImageResource(R.drawable.sad);
}
}
#Override
public int getItemCount() {
return list.size();
}
static class ViewHolder extends RecyclerView.ViewHolder {
protected TextView parentHeading;
protected ImageView parentImage;
public ViewHolder(View itemView) {
super(itemView);
parentHeading = (TextView)itemView.findViewById(R.id.parent_heading);
parentImage = (ImageView)itemView.findViewById(R.id.imageView);
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
selectedPosition.add(list.get(getAdapterPosition()).getHeading());
parentImage.setImageResource(R.drawable.sad);
}
});
}
}
}
the above code is my implementation for recyclerview adapter. please help to understand the concept.
SOLUTION
change
if (selectedPosition.contains(list.get(position).getHeading())){
holder.parentImage.setImageResource(R.drawable.sad);
}
with
if (selectedPosition.contains(list.get(position).getHeading())){
holder.parentImage.setImageResource(R.drawable.sad);
} else {
holder.parentImage.setImageResource(R.drawable.your_default_drawable);
}
EXPLANATION
When you scroll your RecyclerView the system doesn't recreate always your ViewHolder but reuse one you previously scrolled that is no longer visible, so you need to reset your standard values in order to avoid showing wrong values.

Categories

Resources