OnClickListener in RecyclerView having image, text - java

I want to show another activity when object of recycler view is clicked. For eg: if I clicked "dd" text or"image of that line" then I should go to activity named "AbcActivity".
It went to many site, saw youtube tutorial but didn't helped. please help me with it. Please help me out this is my last hope :(
I'm beginner in this, It'd be great if you can provide project.
This is main activity:
public class MainActivity extends AppCompatActivity implements WordAdapter.OnNoteListener {
private RecyclerView recyclerView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView = findViewById(R.id.home_view);
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
recyclerView.setLayoutManager(layoutManager);
List<Word> wordList = new ArrayList<>();
wordList.add(new Word(R.drawable.ic_launcher_background, "dd"));
wordList.add(new Word(R.drawable.ic_launcher_background, "ss"));
WordAdapter adapter = new WordAdapter(wordList, this);
recyclerView.setAdapter(adapter);
adapter.notifyDataSetChanged();
}
#Override
public void onNoteClick(int position) {
}
}
WordAdapter:
public class WordAdapter extends RecyclerView.Adapter<WordAdapter.viewholder> {
private List<Word> wordList;
private OnNoteListener mOnNoteListener;
public WordAdapter(List<Word> wordList, OnNoteListener onNoteListener) {
this.wordList = wordList;
this.mOnNoteListener = onNoteListener;
}
#NonNull
#Override
public viewholder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.list_items, viewGroup, false);
return new viewholder(view, mOnNoteListener);
}
#Override
public void onBindViewHolder(#NonNull viewholder viewholder, int position) {
int resource = wordList.get(position).getImageResource();
String title = wordList.get(position).getTitle();
viewholder.setData(resource, title);
}
#Override
public int getItemCount() {
return wordList.size();
}
class viewholder extends RecyclerView.ViewHolder implements View.OnClickListener{
private ImageView imageView;
private TextView title;
OnNoteListener onNoteListener;
public viewholder(#NonNull View itemView, OnNoteListener onNoteListener) {
super(itemView);
imageView = itemView.findViewById(R.id.image);
title = itemView.findViewById(R.id.word);
this.onNoteListener = onNoteListener;
itemView.setOnClickListener(this);
}
private void setData(int resource, String titleText){
imageView.setImageResource(resource);
title.setText(titleText);
}
#Override
public void onClick(View view) {
onNoteListener.onNoteClick(getAdapterPosition());
}
}
public interface OnNoteListener {
void onNoteClick(int position);
}
}
This is word:
public class Word implements Parcelable {
private int imageResource;
private String title;
public Word(int imageResource, String title) {
this.imageResource = imageResource;
this.title = title;
}
protected Word(Parcel in) {
imageResource = in.readInt();
title = in.readString();
}
public static final Creator<Word> CREATOR = new Creator<Word>() {
#Override
public Word createFromParcel(Parcel in) {
return new Word(in);
}
#Override
public Word[] newArray(int size) {
return new Word[size];
}
};
public int getImageResource() {
return imageResource;
}
public String getTitle() {
return title;
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel parcel, int i) {
parcel.writeInt(imageResource);
parcel.writeString(title);
}
}

Your code works to a big percent fine. Not sure what is the problem. Maybe you have a problem when starting the new activity but surely this code has no issues.
I will post below your example with small modifications to the ViewHolder.
public class MainActivity extends AppCompatActivity implements WordAdapter.OnNoteListener {
private RecyclerView recyclerView;
private static final String TAG = MainActivity.class.getCanonicalName();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView = findViewById(R.id.home_view);
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
recyclerView.setLayoutManager(layoutManager);
List<Word> wordList = new ArrayList<>();
wordList.add(new Word(R.drawable.ic_launcher_background, "dd"));
wordList.add(new Word(R.drawable.ic_launcher_background, "ss"));
wordList.add(new Word(R.drawable.ic_launcher_background, "cc"));
WordAdapter adapter = new WordAdapter(this);
recyclerView.setAdapter(adapter);
adapter.addItems(wordList);
}
#Override
public void onNoteClick(int position) {
Log.d(TAG, "clicked on the position:" + position);
}
}
public class WordAdapter extends RecyclerView.Adapter<WordAdapter.ViewHolder> {
private List<Word> wordList;
private OnNoteListener mOnNoteListener;
public WordAdapter(List<Word> wordList, OnNoteListener onNoteListener) {
this.wordList = wordList;
this.mOnNoteListener = onNoteListener;
}
public WordAdapter(OnNoteListener onNoteListener) {
this(new ArrayList<Word>(), onNoteListener);
}
public void addItems(List<Word> items) {
wordList.addAll(items);
notifyDataSetChanged();
}
public void clear() {
wordList.clear();
notifyDataSetChanged();
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.list_items, viewGroup, false);
return new ViewHolder(view, mOnNoteListener);
}
#Override
public void onBindViewHolder(#NonNull ViewHolder viewholder, int position) {
int resource = wordList.get(position).getImageResource();
String title = wordList.get(position).getTitle();
viewholder.setData(resource, title);
}
#Override
public int getItemCount() {
return wordList.size();
}
static class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
private ImageView imageView;
private TextView title;
private OnNoteListener onNoteListener;
public ViewHolder(#NonNull View itemView, OnNoteListener onNoteListener) {
super(itemView);
imageView = itemView.findViewById(R.id.imageView);
title = itemView.findViewById(R.id.word);
this.onNoteListener = onNoteListener;
itemView.setOnClickListener(this);
}
private void setData(int resource, String titleText) {
imageView.setImageResource(resource);
title.setText(titleText);
}
#Override
public void onClick(View view) {
onNoteListener.onNoteClick(getAdapterPosition());
}
}
public interface OnNoteListener {
void onNoteClick(int position);
}
}
The word class stays the same.
Now, regarding the xml, I put some quick stuff below(list_item.xml):
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/md_green_100"
android:orientation="horizontal"
android:layout_marginTop="4dp"
android:layout_marginBottom="4dp">
<TextView
android:id="#+id/word"
android:layout_width="86dp"
android:layout_height="36dp"
android:layout_marginStart="8dp"
android:gravity="center"
android:text="Word 1"
android:textSize="16sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="#+id/imageView"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="#+id/imageView"
android:layout_width="120dp"
android:layout_height="160dp"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
android:background="#drawable/ic_launcher_background"
android:contentDescription="Icon"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="#+id/word"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
Below you can find a screenshot of the click events.
Now, knowing that click events work do whatever you want, startActivity, Log, etc.

You can set an OnClickListener for your viewHolder's itemView.
This will start the AbcActivity when you click on the imageView of the viewholder.
#Override
public void onBindViewHolder(#NonNull viewholder viewholder, int position) {
int resource = wordList.get(position).getImageResource();
String title = wordList.get(position).getTitle();
viewholder.setData(resource, title);
// #ADDED
// viewholder.itemView or viewholder.title will work too
viewholder.imageView.setOnClickListener(new View.OnClickListener() {
#Override
void onClick(View v) {
// start activity
Context context = viewHolder.itemView.getContext();
Intent intent = new Intent(context, AbcActivity.class);
context.startActivity(intent);
}
});
}

You've done almost everything.
All that remains is actually handling the click event that the listener you passed to your adapter is letting you know in the activity.
Change
#Override
public void onNoteClick(int position) {
}
To this
#Override
public void onNoteClick(int position) {
Intent intent = new Intent(context, AbcActivity.class);
context.startActivity(intent);
}
in your activity

Related

how to set onclicklistener with int array in recyclerview for cardview android

I want to click on Cardview items and intent to another activities using if else statements. Please help.
MainActivity.java
public class MainActivity extends AppCompatActivity {
private RecyclerView imagesRV;
private int[] images = {R.drawable.image01, R.drawable.image02, R.drawable.image03, R.drawable.image04, R.drawable.image05, R.drawable.image06, R.drawable.image07, R.drawable.image08};
private RecyclerViewAdapter imageAdapter;
//private ArrayList<String> imagePaths;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home_page);
imagesRV = (RecyclerView) findViewById(R.id.idRVImages);
prepareRecyclerView();
}
private void prepareRecyclerView() {
imageAdapter = new RecyclerViewAdapter(MainActivity.this, images);
GridLayoutManager manager = new GridLayoutManager(MainActivity.this, 2);
imagesRV.setLayoutManager(manager);
imagesRV.setAdapter(imageAdapter);
}
}
RecyclerViewAdapter.java
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.RecyclerViewHolder> {
private final Context context;
private final int[] imagePathArrayList;
public RecyclerViewAdapter(Context context, int[] imagePathArrayList) {
this.context = context;
this.imagePathArrayList = imagePathArrayList;
}
#NonNull
#Override
public RecyclerViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.cardview, parent, false);
return new RecyclerViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull RecyclerViewHolder holder, int position) {
int imageId = imagePathArrayList[position];
Picasso.get().load(imageId).placeholder(R.drawable.ic_launcher_background).into(holder.imageIV);
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
}
});
}
#Override
public int getItemCount() {
return imagePathArrayList.length;
}
public static class RecyclerViewHolder extends RecyclerView.ViewHolder {
private final ImageView imageIV;
public RecyclerViewHolder(#NonNull View itemView) {
super(itemView);
imageIV = itemView.findViewById(R.id.idIVImage);
}
}
}
Create interface:
public interface MyOnClick {
void onClick(int imageId);
}
Add a reference to MyOnClick to the constructor
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.RecyclerViewHolder> {
...
private final MyOnClick myOnClick;
public RecyclerViewAdapter(Context context, int[] imagePathArrayList, MyOnClick myOnClick) {
this.context = context;
this.imagePathArrayList = imagePathArrayList;
this.myOnClick = myOnClick
}
...
#Override
public void onBindViewHolder(#NonNull RecyclerViewHolder holder, int position) {
final int imageId = imagePathArrayList[position];
Picasso.get().load(imageId).placeholder(R.drawable.ic_launcher_background).into(holder.imageIV);
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
myOnClick.onClick(imageId)
}
});
}
Pass MyOnClick to adapter
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.RecyclerViewHolder> {
private RecyclerView imagesRV;
private int[] images = {R.drawable.image01, R.drawable.image02, R.drawable.image03, R.drawable.image04, R.drawable.image05, R.drawable.image06, R.drawable.image07, R.drawable.image08};
private RecyclerViewAdapter imageAdapter;
//private ArrayList<String> imagePaths;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home_page);
imagesRV = (RecyclerView) findViewById(R.id.idRVImages);
prepareRecyclerView();
}
private void prepareRecyclerView() {
imageAdapter = new RecyclerViewAdapter(this, images, new MyOnClick() {
#Override
public void onClick(int imageId) {
// Your action
}
});
GridLayoutManager manager = new GridLayoutManager(MainActivity.this, 2);
imagesRV.setLayoutManager(manager);
imagesRV.setAdapter(imageAdapter);
}
}

RecyclerView onClickItem is not responding to the click

I want to implement an onClickListener for a RecyclerViewItem in my App. My problem is, that the onclick listener isn't being called. Not even in the adapter. I'm trying to get this to work for 5 hours now and I'm really frustrated and don't know how to fix this/proceed.
I hope you can help me.
ItemListAdapter.class
public class ItemListAdapter extends RecyclerView.Adapter<ItemListAdapter.ItemViewHolder> implements Filterable {
private ArrayList<Item> mItemList;
private ArrayList<Item> mItemListFiltered;
private ItemsListAdapterListener mItemsListAdapterListener;
public ItemListAdapter(ArrayList<Item> itemArrayList, ItemsListAdapterListener itemsListAdapterListener) {
mItemList = itemArrayList;
mItemListFiltered = itemArrayList;
this.mItemsListAdapterListener = itemsListAdapterListener;
}
public interface ItemsListAdapterListener {
void onItemClick(int position);
}
public static class ItemViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
public ImageView mImageView;
public TextView mTextView;
ItemsListAdapterListener mItemsListAdapterListener;
public ItemViewHolder(#NonNull View itemView, ItemsListAdapterListener itemsListAdapterListener) {
super(itemView);
mItemsListAdapterListener = itemsListAdapterListener;
mImageView = itemView.findViewById(R.id.imageViewItem);
mTextView = itemView.findViewById(R.id.textViewItem);
itemView.setOnClickListener(this);
}
#Override
public void onClick(View v) {
mItemsListAdapterListener.onItemClick(getAdapterPosition());
Log.i("test", "Adapter click");
}
}
#NonNull
#Override
public ItemViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.adapter_view_layout, parent, false);
ItemViewHolder itemViewHolder = new ItemViewHolder(view, mItemsListAdapterListener);
return itemViewHolder;
}
#Override
public void onBindViewHolder(#NonNull ItemViewHolder holder, int position) {
Item item = mItemListFiltered.get(position);
holder.mImageView.setImageResource(item.getImgURL());
holder.mTextView.setText(item.getItemName());
}
#Override
public int getItemCount() {
return mItemListFiltered.size();
}
#Override
public Filter getFilter() {
return new Filter() {
#Override
protected FilterResults performFiltering(CharSequence charSequence) {
String charString = charSequence.toString();
if (charString.isEmpty()) {
mItemListFiltered = mItemList;
} else {
ArrayList<Item> filteredList = new ArrayList<>();
for (Item row: mItemList) {
// name match condition. this might differ depending on your requirement
// here we are looking for name or phone number match
if (row.getItemName().toLowerCase().contains(charString.toLowerCase()) || row.getItemCategory().toLowerCase().contains(charString.toLowerCase())) {
filteredList.add(row);
}
}
mItemListFiltered = (ArrayList<Item>) filteredList;
}
FilterResults filterResults = new FilterResults();
filterResults.values = mItemListFiltered;
return filterResults;
}
#Override
protected void publishResults(CharSequence charSequence, FilterResults filterResults) {
mItemListFiltered = (ArrayList<Item>) filterResults.values;
notifyDataSetChanged();
}
};
}
}
ItemsFragment.class
public class ItemsFragment extends Fragment implements TextWatcher, ItemListAdapter.ItemsListAdapterListener{
private ItemsViewModel itemsViewModel;
private RecyclerView mRecyclerView;
private ItemListAdapter mAdapter;
private RecyclerView.LayoutManager mLayoutManager;
public View onCreateView(#NonNull final LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
itemsViewModel =
ViewModelProviders.of(this).get(ItemsViewModel.class);
View root = inflater.inflate(R.layout.fragment_items, container, false);
final EditText editTextItemSearch;
editTextItemSearch = (EditText) root.findViewById(R.id.editTextItemSearch);
editTextItemSearch.addTextChangedListener(this);
final ArrayList<Item> itemArrayList = new ArrayList<>();
itemArrayList.add(new Item("TestItem1", R.drawable.unbenannt, getString(R.string.item_parts)));
itemArrayList.add(new Item("TestItem2", R.drawable.ic_home_black_24dp, getString(R.string.item_tools)));
itemArrayList.add(new Item("TestItem3", R.drawable.ic_dashboard_black_24dp, getString(R.string.item_consumable)));
itemArrayList.add(new Item("test123", R.drawable.ic_notifications_black_24dp, getString(R.string.item_interactive)));
itemArrayList.add(new Item("test12567687863", R.drawable.ic_notifications_black_24dp,getString(R.string.item_blocks)));
Log.i("test", "items added");
mRecyclerView = root.findViewById(R.id.recylcerViewItems);
mRecyclerView.setHasFixedSize(true);
mLayoutManager = new LinearLayoutManager(getContext());
mAdapter = new ItemListAdapter(itemArrayList, this);
mRecyclerView.setLayoutManager(mLayoutManager);
mRecyclerView.setAdapter(mAdapter);
return root;
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
mAdapter.getFilter().filter(s);
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void afterTextChanged(Editable s) {
}
#Override
public void onItemClick(int position) {
Log.i("test", "item clicked");
}
}
adapter_view_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="6dp">
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="60dp"
android:layout_margin="8dp"
android:backgroundTint="#color/colorBackroundBright"
android:clickable="true"
android:foreground="?attr/selectableItemBackground"
app:cardCornerRadius="15dp"
tools:layout_editor_absoluteX="144dp"
tools:layout_editor_absoluteY="42dp">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="#+id/imageViewItem"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_margin="16dp"
android:layout_marginStart="16dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/textViewItem"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="32dp"
android:fontFamily="#font/nunito_regular"
android:text="ItemName"
android:textColor="#959595"
app:layout_constraintBottom_toBottomOf="#+id/imageViewItem"
app:layout_constraintStart_toEndOf="#+id/imageViewItem"
app:layout_constraintTop_toTopOf="#+id/imageViewItem" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
</androidx.constraintlayout.widget.ConstraintLayout>
Try removing android:clickable="true" from your CardView.
I think what is happening is you are clicking on the CardView, which is stealing the click so the root view does not get it.
Try this:
In ItemViewHolder add a View object and set it to itemView:
public static class ItemViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
public ImageView mImageView;
public TextView mTextView;
//add here
public View view;
ItemsListAdapterListener mItemsListAdapterListener;
public ItemViewHolder(#NonNull View itemView, ItemsListAdapterListener itemsListAdapterListener) {
super(itemView);
//set here
view = itemView;
.........
.........
Now set the onClickListener in onBindViewHolder:
#Override
public void onBindViewHolder(#NonNull ItemViewHolder holder, int position) {
Item item = mItemListFiltered.get(position);
holder.mImageView.setImageResource(item.getImgURL());
holder.mTextView.setText(item.getItemName());
//here
holder.view.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View view){
mItemsListAdapterListener.onItemClick(position);
}
});
}
UPDATE:
Remove this from cardView xml:
android:clickable="true"

OnClickListener for the Recycler View returns nothing

I'm a beginner and I'm trying to build a simple voice recorder app. I've already posted on the website concerning the access of external storage. This problem is now solved but I've an another one concerning my RecyclerView.
I've followed a tutorial online in order to detect which view is clicked and play the audio accordingly (I use my RecyclerView to display all the recording files just created). Here's the tutorial in question : https://www.youtube.com/watch?v=ZXoGG2XTjzU
The problem is, the 'OnNoteClick' does absolutely nothing. How can I fix this ?
I created an interface with a function 'OnNoteClick' attached to it. I implemented this function in mainactivity.java. Basically, I've followed the tutorial.
\\\ Adapter Code
private OnNoteListener mOnNoteListener;
...
public RecyclerViewAdapter(#NonNull ArrayList<String> text, Context context, OnNoteListener onNoteListener) {
Text = text;
this.context = context;
this.mOnNoteListener = onNoteListener;
}
...
public ViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.cardview, viewGroup, false);
ViewHolder holder = new ViewHolder(view, mOnNoteListener);
return holder;
}
...
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
TextView textView;
CardView ParentLayout;
OnNoteListener onNoteListener;
public ViewHolder(#NonNull View itemView, OnNoteListener onNoteListener) {
super(itemView);
textView = itemView.findViewById(R.id.cardtext);
ParentLayout = itemView.findViewById(R.id.cardview);
this.onNoteListener = onNoteListener;
ParentLayout.setOnClickListener(this);
}
#Override
public void onClick(View v) {
onNoteListener.onNoteClick(getAdapterPosition());
}
}
public interface OnNoteListener{
void onNoteClick(int position);
}
}
...
\\\ MainActivityCode
public class FileAndDirectoryActivity extends AppCompatActivity implements RecyclerViewAdapter.OnNoteListener {
...
private void initRecyclerView() {
RecyclerView recyclerView = findViewById(R.id.recyclerview);
RecyclerViewAdapter adapter = new RecyclerViewAdapter(mNames, this, this);
recyclerView.setAdapter(adapter);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
}
...
#Override
public void onNoteClick(int position) {
Toast.makeText(this, "Good News : I'm working", Toast.LENGTH_SHORT).show();
}
}
...
I expect the app to show a message reading "I'm working" or something like that but in reality, when i touch the cardview, nothing happens.
Your problem is in:
public void onBindViewHolder(#NonNull ViewHolder holder, int i) {
holder.textView.setText(Text.get(i));
holder.ParentLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.d(TAG, "onClick: Click on this card !");
}
});
}
You set a new click listener on ParentLayout so it overwrites click listener that you set in constructor. Try it without and it should work:
public void onBindViewHolder(#NonNull ViewHolder holder, int i) {
holder.textView.setText(Text.get(i));
}
Change your Adapter to below code and also Make sure you are fetching correct id of cardView
private OnNoteListener mOnNoteListener;
...
public RecyclerViewAdapter(#NonNull ArrayList<String> text, Context context, OnNoteListener onNoteListener) {
Text = text;
this.context = context;
this.mOnNoteListener = onNoteListener;
}
...
public ViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(context).inflate(R.layout.cardview, viewGroup, false);
ViewHolder holder = new ViewHolder(view);
return holder;
}
...
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
TextView textView;
CardView ParentLayout;
public ViewHolder(#NonNull View itemView) {
super(itemView);
textView = itemView.findViewById(R.id.cardtext);
ParentLayout = itemView.findViewById(R.id.cardview);
ParentLayout.setOnClickListener(this);
}
#Override
public void onClick(View v) {
mOnNoteListener.onNoteClick(getAdapterPosition());
}
}
public interface OnNoteListener{
void onNoteClick(int position);
}
}
No need to pass listener on ViewHolder constructor, because you have mOnNoteListener as global varible.
Just create setonclicklistener of view in onBind method. And call interface method on that.
Like
mOnNoteListener.onNoteClick(pos);
pos integer as position got in onBind method
Here i given you clear explanation,
Create one common Interface, named as CustomItemClickListenere
public interface CustomItemClickListenere {
public void onItemClick(View v, int position); }
Change your adapter class like below,
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder> {
private ArrayList<AddSingleItemList> data;
private Context mContext;
private CustomItemClickListenere listener;
public RecyclerViewAdapter(Context mContext, ArrayList<AddSingleItemList> data, CustomItemClickListenere listener) {
this.data = data;
this.mContext = mContext;
this.listener = listener;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View mView = LayoutInflater.from(parent.getContext()).inflate(R.layout.items_list_single_item, parent, false);
final ViewHolder mViewHolder = new ViewHolder(mView);
mView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
listener.onItemClick(v, mViewHolder.getPosition());
}
});
return mViewHolder;
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.itemTitle.setText(Html.fromHtml(data.get(position).getTitle()));
}
#Override
public int getItemCount() {
return data.size();
}
public static class ViewHolder extends RecyclerView.ViewHolder {
public TextView itemTitle;
public CardView cardView;
ViewHolder(View v) {
super(v);
itemTitle = (TextView) v.findViewById(R.id.person_name);
cardView = (CardView) v.findViewById(R.id.cv);
}
}
}
adapter's xml item_list_single_item :
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/cv"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="5dp">
<TextView
android:id="#+id/person_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:textSize="12sp" />
</RelativeLayout>
</android.support.v7.widget.CardView>
Here i have created on Pojo class for setting static items on Recyclerview, named as AddSingleItemList :
public class AddSingleItemList {
private String title;
long id;
/**
*
* #param id
* #param title
*/
public AddSingleItemList(long id, String title) {
this.id = id;
this.title = title;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
}
Update you RecyclerViewActivity like below :
public class RecyclerViewActivity extends AppCompatActivity {
RecyclerView itemsList;
RecyclerViewAdapter adapter;
ArrayList<AddSingleItemList> data = new ArrayList<>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_list);
itemsList = (RecyclerView) findViewById(R.id.items_list);
LinearLayoutManager llm = new LinearLayoutManager(this);
itemsList.setLayoutManager(llm);
itemsList.setHasFixedSize(true);
//Add you items into the Recyclerview list
data.add(new AddSingleItemList(1, "First Item"));
data.add(new AddSingleItemList(2, "Second Item"));
adapter = new RecyclerViewAdapter(this, data, new CustomItemClickListenere() {
#Override
public void onItemClick(View v, int position) {
Log.d("RecyclerViewActivity", "clicked position:" + position);
Toast.makeText(RecyclerViewActivity.this, "Good News : I'm working", Toast.LENGTH_SHORT).show();
// do what ever you want to do with it
}
});
itemsList.setAdapter(adapter);
}
}
Finally you will get result as you raised in your question,

How can I get a variable from RecyclerView Adapter passed to MainActivity?

I was just playing around with some code, learning new things, when I ran into this problem... I'm trying to pass a variable from my RecylcerViewAdapter to a method in MainActivity, but I just can't seem to accomplish it.
I tried a lot of different thing with interfaces and casting, but nothing did the trick. Since I'm fairly new to all of this, maybe I'm making a trivial mistake somewhere?
My Interface:
public interface AdapterCallback {
void onMethodCallback(int id);
}
This is my adapter class:
public class PostAdapter extends RecyclerView.Adapter<PostAdapter.ViewHolder> {
private List<Post> postList;
private Context context;
private AdapterCallback listener;
public PostAdapter() {
}
public PostAdapter(List<Post> postList, Context context) {
this.postList = postList;
this.context = context;
}
public void setListener(AdapterCallback listener) {
this.listener = listener;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.recycler_layout, viewGroup, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull final ViewHolder viewHolder, final int position) {
viewHolder.tvTitle.setText(postList.get(position).getTitle());
viewHolder.tvBody.setText(new StringBuilder(postList.get(position).getBody().substring(0, 20)).append("..."));
viewHolder.tvId.setText(String.valueOf(postList.get(position).getUserId()));
viewHolder.parentLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int id = postList.get(position).getId();
if (listener != null) {
listener.onMethodCallback(id);
}
}
});
}
#Override
public int getItemCount() {
return postList.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
TextView tvTitle;
TextView tvBody;
TextView tvId;
LinearLayout parentLayout;
public ViewHolder(View itemView) {
super(itemView);
tvTitle = itemView.findViewById(R.id.tvTitle);
tvBody = itemView.findViewById(R.id.tvBody);
tvId = itemView.findViewById(R.id.tvId);
parentLayout = itemView.findViewById(R.id.parentLayout);
}
}
}
And my MainActivity:
public class MainActivity extends AppCompatActivity {
public static final String TAG = "MainActivityLog";
private CompositeDisposable disposable = new CompositeDisposable();
#BindView(R.id.rvPosts)
RecyclerView rvPosts;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
rvPosts.setHasFixedSize(true);
rvPosts.setLayoutManager(new LinearLayoutManager(this));
populateList();
logItems();
}
private void populateList() {
MainViewModel viewModel = ViewModelProviders.of(MainActivity.this).get(MainViewModel.class);
viewModel.makeQuery().observe(MainActivity.this, new Observer<List<Post>>() {
#Override
public void onChanged(#Nullable List<Post> posts) {
PostAdapter adapter = new PostAdapter(posts, getApplicationContext());
rvPosts.setAdapter(adapter);
}
});
}
public void logItems() {
PostAdapter adapter = new PostAdapter();
adapter.setListener(new AdapterCallback() {
#Override
public void onMethodCallback(int id) {
MainViewModel viewModel = ViewModelProviders.of(MainActivity.this).get(MainViewModel.class);
viewModel.makeSingleQuery(id).observe(MainActivity.this, new Observer<Post>() {
#Override
public void onChanged(#Nullable final Post post) {
Log.d(TAG, "onChanged: data response");
Log.d(TAG, "onChanged: " + post);
}
});
}
});
}
#Override
protected void onDestroy() {
super.onDestroy();
disposable.clear();
}
}
The populateList() method works just fine, but the logItems() method is the problem.
So when i click on a view in RecyclerView I expect the log to output the title, description and ID of the post that was clicked. nut nothing happens...
So, any help would be appreciated.
Make adapter global variable i.e. a field. Use the same object to set every properties.
private PostAdapter adapter;
Replace your logItems method with this:
public void logItems() {
adapter.setListener(new AdapterCallback() {
#Override
public void onMethodCallback(int id) {
MainViewModel viewModel = ViewModelProviders.of(MainActivity.this).get(MainViewModel.class);
viewModel.makeSingleQuery(id).observe(MainActivity.this, new Observer<Post>() {
#Override
public void onChanged(#Nullable final Post post) {
Log.d(TAG, "onChanged: data response");
Log.d(TAG, "onChanged: " + post);
}
});
}
});
}
And populateList with this:
private void populateList() {
MainViewModel viewModel = ViewModelProviders.of(MainActivity.this).get(MainViewModel.class);
viewModel.makeQuery().observe(MainActivity.this, new Observer<List<Post>>() {
#Override
public void onChanged(#Nullable List<Post> posts) {
adapter = new PostAdapter(posts, getApplicationContext());
rvPosts.setAdapter(adapter);
logItems();
}
});
}
And don't call logItems() from onCreate
This is how I implement with my ListAdapters:
public class FeedbackListAdapter extends RecyclerView.Adapter<FeedbackListAdapter.ViewHolder> {
private final ArrayList<Feedback> feedbacks;
private View.OnClickListener onItemClickListener;
private View.OnLongClickListener onItemLongClickListener;
private final Context context;
public FeedbackListAdapter(ArrayList<Feedback> feedbacks, Context context) {
this.feedbacks = feedbacks;
this.context = context;
}
public void setItemClickListener(View.OnClickListener onItemClickListener) {
this.onItemClickListener = onItemClickListener;
}
public void setOnItemLongClickListener(View.OnLongClickListener onItemLongClickListener){
this.onItemLongClickListener = onItemLongClickListener;
}
public class ViewHolder extends RecyclerView.ViewHolder{
final TextView feedback, created, updated;
final LinearLayout mainLayout;
ViewHolder(View iv) {
super(iv);
/*
* Associate layout elements to Java declarations
* */
mainLayout = iv.findViewById(R.id.main_layout);
feedback = iv.findViewById(R.id.feedback);
created = iv.findViewById(R.id.created_string);
updated = iv.findViewById(R.id.updated_string);
}
}
#Override
public int getItemCount() {
return feedbacks.size();
}
#Override
#NonNull
public FeedbackListAdapter.ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.fragment_feedback_table_row, parent, false);
return new FeedbackListAdapter.ViewHolder(view);
}
#Override
public void onBindViewHolder(final #NonNull FeedbackListAdapter.ViewHolder holder, final int position) {
/*
* Bind data to layout
* */
try{
Feedback feedback = feedbacks.get(position);
holder.feedback.setText(feedback.getContent());
holder.created.setText(feedback.getCreated());
holder.updated.setText(feedback.getUpdated());
holder.mainLayout.setOnClickListener(this.onItemClickListener);
holder.mainLayout.setOnLongClickListener(this.onItemLongClickListener);
holder.mainLayout.setTag(feedback.getDbID());
TypedValue outValue = new TypedValue();
context.getTheme().resolveAttribute(android.R.attr.selectableItemBackground, outValue, true);
holder.mainLayout.setBackgroundResource(outValue.resourceId);
}catch(IndexOutOfBoundsException e){
e.printStackTrace();
}
}
}
In onPopulateList you create an adaptor:
PostAdapter adapter = new PostAdapter(posts, getApplicationContext());
rvPosts.setAdapter(adapter);
However in public void logItems() { you used a different adapter
PostAdapter adapter = new PostAdapter();
adapter.setListener(new AdapterCallback() {
#Override
public void onMethodCallback(int id) {
...
}
});
Therefore the list is being populated with 1 adapter, but you are setting the listener on an unused second adapter.
The fix is to use the same adapter for both. If you make the adapater a field, and don't create a new one inside of logItems, but just set your listener it should work.
i.e.
// as a field in your class
private PostAdapter adapter;
then
// in `populateList()`
adapter = new PostAdapter(posts, getApplicationContext());
rvPosts.setAdapter(adapter);
and
// in `logItems()`
adapter.setListener(new AdapterCallback() {
#Override
public void onMethodCallback(int id) {
...
}
});
In Adapter
public class CustomerListAdapter extends RecyclerView.Adapter<CustomerListAdapter.OrderItemViewHolder> {
private Context mCtx;
ProgressDialog progressDialog;
//we are storing all the products in a list
private List<CustomerModel> customeritemList;
public CustomerListAdapter(Context mCtx, List<CustomerModel> orderitemList) {
this.mCtx = mCtx;
this.customeritemList = orderitemList;
progressDialog = new ProgressDialog(mCtx);
}
#NonNull
#Override
public OrderItemViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(mCtx);
View view = inflater.inflate(R.layout.activity_customer_list, null);
return new OrderItemViewHolder(view, mCtx, customeritemList);
}
#Override
public void onBindViewHolder(#NonNull OrderItemViewHolder holder, int position) {
CustomerModel customer = customeritemList.get(position);
try {
//holder.textViewPINo.setText("PINo \n"+Integer.toString( order.getPINo()));
holder.c_name.setText(customer.getCustomerName());
holder.c_address.setText(customer.getAddress());
holder.c_contact.setText(customer.getMobile());
holder.i_name.setText(customer.getInteriorName());
holder.i_contact.setText(customer.getInteriorMobile());
holder.i_address.setText(customer.getAddress());
} catch (Exception E) {
E.printStackTrace();
}
}
#Override
public int getItemCount() {
return customeritemList.size();
}
class OrderItemViewHolder extends RecyclerView.ViewHolder implements View.OnLongClickListener, View.OnClickListener {
AlertDialog.Builder alert;
private Context mCtx;
TextView c_name, c_contact, c_address, i_name, i_contact, i_address;
TextView OrderItemID, MaterialType, Price2, Qty, AQty;
//we are storing all the products in a list
private List<CustomerModel> orderitemList;
public OrderItemViewHolder(View itemView, Context mCtx, List<CustomerModel> orderitemList) {
super(itemView);
this.mCtx = mCtx;
this.orderitemList = orderitemList;
itemView.setOnClickListener(this);
itemView.setOnLongClickListener(this);
// CatelogOrderDetailModel catelogOrderDetailModel = new CatelogOrderDetailModel();
c_name = itemView.findViewById(R.id.customerName);
c_contact = itemView.findViewById(R.id.contact);
c_address = itemView.findViewById(R.id.address);
i_name = itemView.findViewById(R.id.interiorName);
i_address = itemView.findViewById(R.id.interiorAddress);
i_contact = itemView.findViewById(R.id.interiorContact);
}
#Override
public void onClick(View v) {
int position = getAdapterPosition();
CustomerModel orderitem = this.orderitemList.get(position);
}
#Override
public boolean onLongClick(View v) {
int position = getAdapterPosition();
CustomerModel orderitem = this.orderitemList.get(position);
if (v.getId() == itemView.getId()) {
// showUpdateDeleteDialog(order);
try {
} catch (Exception E) {
E.printStackTrace();
}
Toast.makeText(mCtx, "lc: ", Toast.LENGTH_SHORT).show();
}
return true;
}
}
}

How to Pass Image or path from Recyclerview to next Activity onClick so that i can display Image Full View?

I really don't know how to do this. I have tried some tutorial but not worked for me ... i've already done the this with many Methods but unable to do this.
Here is my RecyclerView Holder
public class RecyclerViewHolders extends RecyclerView.ViewHolder implements View.OnClickListener{
public TextView countryName;
public ImageView countryPhoto;
String s;
Bitmap image;
public RecyclerViewHolders(View itemView) {
super(itemView);
itemView.setOnClickListener(this);
countryPhoto = (ImageView)itemView.findViewById(R.id.country_photo);
}
#Override public void onClick(View view) {
Intent imageIntent = new Intent(view.getContext(),GalleryFullImage.class);
imageIntent.putExtra("id",getAdapterPosition());
view.getContext().startActivity(imageIntent);
Toast.makeText(view.getContext(), "Clicked Country Position = " + getAdapterPosition(), Toast.LENGTH_SHORT).show();
}}
Here is my Recyclerview Adapter
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewHolders> {
private ArrayList<String> arrayList;
private Context context;
public RecyclerViewAdapter(Context context, ArrayList<String> itemList) {
this.arrayList = itemList;
this.context = context;
}
#Override
public long getItemId(int position) {
return position;
}
#Override public RecyclerViewHolders onCreateViewHolder(ViewGroup parent, int viewType) {
View layoutView = LayoutInflater.from(parent.getContext()).inflate(R.layout.gallery_item, null);
RecyclerViewHolders rcv = new RecyclerViewHolders(layoutView);
return rcv;
}
#Override public void onBindViewHolder(RecyclerViewHolders holder, int position) {
Bitmap bitmap = BitmapFactory.decodeFile(arrayList.get(position));
holder.countryPhoto.setImageBitmap(bitmap);
}
#Override public int getItemCount() {
return this.arrayList.size();
}}
Here is my GalleryActivity
public class GalleryActivity extends AppCompatActivity {
ArrayList<String> stringList;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activty_gallery);
setTitle("Gallery");
stringList = new ArrayList<>();
// Be sure that this file is exist !!
String targetPath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/Country";
File targetDirector = new File(targetPath);
File[] files = targetDirector.listFiles();
try
{
Arrays.sort( files, new Comparator()
{
public int compare(Object o1, Object o2) {
if (((File)o1).lastModified() > ((File)o2).lastModified()) {
return -1;
} else if (((File)o1).lastModified() < ((File)o2).lastModified()) {
return +1;
} else {
return 0;
}
}
});
for (File file : files) {
stringList.add(file.getAbsolutePath());
}
}catch (Exception e)
{
Log.e("Sort Error", e.getMessage());
}
RecyclerView rView = (RecyclerView)findViewById(R.id.my_recycler_view);
RecyclerView.LayoutManager layoutManager = new GridLayoutManager(getApplicationContext(),2);
rView.setHasFixedSize(true);
rView.setLayoutManager(layoutManager);
RecyclerViewAdapter rcAdapter = new RecyclerViewAdapter(getApplicationContext(), stringList);
rView.setAdapter(rcAdapter);
}
}
You just have to apply onClickListener in you viewholder, take the clicked adapter position in integer and pass it in next your fullscreen activity
Here is the full code, hope it helps
MainActivity
public class MainActivity extends AppCompatActivity {
private final Integer image_ids[] = {
R.drawable.image1,
R.drawable.image2,
R.drawable.image3,
R.drawable.image4,
R.drawable.image5,
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
RecyclerView recyclerView = (RecyclerView)findViewById(R.id.recyclerview);
recyclerView.setHasFixedSize(true);
RecyclerView.LayoutManager layoutManager = new GridLayoutManager(getApplicationContext(),gridColumnlayout);
recyclerView.setLayoutManager(layoutManager);
ArrayList<CreateList> createLists = prepareData();
MyAdapter adapter = new MyAdapter(getApplicationContext(), createLists);
recyclerView.setAdapter(adapter);
}
private ArrayList<CreateList> prepareData(){
ArrayList<CreateList> theimage = new ArrayList<>();
for(int i = 0; i< 5; i++){
CreateList createList = new CreateList();
createList.setImage_ID(image_ids[i]);
theimage.add(createList);
}
return theimage;
}
}
CreateList Class
public class CreateList {
private Integer image_id;
public Integer getImage_ID() {
return image_id;
}
public void setImage_ID(Integer android_image_url) {
this.image_id = android_image_url;
}
}
MyAdapter
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
private ArrayList<CreateList> galleryList;
private Context context;
public final static String EXTRA_MESSAGE = "FullScreen Image";
public MyAdapter(Context context, ArrayList<CreateList> galleryList) {
this.galleryList = galleryList;
this.context = context;
}
#Override
public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int i) {
return new ViewHolder(LayoutInflater.from(context).inflate(R.layout.list_item, parent, false));
}
#Override
public void onBindViewHolder(final MyAdapter.ViewHolder viewHolder, int i) {
CreateList currentList = galleryList.get(i);
Glide.with(context).load(currentList.getImage_ID()).centerCrop().crossFade().into(viewHolder.img);
viewHolder.img.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int pos = viewHolder.getAdapterPosition();
String stringID = Integer.valueOf(pos).toString();
Intent intent = new Intent(MyAdapter.this.context, FullScreen.class);
intent.putExtra(EXTRA_MESSAGE, stringID);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
}
});
}
#Override
public int getItemCount() {
return galleryList.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
private ImageView img;
public ViewHolder(View view) {
super(view);
img = (ImageView) view.findViewById(R.id.image);
}
}
}
FullScreen Activity
public class FullScreen extends AppCompatActivity {
private final Integer image_ids[] = {
R.drawable.image1,
R.drawable.image2,
R.drawable.image3,
R.drawable.image4,
R.drawable.image5,
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_full_screen);
Intent intent = getIntent();
String message = intent.getStringExtra(MyAdapter.EXTRA_MESSAGE);
int position = Integer.parseInt(message);
ImageView imageView = (ImageView) viewItem.findViewById(R.id.imageView);
imageView.setImageResource(image_ids[position]);
}
}
list_item.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:layout_width="match_parent"
android:layout_height="170dp"
android:scaleType="fitXY"
android:id="#+id/image"/>
</RelativeLayout>
Since you are loading the bitmap from file in onBindViewHolder, you can just pass the path instead in onClick and decode it again in your next activity. This may require a bit of work in your case since your ViewHolder is defined separately from your RecyclerView so it does not have access to your dataset. For starters, move your ViewHolder so it can be a static nested class of your RecyclerView. Something like this:
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.RecyclerViewHolders>
private ArrayList<String> arrayList;
....
public static class RecyclerViewHolders extends RecyclerView.ViewHolder implements View.OnClickListener{
....
#Override
public void onClick(View view) {
Intent intent = new Intent(...);
intent.putExtra("path",arrayList.get(getAdapterPosition());
/* send intent*/
}
}

Categories

Resources